#!/usr/bin/env bash set -Eeuo pipefail CONTAINER="nextcloud" OVERRIDE="/var/www/html/config/zz-docker-env.config.php" FIX=false if [[ "${1:-}" == "--fix" ]]; then FIX=true fi PASS=0 FAIL=0 pass() { echo "PASS: $1" PASS=$((PASS + 1)) } fail() { echo "FAIL: $1" FAIL=$((FAIL + 1)) } # ============================================================ # Basic checks # ============================================================ echo "==========================================" echo " Nextcloud Docker configuration checker" echo "==========================================" echo if ! docker inspect "$CONTAINER" >/dev/null 2>&1; then echo "FAIL: Docker container '$CONTAINER' does not exist" exit 1 fi if [[ "$(docker inspect -f '{{.State.Running}}' "$CONTAINER")" != "true" ]]; then echo "FAIL: Docker container '$CONTAINER' is not running" exit 1 fi if [[ ! -f ".env" ]]; then echo "FAIL: .env not found" exit 1 fi # ============================================================ # Read .env # ============================================================ declare -A ENV while IFS='=' read -r key value; do key="${key//$'\r'/}" value="${value//$'\r'/}" # Ignore empty lines [[ -z "${key// /}" ]] && continue # Ignore comments [[ "$key" =~ ^[[:space:]]*# ]] && continue # Trim whitespace key="${key#"${key%%[![:space:]]*}"}" key="${key%"${key##*[![:space:]]}"}" # Remove "export " key="${key#export }" # Remove quotes value="${value#\"}" value="${value%\"}" value="${value#\'}" value="${value%\'}" ENV["$key"]="$value" done < .env MYSQL_PASSWORD="${ENV[MYSQL_PASSWORD]:-}" MYSQL_ROOT_PASSWORD="${ENV[MYSQL_ROOT_PASSWORD]:-}" REDIS_PASSWORD="${ENV[REDIS_PASSWORD]:-}" NEXTCLOUD_ADMIN_USER="${ENV[NEXTCLOUD_ADMIN_USER]:-}" NEXTCLOUD_ADMIN_PASSWORD="${ENV[NEXTCLOUD_ADMIN_PASSWORD]:-}" NEXTCLOUD_DOMAIN="${ENV[NEXTCLOUD_DOMAIN]:-}" # ============================================================ # Environment checks # ============================================================ echo "Checking .env variables" echo "-----------------------" for name in \ MYSQL_PASSWORD \ MYSQL_ROOT_PASSWORD \ REDIS_PASSWORD \ NEXTCLOUD_ADMIN_USER \ NEXTCLOUD_ADMIN_PASSWORD \ NEXTCLOUD_DOMAIN do if [[ -n "${ENV[$name]:-}" ]]; then pass "$name is defined" else fail "$name is missing" fi done echo # ============================================================ # Read config.php # # PHP runs ONLY inside Docker. # No PHP is required on the host. # ============================================================ CONFIG_JSON="$( docker exec "$CONTAINER" php -r ' $CONFIG = []; include "/var/www/html/config/config.php"; echo json_encode([ "dbhost" => $CONFIG["dbhost"] ?? "", "dbname" => $CONFIG["dbname"] ?? "", "dbuser" => $CONFIG["dbuser"] ?? "", "dbpassword" => $CONFIG["dbpassword"] ?? "", "redis_host" => $CONFIG["redis"]["host"] ?? "", "redis_password" => $CONFIG["redis"]["password"] ?? "", "overwriteprotocol" => $CONFIG["overwriteprotocol"] ?? "", "overwrite_cli_url" => $CONFIG["overwrite.cli.url"] ?? "", "trusted_domains" => $CONFIG["trusted_domains"] ?? [], "trusted_proxies" => $CONFIG["trusted_proxies"] ?? [] ]); ' )" # ============================================================ # Extract configuration # ============================================================ DB_HOST="$(jq -r '.dbhost' <<< "$CONFIG_JSON")" DB_NAME="$(jq -r '.dbname' <<< "$CONFIG_JSON")" DB_USER="$(jq -r '.dbuser' <<< "$CONFIG_JSON")" DB_PASSWORD="$(jq -r '.dbpassword' <<< "$CONFIG_JSON")" REDIS_HOST="$(jq -r '.redis_host' <<< "$CONFIG_JSON")" REDIS_PASSWORD_CONFIG="$(jq -r '.redis_password' <<< "$CONFIG_JSON")" OVERWRITE_PROTOCOL="$(jq -r '.overwriteprotocol' <<< "$CONFIG_JSON")" OVERWRITE_CLI_URL="$(jq -r '.overwrite_cli_url' <<< "$CONFIG_JSON")" # ============================================================ # Database # ============================================================ echo "Checking database configuration" echo "-------------------------------" if [[ "$DB_HOST" == "mariadb" ]]; then pass "dbhost = mariadb" else fail "dbhost: expected mariadb, got $DB_HOST" fi if [[ "$DB_NAME" == "nextcloud" ]]; then pass "dbname = nextcloud" else fail "dbname: expected nextcloud, got $DB_NAME" fi if [[ "$DB_USER" == "nextcloud" ]]; then pass "dbuser = nextcloud" else fail "dbuser: expected nextcloud, got $DB_USER" fi if [[ "$MYSQL_PASSWORD" == "$DB_PASSWORD" ]]; then pass "dbpassword" else fail "dbpassword" fi echo # ============================================================ # Redis # ============================================================ echo "Checking Redis configuration" echo "----------------------------" if [[ "$REDIS_HOST" == "redis" ]]; then pass "redis host = redis" else fail "redis host: expected redis, got $REDIS_HOST" fi if [[ "$REDIS_PASSWORD" == "$REDIS_PASSWORD_CONFIG" ]]; then pass "redis password" else fail "redis password" echo " expected: [hidden]" echo " actual: [hidden]" fi echo # ============================================================ # URL # ============================================================ echo "Checking Nextcloud URL configuration" echo "------------------------------------" if [[ "$OVERWRITE_PROTOCOL" == "https" ]]; then pass "overwriteprotocol = https" else fail "overwriteprotocol: expected https, got $OVERWRITE_PROTOCOL" fi EXPECTED_URL="https://${NEXTCLOUD_DOMAIN}" if [[ "$OVERWRITE_CLI_URL" == "$EXPECTED_URL" ]]; then pass "overwrite.cli.url = $EXPECTED_URL" else fail "overwrite.cli.url" echo " expected: $EXPECTED_URL" echo " actual: $OVERWRITE_CLI_URL" fi echo # ============================================================ # Trusted domains # ============================================================ echo "Checking trusted domains" echo "-----------------------" if jq -e \ --arg domain "$NEXTCLOUD_DOMAIN" \ '.trusted_domains | index($domain) != null' \ <<< "$CONFIG_JSON" >/dev/null then pass "trusted_domains contains $NEXTCLOUD_DOMAIN" else fail "trusted_domains does not contain $NEXTCLOUD_DOMAIN" fi echo # ============================================================ # Trusted proxies # ============================================================ echo "Checking trusted proxies" echo "------------------------" if jq -e \ '.trusted_proxies | index("172.16.0.0/12") != null' \ <<< "$CONFIG_JSON" >/dev/null then pass "trusted_proxies contains 172.16.0.0/12" else fail "trusted_proxies does not contain 172.16.0.0/12" fi echo # ============================================================ # FIX # ============================================================ if [[ "$FIX" == true ]]; then echo "==========================================" echo " Fixing Nextcloud configuration" echo "==========================================" echo # -------------------------------------------------------- # Backup existing override # -------------------------------------------------------- if docker exec "$CONTAINER" test -f "$OVERRIDE"; then BACKUP="/var/www/html/config/zz-docker-env.config.php.backup.$(date +%Y%m%d-%H%M%S)" docker exec "$CONTAINER" \ cp "$OVERRIDE" "$BACKUP" echo "Backup created:" echo " $BACKUP" echo fi # -------------------------------------------------------- # Generate override INSIDE the container. # # Therefore PHP is NOT required on the host. # -------------------------------------------------------- docker exec \ -e MYSQL_PASSWORD="$MYSQL_PASSWORD" \ -e REDIS_PASSWORD="$REDIS_PASSWORD" \ -e NEXTCLOUD_DOMAIN="$NEXTCLOUD_DOMAIN" \ "$CONTAINER" \ php -r ' $mysql = getenv("MYSQL_PASSWORD"); $redis = getenv("REDIS_PASSWORD"); $domain = getenv("NEXTCLOUD_DOMAIN"); $file = "/var/www/html/config/zz-docker-env.config.php"; $config = " $CONFIG["dbhost"] ?? "", "dbname" => $CONFIG["dbname"] ?? "", "dbuser" => $CONFIG["dbuser"] ?? "", "dbpassword" => $CONFIG["dbpassword"] ?? "", "redis_host" => $CONFIG["redis"]["host"] ?? "", "redis_password" => $CONFIG["redis"]["password"] ?? "", "overwriteprotocol" => $CONFIG["overwriteprotocol"] ?? "", "overwrite_cli_url" => $CONFIG["overwrite.cli.url"] ?? "", "trusted_domains" => $CONFIG["trusted_domains"] ?? [], "trusted_proxies" => $CONFIG["trusted_proxies"] ?? [] ]); ' )" EFFECTIVE_REDIS_PASSWORD="$( jq -r '.redis_password' <<< "$EFFECTIVE_JSON" )" EFFECTIVE_DOMAINS="$( jq -r '.trusted_domains[]?' <<< "$EFFECTIVE_JSON" )" if [[ "$EFFECTIVE_REDIS_PASSWORD" == "$REDIS_PASSWORD" ]]; then pass "Redis password fixed" else fail "Redis password was not fixed" fi if grep -Fxq "$NEXTCLOUD_DOMAIN" <<< "$EFFECTIVE_DOMAINS"; then pass "trusted_domains fixed" else fail "trusted_domains was not fixed" fi echo echo "==========================================" echo " Fix complete" echo "==========================================" exit 0 fi # ============================================================ # Summary # ============================================================ echo "==========================================" echo "Result" echo "==========================================" echo "PASS: $PASS" echo "FAIL: $FAIL" if [[ "$FAIL" -eq 0 ]]; then echo echo "PASS: configuration is consistent." exit 0 else echo echo "FAIL: configuration has mismatches." echo echo "Run:" echo echo " $0 --fix" echo exit 1 fi