166 lines
6.6 KiB
YAML
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
|