184 lines
5.8 KiB
YAML
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
|