diff options
Diffstat (limited to 'scripts/init-docker.sh')
| -rwxr-xr-x | scripts/init-docker.sh | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/scripts/init-docker.sh b/scripts/init-docker.sh new file mode 100755 index 0000000..4bae29b --- /dev/null +++ b/scripts/init-docker.sh @@ -0,0 +1,157 @@ +#!/bin/sh + +set -eu + +SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +PROJECT_DIR=$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd) +FORCE_USER=no + +if [ "${1:-}" = "--force-user" ]; then + FORCE_USER=yes +elif [ "$#" -gt 0 ]; then + printf 'Usage: %s [--force-user]\n' "$0" >&2 + exit 1 +fi + +if [ ! -f "$PROJECT_DIR/.env" ]; then + cp "$PROJECT_DIR/.env.example" "$PROJECT_DIR/.env" + printf 'Created .env from .env.example\n' +fi + +set -a +. "$PROJECT_DIR/.env" +set +a + +BASE_DOMAIN=${BASE_DOMAIN:-tdwiki.home.arpa} + +case "$BASE_DOMAIN" in + *[!a-zA-Z0-9.-]*|.*|*.) + printf 'Invalid BASE_DOMAIN: %s\n' "$BASE_DOMAIN" >&2 + exit 1 + ;; +esac + +mkdir -p \ + "$PROJECT_DIR/data/authelia" \ + "$PROJECT_DIR/data/caddy/data" \ + "$PROJECT_DIR/data/caddy/config" \ + "$PROJECT_DIR/secrets" + +chmod 700 "$PROJECT_DIR/secrets" + +generate_secret() { + file=$1 + bytes=$2 + if [ ! -s "$file" ]; then + umask 077 + openssl rand -hex "$bytes" > "$file" + printf 'Generated %s\n' "${file#"$PROJECT_DIR/"}" + fi +} + +generate_secret "$PROJECT_DIR/secrets/authelia_jwt_secret" 32 +generate_secret "$PROJECT_DIR/secrets/authelia_session_secret" 32 +generate_secret "$PROJECT_DIR/secrets/authelia_storage_encryption_key" 32 + +sed "s/__BASE_DOMAIN__/$BASE_DOMAIN/g" \ + "$PROJECT_DIR/docker/authelia/configuration.template.yml" \ + > "$PROJECT_DIR/docker/authelia/configuration.yml" + +USERS_FILE="$PROJECT_DIR/docker/authelia/users_database.yml" + +if [ ! -f "$USERS_FILE" ] || [ "$FORCE_USER" = yes ]; then + USERNAME=${AUTHELIA_USERNAME:-} + DISPLAY_NAME=${AUTHELIA_DISPLAY_NAME:-} + EMAIL=${AUTHELIA_EMAIL:-} + PASSWORD=${AUTHELIA_PASSWORD:-} + + if [ -z "$USERNAME" ]; then + printf 'Authelia username [admin]: ' + read -r USERNAME + USERNAME=${USERNAME:-admin} + fi + + case "$USERNAME" in + *[!a-zA-Z0-9_.-]*) + printf 'Username may only contain letters, digits, dot, underscore, and hyphen.\n' >&2 + exit 1 + ;; + esac + + if [ -z "$DISPLAY_NAME" ]; then + printf 'Display name [%s]: ' "$USERNAME" + read -r DISPLAY_NAME + DISPLAY_NAME=${DISPLAY_NAME:-$USERNAME} + fi + + if [ -z "$EMAIL" ]; then + printf 'Email [%s@%s]: ' "$USERNAME" "$BASE_DOMAIN" + read -r EMAIL + EMAIL=${EMAIL:-$USERNAME@$BASE_DOMAIN} + fi + + case "$DISPLAY_NAME$EMAIL" in + *'"'*|*'\'*) + printf 'Display name and email cannot contain quote or backslash characters.\n' >&2 + exit 1 + ;; + esac + + if [ -z "$PASSWORD" ]; then + if [ ! -t 0 ]; then + printf 'Set AUTHELIA_PASSWORD for non-interactive initialization.\n' >&2 + exit 1 + fi + printf 'Password: ' + stty -echo + read -r PASSWORD + stty echo + printf '\nConfirm password: ' + stty -echo + read -r PASSWORD_CONFIRM + stty echo + printf '\n' + if [ "$PASSWORD" != "$PASSWORD_CONFIRM" ]; then + printf 'Passwords do not match.\n' >&2 + exit 1 + fi + fi + + if [ "${#PASSWORD}" -lt 12 ]; then + printf 'Password must contain at least 12 characters.\n' >&2 + exit 1 + fi + + HASH_OUTPUT=$(docker run --rm authelia/authelia:4.39.20 \ + authelia crypto hash generate argon2 \ + --password "$PASSWORD" \ + --no-confirm) + PASSWORD_HASH=${HASH_OUTPUT#Digest: } + unset PASSWORD PASSWORD_CONFIRM HASH_OUTPUT + + escape_sed() { + printf '%s' "$1" | sed 's/[|&]/\\&/g' + } + + USERNAME_ESCAPED=$(escape_sed "$USERNAME") + DISPLAY_NAME_ESCAPED=$(escape_sed "$DISPLAY_NAME") + EMAIL_ESCAPED=$(escape_sed "$EMAIL") + PASSWORD_HASH_ESCAPED=$(escape_sed "$PASSWORD_HASH") + + sed \ + -e "s|__USERNAME__|$USERNAME_ESCAPED|g" \ + -e "s|__DISPLAY_NAME__|$DISPLAY_NAME_ESCAPED|g" \ + -e "s|__EMAIL__|$EMAIL_ESCAPED|g" \ + -e "s|__PASSWORD_HASH__|$PASSWORD_HASH_ESCAPED|g" \ + "$PROJECT_DIR/docker/authelia/users_database.template.yml" \ + > "$USERS_FILE" + chmod 600 "$USERS_FILE" + printf 'Created Authelia user %s\n' "$USERNAME" +fi + +docker compose --project-directory "$PROJECT_DIR" config --quiet + +printf '\nInitialization complete.\n' +printf 'Add wiki.%s, dav.%s, and auth.%s to local DNS, then run:\n' \ + "$BASE_DOMAIN" "$BASE_DOMAIN" "$BASE_DOMAIN" +printf ' docker compose up -d --build\n' |
