HTTPS con reverse proxy
HTTPS con reverse proxy
Forgejo por defecto escucha en el puerto 3000 sin cifrado. Para produccion necesitas HTTPS con un dominio propio. La forma estandar es poner un reverse proxy frente al contenedor.
Por que usar un reverse proxy
- SSL termination: el proxy maneja los certificados; Forgejo no necesita saber nada de TLS
- Dominio propio: accedes por
https://git.tudominio.comen lugar dehttp://ip:3000 - No exponer puertos internos: el puerto 3000 queda dentro de la red Docker, sin acceso directo desde Internet
- Headers de seguridad: el proxy puede agregar
HSTS,X-Frame-Options, etc.
Opcion 1: Nginx
Nginx es la opcion mas extendida. Requiere gestionar los certificados TLS manualmente con Certbot.
Instalar dependencias
apt install nginx certbot python3-certbot-nginx
Obtener certificado SSL
certbot --nginx -d git.tudominio.com
Certbot modifica la configuracion de Nginx automaticamente. Si prefieres hacerlo manual, obtener solo el certificado:
certbot certonly --standalone -d git.tudominio.com
Configuracion de Nginx
Crea el archivo /etc/nginx/sites-available/forgejo:
server {
listen 80;
server_name git.tudominio.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name git.tudominio.com;
ssl_certificate /etc/letsencrypt/live/git.tudominio.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/git.tudominio.com/privkey.pem;
client_max_body_size 512m;
location / {
proxy_pass http://localhost:3000;
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;
}
}
Headers necesarios explicados:
Host: Forgejo necesita saber el dominio original para construir URLsX-Real-IP/X-Forwarded-For: la IP real del cliente, no la del proxyX-Forwarded-Proto: indica que la conexion original era HTTPS
Habilitar el sitio y recargar Nginx:
ln -s /etc/nginx/sites-available/forgejo /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
client_max_body_size 512m permite subir repositorios y archivos grandes. Ajusta segun tus necesidades.
Opcion 2: Caddy
Caddy es mas simple: obtiene y renueva certificados Let’s Encrypt de forma automatica sin configuracion adicional.
Instalar Caddy
apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
| gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
| tee /etc/apt/sources.list.d/caddy-stable.list
apt update && apt install caddy
Caddyfile
Edita /etc/caddy/Caddyfile:
git.tudominio.com {
reverse_proxy localhost:3000
}
Eso es todo. Caddy obtiene el certificado de Let’s Encrypt automaticamente al primer arranque, lo renueva antes de que expire y redirige HTTP a HTTPS sin configuracion adicional.
Recargar Caddy:
systemctl reload caddy
Para ver los logs de Caddy y confirmar que obtuvo el certificado:
journalctl -u caddy -f
Actualizar app.ini
Independientemente del proxy elegido, debes actualizar ROOT_URL en app.ini para que Forgejo genere URLs correctas (clone URLs, emails, webhooks):
[server]
DOMAIN = git.tudominio.com
ROOT_URL = https://git.tudominio.com/
SSH_DOMAIN = git.tudominio.com
O via variable de entorno en docker-compose.yml:
environment:
- FORGEJO__server__DOMAIN=git.tudominio.com
- FORGEJO__server__ROOT_URL=https://git.tudominio.com/
- FORGEJO__server__SSH_DOMAIN=git.tudominio.com
Reinicia el contenedor despues del cambio:
docker compose restart forgejo
Actualizar docker-compose.yml
Con el reverse proxy funcionando, el puerto 3000 ya no debe estar expuesto al exterior. Solo el puerto SSH (22) necesita exposicion directa:
services:
forgejo:
image: codeberg.org/forgejo/forgejo:14
container_name: forgejo
restart: unless-stopped
environment:
- USER_UID=1000
- USER_GID=1000
- FORGEJO__server__DOMAIN=git.tudominio.com
- FORGEJO__server__ROOT_URL=https://git.tudominio.com/
volumes:
- forgejo-data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "22:22"
# Puerto 3000 eliminado: solo accesible desde el proxy
volumes:
forgejo-data:
Aplica el cambio:
docker compose up -d
Verificar que todo funciona
# Verificar respuesta HTTPS
curl -I https://git.tudominio.com
# Verificar que el certificado es valido
curl -v https://git.tudominio.com 2>&1 | grep -E "SSL|certificate|expire"
# Verificar que el puerto 3000 NO es accesible desde fuera
curl http://tu-ip-publica:3000 # debe fallar o no responder
La respuesta de Forgejo via HTTPS debe retornar HTTP/2 200 o HTTP/1.1 302 redirigiendo al login.
Siguiente: Capitulo 7: Gestion de usuarios y organizaciones —>