platform-deployments/docker/forgejo/docker-compose.yml
2026-03-05 21:30:08 -08:00

184 lines
5.8 KiB
YAML

# Forgejo - Self-hosted DevOps Stack
# Deploys to: 'devops' role (see deployments/hosts/roles.yaml)
# Docs: https://forgejo.org/docs/latest/admin/
#
# Deployment:
# ./deployments/scripts/deploy-devops-stack.sh
#
# Manual usage (resolves host from role):
# TARGET=$(source lib/hosts.sh && get_role_host devops)
# scp -r deployments/docker/forgejo $TARGET:/bigdisk/forgejo/
# ssh $TARGET "cd /bigdisk/forgejo && docker-compose up -d"
#
# SSL Certificates (self-signed, VPN-only):
# mkdir -p ssl && cd ssl
# # forge.nasty.sh
# openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
# -keyout forge.nasty.sh.key -out forge.nasty.sh.crt \
# -subj '/CN=forge.nasty.sh' -addext 'subjectAltName=DNS:forge.nasty.sh'
# # npm.nasty.sh (Verdaccio)
# openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
# -keyout npm.nasty.sh.key -out npm.nasty.sh.crt \
# -subj '/CN=npm.nasty.sh' -addext 'subjectAltName=DNS:npm.nasty.sh'
#
# Access (VPN-only, add to /etc/hosts with IP from roles.yaml):
# <devops-role-ip> forge.nasty.sh npm.nasty.sh
#
# Features:
# - Git repositories (Forgejo)
# - NPM/PyPI/Container registries (Forgejo)
# - Forgejo Actions (built-in CI)
# - Verdaccio NPM cache (npm.nasty.sh)
services:
nginx:
image: nginx:alpine
container_name: forgejo-nginx
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "2222:2222"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
networks:
- forgejo
depends_on:
- forgejo
forgejo:
image: codeberg.org/forgejo/forgejo:11
container_name: forgejo
environment:
- USER_UID=1000
- USER_GID=1000
# Database
- FORGEJO__database__DB_TYPE=postgres
- FORGEJO__database__HOST=db:5432
- FORGEJO__database__NAME=forgejo
- FORGEJO__database__USER=forgejo
- FORGEJO__database__PASSWD=${FORGEJO_DB_PASSWORD}
# Server
- FORGEJO__server__DOMAIN=forge.black.local
- FORGEJO__server__SSH_DOMAIN=forge.black.local
- FORGEJO__server__ROOT_URL=http://forge.black.local/
- FORGEJO__server__SSH_PORT=2222
- FORGEJO__server__SSH_LISTEN_PORT=22
- FORGEJO__server__LFS_START_SERVER=true
# Security
- FORGEJO__security__INSTALL_LOCK=true
- FORGEJO__security__SECRET_KEY=${FORGEJO_SECRET_KEY}
- FORGEJO__security__INTERNAL_TOKEN=${FORGEJO_INTERNAL_TOKEN}
# Service settings
- FORGEJO__service__DISABLE_REGISTRATION=true
- FORGEJO__service__REQUIRE_SIGNIN_VIEW=false
- FORGEJO__service__DEFAULT_KEEP_EMAIL_PRIVATE=true
# Package registries
- FORGEJO__packages__ENABLED=true
# Actions (CI/CD)
- FORGEJO__actions__ENABLED=true
- FORGEJO__actions__DEFAULT_ACTIONS_URL=https://code.forgejo.org
# OAuth2 JWT
- FORGEJO__oauth2__JWT_SECRET=${FORGEJO_JWT_SECRET}
restart: unless-stopped
networks:
- forgejo
volumes:
- ./data/forgejo:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
expose:
- "3000"
- "22"
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
container_name: forgejo-db
restart: unless-stopped
environment:
- POSTGRES_USER=forgejo
- POSTGRES_PASSWORD=${FORGEJO_DB_PASSWORD}
- POSTGRES_DB=forgejo
networks:
- forgejo
volumes:
- ./data/postgres:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "forgejo"]
interval: 10s
timeout: 5s
retries: 5
runner:
image: code.forgejo.org/forgejo/runner:6.2.1
container_name: forgejo-runner
command: forgejo-runner daemon
restart: unless-stopped
depends_on:
- forgejo
# Get docker GID with: ssh <devops-host> "getent group docker | cut -d: -f3"
# HOST-SPECIFIC: Update this GID when migrating to new host
group_add:
- "${DOCKER_GID:-1001}"
volumes:
- ./data/runner:/data
- /var/run/docker.sock:/var/run/docker.sock
networks:
- forgejo
# Runner registration:
# docker exec -u git forgejo forgejo actions generate-runner-token
# docker run --rm -v ./data/runner:/data code.forgejo.org/forgejo/runner:6.2.1 \
# forgejo-runner register --instance http://localhost:3000 --token <TOKEN> --name $(hostname)-runner --no-interactive
# ==========================================================================
# pypiserver - Python Package Index (proxied via nginx at pypi.black.local)
# ==========================================================================
pypi:
image: pypiserver/pypiserver:latest
container_name: pypiserver
restart: unless-stopped
command: run -P . -a . --server wsgiref
volumes:
- /bigdisk/pypi/packages:/data/packages
expose:
- "8080"
networks:
- forgejo
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:8080/"]
interval: 30s
timeout: 10s
retries: 3
# ==========================================================================
# Verdaccio - NPM Cache (proxied via nginx at npm.black.local)
# ==========================================================================
verdaccio:
image: verdaccio/verdaccio:6
container_name: verdaccio
restart: unless-stopped
environment:
- VERDACCIO_PORT=4873
- VERDACCIO_PUBLIC_URL=http://npm.black.local
- FORGEJO_NPM_TOKEN=${FORGEJO_NPM_TOKEN}
expose:
- "4873"
volumes:
- /bigdisk/verdaccio/storage:/verdaccio/storage
- /bigdisk/verdaccio/config:/verdaccio/conf
networks:
- forgejo
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:4873/-/ping"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
networks:
forgejo:
driver: bridge