diff --git a/docs/troubleshooting/gitea-troubleshooting-summary.md b/docs/troubleshooting/gitea-troubleshooting-summary.md new file mode 100644 index 0000000..2c25120 --- /dev/null +++ b/docs/troubleshooting/gitea-troubleshooting-summary.md @@ -0,0 +1,86 @@ +# Gitea Docker Troubleshooting - Complete Resolution + +## The Problem +Gitea container failing with: `s6-svscan: fatal: unable to open .s6-svscan/lock: Read-only file system` + +## Root Cause Analysis +The issue was **Docker security hardening interfering with Gitea's s6-overlay init system**. + +### What Broke Gitea +1. **`read_only: true`** - Prevented s6-overlay from creating lock files +2. **`user: "1000:1000"`** - Forced non-root start, breaking s6-overlay initialization +3. **`Missing config values`** + - GITEA__server__ROOT_URL=https://ak-homelab.duckdns.org/gitea/ + - GITEA__server__SSH_PORT=2223 +4. **`Overy restrictive port config`** + - "127.0.0.1:3000:3000" # Web UI localhost only: ok, since requests come in via reverse proxy + - "127.0.0.1:2223:22" # Git port on localhost: NOT OK, this prevents git push/pull from outside + - "2223:22" # <- Fixed config +5. **Overly restrictive security caps** - Prevented proper container initialization + +### Key Understanding: s6-overlay Init System +Gitea uses s6-overlay which requires: +1. **Start as root** to set up supervision tree and create lock files +2. **Then drop privileges** to user specified by `USER_UID`/`USER_GID` environment variables + +Setting `user: "1000:1000"` at Docker level bypassed this process. + +## The Solution + +### Working Docker Compose Configuration +```yaml +services: + server: + image: gitea/gitea:latest + container_name: gitea + environment: + - USER_UID=1000 + - USER_GID=1000 + - GITEA__server__ROOT_URL=https://ak-homelab.duckdns.org/gitea/ + - GITEA__server__SSH_PORT=2223 + restart: unless-stopped + + # DO NOT set user: directive - breaks s6-overlay init system + + ports: + - "127.0.0.1:3000:3000" # Web UI - localhost only (reverse proxy) + - "2223:22" # SSH - all interfaces (direct Git access) + + # Reasonable resource limits only + deploy: + resources: + limits: + memory: 1G +``` + +### Key Configuration Points + +1. **No Docker User Directive**: Let s6-overlay handle user switching via `USER_UID`/`USER_GID` +2. **ROOT_URL**: Required for asset serving through reverse proxy +3. **SSH_PORT**: Must match external port for correct clone URLs +4. **Port Binding**: SSH needs all interfaces, web UI can be localhost-only + +## Critical Port Configuration +- **Web UI**: `"127.0.0.1:3000:3000"` (through nginx reverse proxy) +- **SSH Git**: `"2223:22"` (direct access, NOT localhost-only) + +**Why SSH can't be localhost-only**: Git operations come from external router/clients and need direct container access. + +## Asset Loading Fix +Added `GITEA__server__ROOT_URL=https://ak-homelab.duckdns.org/gitea/` so Gitea serves assets with correct paths through reverse proxy. + +## Repository Migration +For fresh Gitea instances, bare repositories must be pushed via Git protocol: +```bash +git clone /path/to/bare/repo.git working-copy +cd working-copy +git remote set-url origin https://ak-homelab.duckdns.org/gitea/user/repo.git +git push -u origin --all +git push origin --tags +``` + +## Lessons Learned +1. **Understand service requirements** before applying security hardening +2. **Some services need specific initialization processes** (s6-overlay) +3. **Network access patterns matter** (SSH vs HTTP proxy requirements) +4. **Test incrementally** rather than applying multiple security changes at once