mirror of
https://github.com/aarmea/fahrengit-451.git
synced 2026-03-22 08:58:15 +00:00
126 lines
4.3 KiB
YAML
126 lines
4.3 KiB
YAML
services:
|
|
|
|
# ── Forgejo ────────────────────────────────────────────────────────────────
|
|
forgejo:
|
|
image: codeberg.org/forgejo/forgejo:9
|
|
container_name: forgejo
|
|
restart: unless-stopped
|
|
environment:
|
|
- USER_UID=1000
|
|
- USER_GID=1000
|
|
- FORGEJO__server__DOMAIN=${DOMAIN}
|
|
- FORGEJO__server__ROOT_URL=https://${DOMAIN}/
|
|
- FORGEJO__server__HTTP_PORT=3000
|
|
- FORGEJO__server__DISABLE_SSH=true
|
|
- FORGEJO__service__DISABLE_REGISTRATION=${DISABLE_REGISTRATION:-true}
|
|
- FORGEJO__database__DB_TYPE=sqlite3
|
|
- FORGEJO__database__PATH=/data/gitea/forgejo.db
|
|
- FORGEJO__log__LEVEL=Info
|
|
volumes:
|
|
- forgejo_data:/data
|
|
- /etc/timezone:/etc/timezone:ro
|
|
- /etc/localtime:/etc/localtime:ro
|
|
networks:
|
|
- internal
|
|
healthcheck:
|
|
test: ["CMD", "wget", "-qO-", "http://localhost:3000/api/healthz"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
|
|
# ── nginx (reverse proxy + GeoIP blocking) ─────────────────────────────────
|
|
nginx:
|
|
build:
|
|
context: ./nginx
|
|
dockerfile: Dockerfile
|
|
container_name: nginx
|
|
restart: unless-stopped
|
|
ports:
|
|
- "80:80"
|
|
- "443:443"
|
|
volumes:
|
|
# NOTE: conf.d is intentionally NOT mounted from the host — the nginx
|
|
# Docker entrypoint renders templates/git.conf.template into conf.d at
|
|
# container start, substituting ${DOMAIN}. Mounting conf.d from the host
|
|
# would shadow that rendered output and break the virtual host.
|
|
- ./nginx/geoblock:/etc/nginx/geoblock:ro # rendered by geoblock_watcher
|
|
- ./certs/live:/etc/letsencrypt/live:ro
|
|
- ./certs/archive:/etc/letsencrypt/archive:ro
|
|
- ./certs/options-ssl-nginx.conf:/etc/letsencrypt/options-ssl-nginx.conf:ro
|
|
- ./certs/ssl-dhparams.pem:/etc/letsencrypt/ssl-dhparams.pem:ro
|
|
- certbot_webroot:/var/www/certbot:ro
|
|
- geoip_db:/usr/share/GeoIP:ro
|
|
- nginx_logs:/var/log/nginx
|
|
networks:
|
|
- internal
|
|
depends_on:
|
|
- forgejo
|
|
environment:
|
|
- DOMAIN=${DOMAIN}
|
|
healthcheck:
|
|
test: ["CMD", "nginx", "-t"]
|
|
interval: 60s
|
|
timeout: 5s
|
|
retries: 3
|
|
|
|
# ── MaxMind GeoIP database updater ────────────────────────────────────────
|
|
geoipupdate:
|
|
image: ghcr.io/maxmind/geoipupdate:v7
|
|
container_name: geoipupdate
|
|
restart: unless-stopped
|
|
environment:
|
|
- GEOIPUPDATE_ACCOUNT_ID=${MAXMIND_ACCOUNT_ID}
|
|
- GEOIPUPDATE_LICENSE_KEY=${MAXMIND_LICENSE_KEY}
|
|
- GEOIPUPDATE_EDITION_IDS=GeoLite2-City
|
|
- GEOIPUPDATE_FREQUENCY=72 # hours — MaxMind updates twice a week
|
|
- GEOIPUPDATE_DB_DIR=/usr/share/GeoIP
|
|
volumes:
|
|
- geoip_db:/usr/share/GeoIP
|
|
networks:
|
|
- internal
|
|
|
|
# ── Geo-block config watcher ───────────────────────────────────────────────
|
|
# Watches geo_rules.yml; re-renders the nginx map snippet and reloads nginx
|
|
# whenever rules change.
|
|
geoblock_watcher:
|
|
build:
|
|
context: ./geoblock_watcher
|
|
dockerfile: Dockerfile
|
|
container_name: geoblock_watcher
|
|
restart: unless-stopped
|
|
volumes:
|
|
- ./config:/app/host:ro
|
|
- ./nginx/geoblock:/app/geoblock # shared with nginx (rw here)
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
networks:
|
|
- internal
|
|
depends_on:
|
|
- nginx
|
|
|
|
# ── Certbot (Let's Encrypt) ────────────────────────────────────────────────
|
|
certbot:
|
|
image: certbot/certbot:latest
|
|
container_name: certbot
|
|
restart: unless-stopped
|
|
volumes:
|
|
- ./certs:/etc/letsencrypt
|
|
- certbot_webroot:/var/www/certbot
|
|
entrypoint: >
|
|
/bin/sh -c "
|
|
trap exit TERM;
|
|
while :; do
|
|
certbot renew --webroot -w /var/www/certbot --quiet;
|
|
sleep 12h &
|
|
wait $${!};
|
|
done
|
|
"
|
|
|
|
volumes:
|
|
forgejo_data:
|
|
geoip_db:
|
|
certbot_webroot:
|
|
nginx_logs:
|
|
|
|
networks:
|
|
internal:
|
|
driver: bridge
|