lotr-sut/devops-escape-room/docker-compose.yml
Fellowship Scholar f6a5823439 init commit
2026-03-29 20:07:56 +00:00

166 lines
6.6 KiB
YAML

# Fellowship DevOps Escape Room Stack
# Services: Jenkins (CI), Gitea (Git), code-server (IDE), MailHog (mail)
#
# Environment-aware Configuration
# Usage:
# Production: docker compose up -d (containers: fellowship_jenkins, etc.)
# Local dev: COMPOSE_PROJECT_NAME=fellowship-local docker compose up -d (containers: fellowship-local_jenkins, etc.)
#
# Access:
# Jenkins: http://localhost:8080 (user: fellowship / fellowship123)
# Gitea: http://localhost:3030 (user: fellowship / fellowship123)
# code-server: http://localhost:8443 (password: fellowship)
# MailHog UI: http://localhost:8025
#
# Note: code-server container automatically sets COMPOSE_PROJECT_NAME=fellowship-local via environment
services:
# ── Jenkins CI ──────────────────────────────────────────────────────────────
jenkins:
build:
context: ../jenkins
dockerfile: Dockerfile
image: fellowship-jenkins:latest
restart: unless-stopped
ports:
- "8080:8080"
- "50000:50000"
volumes:
- jenkins_home:/var/jenkins_home
# Mount Docker socket so Jenkins can run docker commands on the host
- /var/run/docker.sock:/var/run/docker.sock
environment:
JENKINS_ADMIN_PASSWORD: ${JENKINS_ADMIN_PASSWORD:-fellowship123}
CASC_JENKINS_CONFIG: /var/jenkins_home/casc_configs
# Set by setup_fellowship.sh when CADDY_DOMAIN is known.
# JCasC reads this to configure Jenkins' canonical root URL (used in build
# links, email notifications, etc.). Defaults to the plain HTTP address.
JENKINS_URL: ${JENKINS_URL:-http://localhost:8080/}
# Configure Jenkins to reach Gitea internally via docker network
GITEA_HTTP_URL: "http://gitea:3000"
depends_on:
gitea-init:
condition: service_completed_successfully
healthcheck:
test: ["CMD-SHELL", "curl -sf http://localhost:8080/login || exit 1"]
interval: 30s
timeout: 10s
retries: 5
start_period: 90s
# ── Gitea (self-hosted Git) ──────────────────────────────────────────────────
gitea:
image: gitea/gitea:1.22
restart: unless-stopped
ports:
- "3030:3000"
- "2222:22"
volumes:
- gitea_data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
environment:
USER_UID: "1000"
USER_GID: "1000"
GITEA__database__DB_TYPE: sqlite3
GITEA__server__DOMAIN: ${GITEA_DOMAIN:-localhost}
GITEA__server__HTTP_PORT: "3000"
GITEA__server__ROOT_URL: ${GITEA_ROOT_URL:-http://localhost:3030/}
GITEA__server__SSH_DOMAIN: localhost
GITEA__server__SSH_PORT: "2222"
GITEA__service__DISABLE_REGISTRATION: "false"
GITEA__service__REQUIRE_SIGNIN_VIEW: "false"
# INSTALL_LOCK: true after initialization. Admin will be created by gitea-init container via CLI
GITEA__security__INSTALL_LOCK: "true"
GITEA__admin__DEFAULT_EMAIL_NOTIFICATIONS: disabled
GITEA__mailer__ENABLED: "false"
# These are passed to gitea-init for CLI-based user creation, not used directly by Gitea
GITEA_ADMIN_USER: "${GITEA_ADMIN_USER:-fellowship}"
GITEA_ADMIN_PASSWORD: "${GITEA_ADMIN_PASSWORD:-fellowship123}"
GITEA_ADMIN_EMAIL: "${GITEA_ADMIN_EMAIL:-gandalf@fellowship.local}"
healthcheck:
test: ["CMD-SHELL", "curl -sf http://localhost:3000/api/v1/version || exit 1"]
interval: 15s
timeout: 5s
retries: 6
start_period: 30s
# ── Gitea Initializer (one-shot) ─────────────────────────────────────────────
gitea-init:
platform: linux/amd64
image: alpine:latest
restart: on-failure:5
environment:
GITEA_URL: "http://gitea:3000"
GITEA_ADMIN_USER: "${GITEA_ADMIN_USER:-fellowship}"
GITEA_ADMIN_PASSWORD: "${GITEA_ADMIN_PASSWORD:-fellowship123}"
GITEA_ADMIN_EMAIL: "${GITEA_ADMIN_EMAIL:-gandalf@fellowship.local}"
GITEA_ORG_NAME: "${GITEA_ORG_NAME:-fellowship-org}"
GITEA_REPO_NAME: "${GITEA_REPO_NAME:-lotr-sut}"
GITEA_DOMAIN: "${GITEA_DOMAIN:-}"
SUT_SOURCE_DIR: /sut-source
volumes:
- ../gitea/init.sh:/init.sh:ro
# Mount Docker socket for docker commands
- /var/run/docker.sock:/var/run/docker.sock:rw
# Mount only the SUT source, not the full project tree (avoids .env / secrets)
- ../sut:/sut-source/sut:ro
- ../docker-compose.yml:/sut-source/docker-compose.yml:ro
- ../caddy:/sut-source/caddy:ro
- ../nginx:/sut-source/nginx:ro
- ../Jenkinsfile:/sut-source/Jenkinsfile:ro
entrypoint: ["/bin/sh", "/init.sh"]
depends_on:
gitea:
condition: service_healthy
# ── code-server (VS Code in browser IDE) ────────────────────────────────────
code-server:
build:
context: ./code-server
dockerfile: Dockerfile
image: fellowship-code-server:latest
restart: unless-stopped
ports:
- "8443:8080"
volumes:
- ../:/home/coder/fellowship:rw
- codeserver_config:/home/coder/.config
# Mount host Docker socket so students can run `docker compose` from the IDE terminal.
# The entrypoint aligns the docker group GID at runtime automatically.
- /var/run/docker.sock:/var/run/docker.sock
environment:
PASSWORD: "${CODESERVER_PASSWORD:-fellowship}"
# Set compose project name to 'fellowship' so that students can run `docker compose` without -p flag.
COMPOSE_PROJECT_NAME: "fellowship-local"
# No `user:` here — the entrypoint runs as root to fix Docker group GID,
# then drops to the 'coder' user via gosu before starting code-server.
command:
- --auth=password
- --bind-addr=0.0.0.0:8080
- /home/coder/fellowship
healthcheck:
test: ["CMD-SHELL", "curl -sf http://localhost:8080/ || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
# ── MailHog (mock SMTP + web UI) ────────────────────────────────────────────
mailhog:
platform: linux/amd64
image: mailhog/mailhog:v1.0.1
restart: unless-stopped
ports:
- "1025:1025"
- "8025:8025"
volumes:
jenkins_home:
driver: local
gitea_data:
driver: local
codeserver_config:
driver: local