diff --git a/docs/deployment/hetzner-server-setup.md b/docs/deployment/hetzner-server-setup.md index a90f0d9e..ea0d99dd 100644 --- a/docs/deployment/hetzner-server-setup.md +++ b/docs/deployment/hetzner-server-setup.md @@ -330,8 +330,8 @@ services: - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro ports: - - "3000:3000" - - "2222:22" + - "127.0.0.1:3000:3000" # Localhost only — Caddy proxies git.wizard.lu + - "2222:22" # SSH must stay public (Caddy can't proxy SSH) depends_on: gitea-db: condition: service_healthy @@ -359,14 +359,16 @@ volumes: Generate the database password with `openssl rand -hex 16` and replace `` in both places. -Open the firewall for Gitea and start: +Start Gitea: ```bash -sudo ufw allow 3000/tcp docker compose up -d docker compose ps ``` +!!! note "Initial setup only" + For initial setup, temporarily change the Gitea port to `"3000:3000"` (without `127.0.0.1`) so you can access the web UI from your browser at `http://91.99.65.229:3000`. After Caddy is configured (Step 14), change it back to `"127.0.0.1:3000:3000"` and access via `https://git.wizard.lu` instead. + Visit `http://91.99.65.229:3000` and complete the setup wizard. Create an admin account (e.g. `sboulahtit`). Then create a repository (e.g. `orion`). @@ -435,6 +437,7 @@ Generate secrets: ```bash openssl rand -hex 32 # For JWT_SECRET_KEY openssl rand -hex 16 # For database password +openssl rand -hex 16 # For Redis password ``` | Variable | How to Generate / What to Set | @@ -444,7 +447,8 @@ openssl rand -hex 16 # For database password | `JWT_SECRET_KEY` | Output of `openssl rand -hex 32` | | `ADMIN_PASSWORD` | Strong password | | `USE_CELERY` | `true` | -| `REDIS_URL` | `redis://redis:6379/0` | +| `REDIS_PASSWORD` | Output of `openssl rand -hex 16` | +| `REDIS_URL` | `redis://redis:6379/0` (docker-compose handles auth via `REDIS_PASSWORD`) | | `STRIPE_SECRET_KEY` | Your Stripe secret key (configure later) | | `STRIPE_PUBLISHABLE_KEY` | Your Stripe publishable key (configure later) | | `STRIPE_WEBHOOK_SECRET` | Your Stripe webhook secret (configure later) | @@ -452,6 +456,9 @@ openssl rand -hex 16 # For database password Also update the PostgreSQL password in `docker-compose.yml` (lines 9 and 40) to match. +!!! danger "Docker bypasses UFW" + Docker manipulates iptables directly. Never use bare port mappings like `"5432:5432"` in docker-compose — they expose services to the internet regardless of UFW rules. See [Step 20.0](#200-docker-port-binding-critical-docker-bypasses-ufw) for details. + ## Step 11: Deploy with Docker Compose ```bash @@ -721,13 +728,19 @@ curl -I https://api.wizard.lu/health curl -I https://git.wizard.lu ``` -After Caddy is working, remove the temporary firewall rules: +After Caddy is working, lock down Gitea's port to localhost in `~/gitea/docker-compose.yml`: -```bash -sudo ufw delete allow 3000/tcp -sudo ufw delete allow 8001/tcp +```yaml +ports: + - "127.0.0.1:3000:3000" # Localhost only — Caddy proxies git.wizard.lu + - "2222:22" # SSH must stay public (Caddy can't proxy SSH) ``` +Then restart Gitea: `cd ~/gitea && docker compose up -d gitea` + +!!! warning "Do NOT rely on UFW for Docker ports" + Docker bypasses UFW entirely. The only way to restrict Docker port access is to bind to `127.0.0.1` in the port mapping. See [Step 20.0](#200-docker-port-binding-critical-docker-bypasses-ufw). + Update Gitea's configuration to use its new domain. In `~/gitea/docker-compose.yml`, change: ```yaml