Reverse proxy
terminating TLS and proxying requests to githome with nginx, Caddy, or Traefik
Githome listens on plain HTTP. In production, put a reverse proxy in front for TLS termination, access logging, and to handle large release asset uploads correctly.
Before configuring any proxy, set:
GITHOME_HTML_BASE_URL=https://git.example.com
This value is used to generate OAuth redirect URIs, clone URLs, and webhook URLs. If it does not match the URL users actually reach, OAuth flows break and clone URLs point nowhere.
nginx
Full configuration
upstream githome {
server 127.0.0.1:3000;
keepalive 32;
}
server {
listen 80;
server_name git.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name git.example.com;
ssl_certificate /etc/letsencrypt/live/git.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/git.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
# Allow large release asset uploads (set this to your expected max asset size)
client_max_body_size 512m;
location / {
proxy_pass http://githome;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_read_timeout 300s;
}
# Disable request buffering for release asset uploads
location /api/uploads/ {
proxy_pass http://githome;
proxy_request_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_read_timeout 600s;
client_max_body_size 512m;
}
}
The /api/uploads/ block disables request buffering so that nginx streams large uploads directly to githome rather than writing the entire body to disk first. Without this, uploading a multi-hundred-megabyte release asset consumes nginx's temp space and adds latency.
Testing the configuration
nginx -t
systemctl reload nginx
Verify that a git clone works over HTTPS:
git clone https://git.example.com/alice/myrepo.git
Caddy
Caddy is the fastest path to automatic HTTPS via Let's Encrypt.
git.example.com {
reverse_proxy localhost:3000
# Increase body limit for release asset uploads
request_body {
max_size 512MB
}
# Disable buffering for the upload endpoint
@uploads path /api/uploads/*
handle @uploads {
reverse_proxy localhost:3000 {
flush_interval -1
}
}
log {
output file /var/log/caddy/githome-access.log
format json
}
}
Caddy obtains and renews TLS certificates automatically. No certificate management is required beyond pointing DNS at the server.
Start or reload Caddy:
systemctl reload caddy
Caddy reads Caddyfile from /etc/caddy/Caddyfile by default.
Traefik (Docker labels)
When running githome with docker compose, Traefik can pick up routing configuration from container labels.
services:
traefik:
image: traefik:v3
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.le.acme.tlschallenge=true"
- "[email protected]"
- "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- letsencrypt:/letsencrypt
githome:
image: ghcr.io/tamnd/githome:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.githome.rule=Host(`git.example.com`)"
- "traefik.http.routers.githome.entrypoints=websecure"
- "traefik.http.routers.githome.tls.certresolver=le"
- "traefik.http.services.githome.loadbalancer.server.port=3000"
# Redirect HTTP to HTTPS
- "traefik.http.routers.githome-http.rule=Host(`git.example.com`)"
- "traefik.http.routers.githome-http.entrypoints=web"
- "traefik.http.routers.githome-http.middlewares=https-redirect"
- "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https"
environment:
GITHOME_HTML_BASE_URL: "https://git.example.com"
# ... other vars
volumes:
letsencrypt:
Traefik watches the Docker socket for label changes and updates routing dynamically.
Common issues
OAuth redirects fail or return the wrong URL. GITHOME_HTML_BASE_URL is the source of truth for all generated URLs. If your proxy adds or strips a port, or you access the server via a different hostname than the one in GITHOME_HTML_BASE_URL, OAuth and clone URLs break. Set GITHOME_HTML_BASE_URL to exactly what appears in the browser address bar.
Large uploads hang or fail with 413. Set client_max_body_size in nginx to at least 512MB and add the /api/uploads/ location block with proxy_request_buffering off. For Caddy, set request_body max_size 512MB.
Git push times out mid-transfer. Increase proxy_read_timeout in nginx (300s or more). Git push can take a long time for large repositories.
Git LFS
Git LFS is not supported. Do not configure an LFS endpoint against a githome instance.