- Document common Docker issues and filesystem permission problems - Include service management and configuration validation steps - Provide systematic debugging approach for Gitea deployment issues
3.3 KiB
3.3 KiB
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
read_only: true- Prevented s6-overlay from creating lock filesuser: "1000:1000"- Forced non-root start, breaking s6-overlay initializationMissing config values
- GITEA__server__ROOT_URL=https://ak-homelab.duckdns.org/gitea/
- GITEA__server__SSH_PORT=2223
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
- Overly restrictive security caps - Prevented proper container initialization
Key Understanding: s6-overlay Init System
Gitea uses s6-overlay which requires:
- Start as root to set up supervision tree and create lock files
- Then drop privileges to user specified by
USER_UID/USER_GIDenvironment variables
Setting user: "1000:1000" at Docker level bypassed this process.
The Solution
Working Docker Compose Configuration
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
- No Docker User Directive: Let s6-overlay handle user switching via
USER_UID/USER_GID - ROOT_URL: Required for asset serving through reverse proxy
- SSH_PORT: Must match external port for correct clone URLs
- 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:
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
- Understand service requirements before applying security hardening
- Some services need specific initialization processes (s6-overlay)
- Network access patterns matter (SSH vs HTTP proxy requirements)
- Test incrementally rather than applying multiple security changes at once