diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index c002ba91..34d9d9fe 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -698,19 +698,13 @@ services: - GITEA__service__ENABLE_REVERSE_PROXY_EMAIL=false - GITEA__service__REVERSE_PROXY_AUTHENTICATION_HEADER=X-WEBAUTH-USER - GITEA__service__REQUIRE_SIGNIN_VIEW=true - # Skip installation wizard — admin user created by gitea-init.sh + # Skip installation wizard — admin user created by gitea-init container - GITEA__security__INSTALL_LOCK=true - # Admin user creation (used by gitea-init.sh on first boot) - - GITEA_ADMIN_USER=${GITEA_ADMIN_USER:-admin} - - GITEA_ADMIN_PASSWORD=${GITEA_ADMIN_PASSWORD:-} - - GITEA_ADMIN_EMAIL=${INITIAL_ADMIN_EMAIL:-admin@cmlite.org} restart: unless-stopped volumes: - gitea-data:/data - - ./scripts/gitea-init.sh:/custom/gitea-init.sh:ro - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro - command: ["/bin/sh", "/custom/gitea-init.sh"] ports: - "127.0.0.1:${GITEA_WEB_PORT:-3030}:3000" - "127.0.0.1:${GITEA_SSH_PORT:-2222}:22" @@ -740,6 +734,26 @@ services: networks: - changemaker-lite + # Gitea Init — creates admin user on first boot (after gitea-app is healthy) + gitea-init: + image: ${GITEA_REGISTRY:-gitea.bnkops.com/admin}/gitea:1.23.7 + container_name: gitea-init + depends_on: + gitea-app: + condition: service_healthy + restart: "no" + environment: + - GITEA_ADMIN_USER=${GITEA_ADMIN_USER:-admin} + - GITEA_ADMIN_PASSWORD=${GITEA_ADMIN_PASSWORD:-} + - GITEA_ADMIN_EMAIL=${INITIAL_ADMIN_EMAIL:-admin@cmlite.org} + volumes: + - gitea-data:/data + - ./scripts/gitea-init.sh:/init.sh:ro + entrypoint: ["/bin/sh", "/init.sh"] + logging: *default-logging + networks: + - changemaker-lite + # Mini QR — QR code generator mini-qr: image: ${GITEA_REGISTRY:-gitea.bnkops.com/admin}/mini-qr:v0.26.0 diff --git a/docker-compose.yml b/docker-compose.yml index 6e8d761c..8c39466e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -717,19 +717,13 @@ services: - GITEA__service__ENABLE_REVERSE_PROXY_EMAIL=false - GITEA__service__REVERSE_PROXY_AUTHENTICATION_HEADER=X-WEBAUTH-USER - GITEA__service__REQUIRE_SIGNIN_VIEW=true - # Skip installation wizard — admin user created by gitea-init.sh + # Skip installation wizard — admin user created by gitea-init container - GITEA__security__INSTALL_LOCK=true - # Admin user creation (used by gitea-init.sh on first boot) - - GITEA_ADMIN_USER=${GITEA_ADMIN_USER:-admin} - - GITEA_ADMIN_PASSWORD=${GITEA_ADMIN_PASSWORD:-} - - GITEA_ADMIN_EMAIL=${INITIAL_ADMIN_EMAIL:-admin@cmlite.org} restart: unless-stopped volumes: - gitea-data:/data - - ./scripts/gitea-init.sh:/custom/gitea-init.sh:ro - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro - command: ["/bin/sh", "/custom/gitea-init.sh"] ports: - "127.0.0.1:${GITEA_WEB_PORT:-3030}:3000" - "127.0.0.1:${GITEA_SSH_PORT:-2222}:22" @@ -759,6 +753,26 @@ services: networks: - changemaker-lite + # Gitea Init — creates admin user on first boot (after gitea-app is healthy) + gitea-init: + image: gitea/gitea:1.23.7 + container_name: gitea-init + depends_on: + gitea-app: + condition: service_healthy + restart: "no" + environment: + - GITEA_ADMIN_USER=${GITEA_ADMIN_USER:-admin} + - GITEA_ADMIN_PASSWORD=${GITEA_ADMIN_PASSWORD:-} + - GITEA_ADMIN_EMAIL=${INITIAL_ADMIN_EMAIL:-admin@cmlite.org} + volumes: + - gitea-data:/data + - ./scripts/gitea-init.sh:/init.sh:ro + entrypoint: ["/bin/sh", "/init.sh"] + logging: *default-logging + networks: + - changemaker-lite + # Mini QR — QR code generator mini-qr: image: ghcr.io/lyqht/mini-qr:v0.26.0 diff --git a/scripts/gitea-init.sh b/scripts/gitea-init.sh index bf9eea49..2d7a0ffd 100755 --- a/scripts/gitea-init.sh +++ b/scripts/gitea-init.sh @@ -1,62 +1,44 @@ #!/bin/sh # ============================================================================= -# Gitea Initialization Script +# Gitea Admin User Initialization # ============================================================================= -# Replaces the default CMD in the Gitea Docker container. -# Runs database migrations, creates the admin user (if credentials are provided -# and the user doesn't already exist), then starts the Gitea web server. -# -# The Gitea entrypoint (/usr/bin/entrypoint) has already: -# - Set up UID/GID, created directories, generated app.ini from GITEA__* env vars -# But it exec's our CMD still as root — Gitea refuses to run as root. -# We must drop to the 'git' user before running any gitea commands. +# Runs as a separate init container (like nocodb-init) AFTER gitea-app is healthy. +# Shares the gitea-data volume so the app.ini config is available. +# Creates the admin user if it doesn't exist, then exits. # ============================================================================= set -e PREFIX="[gitea-init]" log() { echo "$PREFIX $1"; } -# Drop privileges: Gitea refuses to run as root. The Docker entrypoint -# sets up directories as root, then exec's the CMD (us) — still as root. -# Re-exec this script as the 'git' user via su-exec. -if [ "$(id -u)" = "0" ]; then - log "Dropping to git user..." - exec su-exec git "$0" "$@" +# The gitea binary needs app.ini to know the database connection. +# On the Gitea Docker image, GITEA_CUSTOM defaults to /data/gitea +# and app.ini lives at /data/gitea/conf/app.ini (created by gitea-app's entrypoint). +export GITEA_CUSTOM="${GITEA_CUSTOM:-/data/gitea}" + +if [ ! -f "$GITEA_CUSTOM/conf/app.ini" ]; then + log "ERROR: No app.ini found at $GITEA_CUSTOM/conf/app.ini" + log "This means gitea-app hasn't completed its first startup yet." + exit 1 fi -# --- Step 1: Run database migrations --- -log "Running database migrations..." -MIGRATE_OK=false -for i in $(seq 1 10); do - if gitea migrate 2>&1; then - MIGRATE_OK=true - log "Migrations complete" - break - fi - log "Waiting for database... (attempt $i/10)" - sleep 3 -done +log "Found app.ini at $GITEA_CUSTOM/conf/app.ini" -if [ "$MIGRATE_OK" = false ]; then - log "WARNING: Migrations may not have completed — starting anyway" +if [ -z "$GITEA_ADMIN_USER" ] || [ -z "$GITEA_ADMIN_PASSWORD" ] || [ -z "$GITEA_ADMIN_EMAIL" ]; then + log "No GITEA_ADMIN_USER/PASSWORD/EMAIL set — skipping" + exit 0 fi -# --- Step 2: Create admin user if credentials provided --- -if [ -n "$GITEA_ADMIN_USER" ] && [ -n "$GITEA_ADMIN_PASSWORD" ] && [ -n "$GITEA_ADMIN_EMAIL" ]; then - log "Creating admin user '${GITEA_ADMIN_USER}'..." - if gitea admin user create --admin \ - --username "$GITEA_ADMIN_USER" \ - --password "$GITEA_ADMIN_PASSWORD" \ - --email "$GITEA_ADMIN_EMAIL" \ - --must-change-password false 2>&1; then - log "Admin user created successfully" - else - log "Admin user already exists (or creation skipped)" - fi +# Create admin user (idempotent — returns non-zero if user exists) +log "Creating admin user '${GITEA_ADMIN_USER}' (${GITEA_ADMIN_EMAIL})..." +if gitea admin user create --admin \ + --username "$GITEA_ADMIN_USER" \ + --password "$GITEA_ADMIN_PASSWORD" \ + --email "$GITEA_ADMIN_EMAIL" \ + --must-change-password false 2>&1; then + log "Admin user created successfully" else - log "No GITEA_ADMIN_USER/PASSWORD/EMAIL set — skipping admin creation" + log "Admin user already exists (or creation skipped)" fi -# --- Step 3: Start Gitea web server --- -log "Starting Gitea web server..." -exec gitea web +log "Done"