From 22e4ddcb460f97aaadc7ecdefb83ddb68bb80c6a Mon Sep 17 00:00:00 2001 From: Philip Henning Date: Tue, 28 Jan 2025 20:04:49 +0100 Subject: [PATCH] add init.sh option to deploy production or test; add test compose file --- docker-compose.test.yml | 173 ++++++++++++++++++++++++++++++++++++++++ scripts/init.sh | 65 ++++++++++----- 2 files changed, 216 insertions(+), 22 deletions(-) create mode 100644 docker-compose.test.yml diff --git a/docker-compose.test.yml b/docker-compose.test.yml new file mode 100644 index 0000000..a319c24 --- /dev/null +++ b/docker-compose.test.yml @@ -0,0 +1,173 @@ +--- + +services: + geoipupdate: + image: "maxmindinc/geoipupdate:latest" + volumes: + - "geoip:/usr/share/GeoIP" + environment: + GEOIPUPDATE_EDITION_IDS: "GeoLite2-City GeoLite2-ASN" + GEOIPUPDATE_FREQUENCY: "8" + GEOIPUPDATE_ACCOUNT_ID: "${GEOIPUPDATE_ACCOUNT_ID:?MaxMind GeoIP account ID required}" + GEOIPUPDATE_LICENSE_KEY: "${GEOIPUPDATE_LICENSE_KEY:?MaxMind GeoIP license key required}" + + postgresql: + image: docker.io/library/postgres:16-alpine + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] + start_period: 20s + interval: 30s + retries: 5 + timeout: 5s + volumes: + - database:/var/lib/postgresql/data + - backups_db:/var/lib/postgresql/backups + environment: + POSTGRES_PASSWORD: ${PG_PASS:?database password required} + POSTGRES_USER: ${PG_USER:-authentik} + POSTGRES_DB: ${PG_DB:-authentik} + env_file: + - .env + networks: + - backend + + redis: + image: docker.io/library/redis:alpine + command: --save 60 1 --loglevel warning + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "redis-cli ping | grep PONG"] + start_period: 20s + interval: 30s + retries: 5 + timeout: 3s + volumes: + - redis:/data + networks: + - backend + + server: + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.10.0} + restart: unless-stopped + command: server + environment: + AUTHENTIK_REDIS__HOST: redis + AUTHENTIK_POSTGRESQL__HOST: postgresql + AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik} + AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik} + AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS:?PG_PASS is required. - Password for authentik's postgresql database} + volumes: + - ./data/authentik/media:/media + - ./data/authentik/custom-templates:/templates + - geoip:/geoip + env_file: + - .env + depends_on: + - postgresql + - redis + networks: + - backend + - web + labels: + - "traefik.enable=true" + - "traefik.http.routers.sso.entrypoints=websecure" + - "traefik.http.routers.sso.rule=Host(`${PUBLIC_DOMAIN}`)" # change hostname! + - "traefik.http.routers.sso.tls=true" + - "traefik.http.routers.sso.tls.certresolver=pdns" + - "traefik.http.routers.sso.tls.domains[0].main=*.test.base23.de" + - "traefik.http.routers.sso.middlewares=secHeaders@file,hsts-header@file" + - "traefik.http.services.sso.loadbalancer.server.port=9443" # set port the container listenes to + - "traefik.http.services.sso.loadbalancer.server.scheme=https" + + worker: + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.10.0} + restart: unless-stopped + command: worker + environment: + AUTHENTIK_REDIS__HOST: redis + AUTHENTIK_POSTGRESQL__HOST: postgresql + AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik} + AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik} + AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS:?PG_PASS is required. - Password for authentik's postgresql database} + # `user: root` and the docker socket volume are optional. + # See more for the docker socket integration here: + # https://goauthentik.io/docs/outposts/integrations/docker + # Removing `user: root` also prevents the worker from fixing the permissions + # on the mounted folders, so when removing this make sure the folders have the correct UID/GID + # (1000:1000 by default) + user: root + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./data/authentik/media:/media + - ./data/authentik/certs:/certs + - ./data/authentik/custom-templates:/templates + - geoip:/geoip + env_file: + - .env + depends_on: + - postgresql + - redis + networks: + - backend + + backup: + image: registry.git.base23.de/base23/backup/resticker:0.17.0 + environment: + PRE_COMMANDS: |- + cd /compose-project/ + [[ $($(docker compose &>/dev/null); echo "$?") -eq 0 ]] || apk add --no-cache docker-cli-compose + docker compose exec -T postgresql pg_dump -U ${PG_USER:-authentik} -d ${PG_DB:-authentik} -f /var/lib/postgresql/backups/${PG_DB:-authentik}.sql + RUN_ON_STARTUP: "false" + BACKUP_CRON: "32 2 * * *" + RESTIC_REPOSITORY: sftp://${RESTIC_REPO_USER:?Restic repository user is required}@${RESTIC_REPO_ADDRESS:?Restic repository address is requried}:${RESTIC_REPO_PORT:?Restic repository port is required}//backup + RESTIC_PASSWORD: '${RESTIC_REPO_PASSWORD:?Restic repository password is required}' + RESTIC_BACKUP_SOURCES: /var/lib/postgresql/backups /var/lib/authentik/backups /var/lib/lego/backups + RESTIC_BACKUP_ARGS: >- + --tag ${RESTIC_TAG:?Restic tag is required} + --verbose + RESTIC_FORGET_ARGS: >- + --keep-last 10 + --keep-daily 7 + --keep-weekly 5 + --keep-monthly 12 + TZ: Europe/Berlin + volumes: + - ./data/restic/ssh/:/run/secrets/.ssh:ro + - /var/run/docker.sock:/var/run/docker.sock + - ./docker-compose.yml:/compose-project/docker-compose.yml:ro + - ./.env:/compose-project/.env:ro + - backups_db:/var/lib/postgresql/backups:ro + - ./data/authentik/certs:/var/lib/authentik/backups/certs:ro + - ./data/authentik/custom-templates:/var/lib/authentik/backups/templates:ro + - ./data/authentik/media:/var/lib/authentik/backups/media:ro + - ./data/.lego:/var/lib/lego/backups:ro + + prune-backup: + image: registry.git.base23.de/base23/backup/resticker:0.17.0 + environment: + SKIP_INIT: "true" + RUN_ON_STARTUP: "false" + PRUNE_CRON: "47 3 * * *" + RESTIC_REPOSITORY: sftp://${RESTIC_REPO_USER:?Restic repository user is required}@${RESTIC_REPO_ADDRESS:?Restic repository address is requried}:${RESTIC_REPO_PORT:?Restic repository port is required}//backup + RESTIC_PASSWORD: '${RESTIC_REPO_PASSWORD:?Restic repository password is required}' + TZ: Europe/Berlin + volumes: + - ./data/restic/ssh/:/run/secrets/.ssh:ro + + +volumes: + backups_db: + driver: local + database: + driver: local + redis: + driver: local + geoip: + driver: local + + +networks: + backend: + web: + external: true diff --git a/scripts/init.sh b/scripts/init.sh index 587935b..17acdb9 100755 --- a/scripts/init.sh +++ b/scripts/init.sh @@ -30,6 +30,24 @@ trap 'printf "\nOperation aborted by user.\n" >&2; exit 1' SIGINT cd "$(dirname "$(realpath "$0")")/../" AUTHENTIK_DOCKER_COMPOSE_PATH="$(realpath "$(pwd)")" +# Ask if initialized for production or test +while true; do + read -p "Do you want to init a [P]roduction or [T]est environment? (P/T): " DEPLOYMENT_ENVIRONMENT + case "$DEPLOYMENT_ENVIRONMENT" in + [Pp]* ) + DEPLOYMENT_ENVIRONMENT="PRODUCTION" + break + ;; + [Tt]* ) + DEPLOYMENT_ENVIRONMENT="TEST" + break + ;; + * ) + echo "Please answer with P or T." + ;; + esac +done + # Check if .env exists and exit if it is if [[ ! -f ./.env ]]; then cat ./env.template >> ./.env @@ -43,7 +61,7 @@ if [[ ! -f ./.env ]]; then fi # Check if lego.env exists and exit if it is -if [[ ! -f ./lego.env ]]; then +if [[ ! -f ./lego.env && "${DEPLOYMENT_ENVIRONMENT}" == "PRODUCTION" ]]; then echo "# Lego - Let's Encrypt certificate tool" >> ./lego.env prompt_password HETZNER_API_KEY; echo "HETZNER_API_KEY=${RETURNED_PASSWORD}" >> ./lego.env; unset RETURNED_PASSWORD echo "" >> ./.env @@ -54,29 +72,31 @@ fi [[ ! -f ./data/restic/ssh/id_ed25519 ]] && ssh-keygen -t ed25519 -C "sso.base23.de" -f ./data/restic/ssh/id_ed25519 # Generate dhparam, if not existing -[[ ! -d ./data/nginx/certs ]] && mkdir -p ./data/nginx/certs && chmod 700 ./data/nginx/certs && chown 101:101 ./data/nginx/certs || true -[[ ! -f ./data/nginx/dhparams.pem ]] && echo "" && openssl dhparam -out ./data/nginx/dhparams.pem 4096 && chown 101:101 ./data/nginx/dhparams.pem \ - && echo "" && echo "Checking generated dhparams" && openssl dhparam -check -in ./data/nginx/dhparams.pem || true +if [[ "${DEPLOYMENT_ENVIRONMENT}" == "PRODUCTION" ]]; then + [[ ! -d ./data/nginx/certs ]] && mkdir -p ./data/nginx/certs && chmod 700 ./data/nginx/certs && chown 101:101 ./data/nginx/certs || true + [[ ! -f ./data/nginx/dhparams.pem ]] && echo "" && openssl dhparam -out ./data/nginx/dhparams.pem 4096 && chown 101:101 ./data/nginx/dhparams.pem \ + && echo "" && echo "Checking generated dhparams" && openssl dhparam -check -in ./data/nginx/dhparams.pem || true -# Create certificate -if [[ ! -d ./data/.lego ]]; then - echo "" - echo "Create certificate" - lego \ - --path ./data/.lego \ - --accept-tos \ - --email="acme@base23.de" \ - --domains="*.base23.de" \ - --dns hetzner \ - run \ - && install -m 400 -o 101 -g 101 "./data/.lego/certificates"/{_.base23.de.crt,_.base23.de.issuer.crt,_.base23.de.key} "./data/nginx/certs" -fi -# Setup directory for acme cheallenges -[[ ! -d ./data/nginx/acme ]] && mkdir -p ./data/nginx/acme + # Create certificate + if [[ ! -d ./data/.lego ]]; then + echo "" + echo "Create certificate" + lego \ + --path ./data/.lego \ + --accept-tos \ + --email="acme@base23.de" \ + --domains="*.base23.de" \ + --dns hetzner \ + run \ + && install -m 400 -o 101 -g 101 "./data/.lego/certificates"/{_.base23.de.crt,_.base23.de.issuer.crt,_.base23.de.key} "./data/nginx/certs" + fi -# Setup cronjob to automatically renew certificates -[[ ! -f /etc/systemd/system/lego-renew-wildcard-base23-de.service ]] && cat < /etc/systemd/system/lego-renew-wildcard-base23-de.service && systemctl daemon-reload + # Setup directory for acme cheallenges + [[ ! -d ./data/nginx/acme ]] && mkdir -p ./data/nginx/acme + + # Setup cronjob to automatically renew certificates + [[ ! -f /etc/systemd/system/lego-renew-wildcard-base23-de.service ]] && cat < /etc/systemd/system/lego-renew-wildcard-base23-de.service && systemctl daemon-reload [Unit] Description=SSL Certificate renewal for *.base23.de with LEGO Documentation=https://go-acme.github.io/lego/ @@ -96,7 +116,7 @@ RemainAfterExit=no WantedBy=multi-user.target EOF -[[ ! -f /etc/systemd/system/lego-renew-wildcard-base23-de.timer ]] && cat < /etc/systemd/system/lego-renew-wildcard-base23-de.timer && systemctl daemon-reload && systemctl enable --now lego-renew-wildcard-base23-de.timer + [[ ! -f /etc/systemd/system/lego-renew-wildcard-base23-de.timer ]] && cat < /etc/systemd/system/lego-renew-wildcard-base23-de.timer && systemctl daemon-reload && systemctl enable --now lego-renew-wildcard-base23-de.timer [Unit] Description=SSL Certificate renewal for *.base23.de with LEGO Timer @@ -109,3 +129,4 @@ Persistent=true [Install] WantedBy=timers.target EOF +fi