HTTPS con reverse proxy

Por: Artiko
forgejohttpsnginxcaddyreverse-proxysslletsencrypt

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

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:

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 —>