diff --git a/README.md b/README.md index 0edcb7b..246620d 100644 --- a/README.md +++ b/README.md @@ -67,5 +67,7 @@ Bootstrap Authentik on Synology: ```bash cd /volume1/docker/dc-cms/source/infra -sudo /usr/local/bin/docker compose --env-file .env.synology -f docker-compose.yml exec -T authentik-worker sh -lc 'set -e; export PATH="${VENV_PATH}/bin:${PATH}"; for bp in default/flow-default-authentication-flow.yaml default/flow-default-invalidation-flow.yaml default/flow-default-provider-authorization-implicit-consent.yaml; do /lifecycle/ak apply_blueprint "$bp"; done; /lifecycle/ak shell < /bootstrap/bootstrap-cms.py' +sudo env CMS_ENV_FILE=.env.synology sh ./scripts/bootstrap-authentik.sh ``` + +Bootstrap выполняется так же, как в платформе NODE.DC: через `authentik-server ak shell < authentik/bootstrap-cms.py`. Ручной вход в worker, `VENV_PATH` и отдельный `apply_blueprint` не являются штатным сценарием. diff --git a/infra/docker-compose.yml b/infra/docker-compose.yml index de4a878..2e1737a 100644 --- a/infra/docker-compose.yml +++ b/infra/docker-compose.yml @@ -111,7 +111,6 @@ services: image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2026.2.2} command: worker restart: unless-stopped - user: root env_file: - ${CMS_SERVICE_ENV_FILE:-.env} environment: @@ -129,7 +128,6 @@ services: - authentik-data:/data - authentik-certs:/certs - ./authentik/custom-templates:/templates:ro - - ./authentik/bootstrap-cms.py:/bootstrap/bootstrap-cms.py:ro networks: - cms-edge diff --git a/infra/scripts/bootstrap-authentik.sh b/infra/scripts/bootstrap-authentik.sh index 0bbde15..8be86e4 100755 --- a/infra/scripts/bootstrap-authentik.sh +++ b/infra/scripts/bootstrap-authentik.sh @@ -1,20 +1,91 @@ -#!/usr/bin/env bash -set -euo pipefail +#!/usr/bin/env sh +set -eu -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -INFRA_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" +SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +INFRA_DIR=$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd) +ROOT_DIR=$(CDPATH= cd -- "$INFRA_DIR/.." && pwd) +ENV_FILE="${CMS_ENV_FILE:-$INFRA_DIR/.env}" +COMPOSE_FILE="${CMS_COMPOSE_FILE:-$INFRA_DIR/docker-compose.yml}" +BOOTSTRAP_SCRIPT="$INFRA_DIR/authentik/bootstrap-cms.py" -cd "${INFRA_DIR}" +case "$ENV_FILE" in + /*) ;; + *) ENV_FILE="$INFRA_DIR/$ENV_FILE" ;; +esac -docker compose --env-file "${CMS_ENV_FILE:-.env}" -f docker-compose.yml exec -T authentik-worker sh -lc ' - set -e - export PATH="${VENV_PATH}/bin:${PATH}" - for bp in \ - default/flow-default-authentication-flow.yaml \ - default/flow-default-invalidation-flow.yaml \ - default/flow-default-provider-authorization-implicit-consent.yaml - do - /lifecycle/ak apply_blueprint "$bp" - done - /lifecycle/ak shell < /bootstrap/bootstrap-cms.py -' +case "$COMPOSE_FILE" in + /*) ;; + *) COMPOSE_FILE="$INFRA_DIR/$COMPOSE_FILE" ;; +esac + +if [ ! -f "$ENV_FILE" ]; then + echo "Missing $ENV_FILE. Create it from infra/.env.example or infra/.env.synology.example first." >&2 + exit 1 +fi + +env_value() { + key="$1" + awk -v wanted="$key" ' + /^[[:space:]]*($|#)/ { next } + { + line = $0 + sub(/^[[:space:]]+/, "", line) + eq = index(line, "=") + if (!eq) { next } + key = substr(line, 1, eq - 1) + sub(/[[:space:]]+$/, "", key) + if (key != wanted) { next } + value = substr(line, eq + 1) + sub(/^[[:space:]]+/, "", value) + sub(/[[:space:]]+$/, "", value) + if (value ~ /^".*"$/ || value ~ /^'\''.*'\''$/) { + value = substr(value, 2, length(value) - 2) + } + print value + exit + } + ' "$ENV_FILE" +} + +env_default() { + value=$(env_value "$1") + if [ -n "$value" ]; then + printf '%s' "$value" + else + printf '%s' "$2" + fi +} + +env_required() { + value=$(env_value "$1") + if [ -z "$value" ]; then + echo "$2" >&2 + exit 1 + fi + printf '%s' "$value" +} + +CMS_AUTH_DOMAIN_VALUE=$(env_default CMS_AUTH_DOMAIN cms-auth.local.nodedc) +CMS_BOOTSTRAP_ADMIN_EMAIL_VALUE=$(env_default CMS_BOOTSTRAP_ADMIN_EMAIL "") +CMS_BOOTSTRAP_ADMIN_PASSWORD_VALUE=$(env_default CMS_BOOTSTRAP_ADMIN_PASSWORD "") +CMS_BOOTSTRAP_ADMIN_NAME_VALUE=$(env_default CMS_BOOTSTRAP_ADMIN_NAME "") +CMS_BASE_URL_VALUE=$(env_default CMS_BASE_URL http://cms.local.nodedc:8210) +CMS_LOGOUT_URI_VALUE=$(env_default CMS_LOGOUT_URI http://cms.local.nodedc:8210/auth/logout) +CMS_OIDC_CLIENT_ID_VALUE=$(env_default CMS_OIDC_CLIENT_ID dc-cms) +CMS_OIDC_CLIENT_SECRET_VALUE=$(env_required CMS_OIDC_CLIENT_SECRET "CMS_OIDC_CLIENT_SECRET is required") +CMS_OIDC_REDIRECT_URI_VALUE=$(env_required CMS_OIDC_REDIRECT_URI "CMS_OIDC_REDIRECT_URI is required") +CMS_OIDC_LOGGED_OUT_REDIRECT_URI_VALUE=$(env_default CMS_OIDC_LOGGED_OUT_REDIRECT_URI "") + +cd "$ROOT_DIR" +docker compose --env-file "$ENV_FILE" -f "$COMPOSE_FILE" exec -T \ + -e CMS_AUTH_DOMAIN="$CMS_AUTH_DOMAIN_VALUE" \ + -e CMS_BOOTSTRAP_ADMIN_EMAIL="$CMS_BOOTSTRAP_ADMIN_EMAIL_VALUE" \ + -e CMS_BOOTSTRAP_ADMIN_PASSWORD="$CMS_BOOTSTRAP_ADMIN_PASSWORD_VALUE" \ + -e CMS_BOOTSTRAP_ADMIN_NAME="$CMS_BOOTSTRAP_ADMIN_NAME_VALUE" \ + -e CMS_BASE_URL="$CMS_BASE_URL_VALUE" \ + -e CMS_LOGOUT_URI="$CMS_LOGOUT_URI_VALUE" \ + -e CMS_OIDC_CLIENT_ID="$CMS_OIDC_CLIENT_ID_VALUE" \ + -e CMS_OIDC_CLIENT_SECRET="$CMS_OIDC_CLIENT_SECRET_VALUE" \ + -e CMS_OIDC_REDIRECT_URI="$CMS_OIDC_REDIRECT_URI_VALUE" \ + -e CMS_OIDC_LOGGED_OUT_REDIRECT_URI="$CMS_OIDC_LOGGED_OUT_REDIRECT_URI_VALUE" \ + authentik-server ak shell < "$BOOTSTRAP_SCRIPT"