#!/bin/bash set -eo pipefail MARKER_COMPLETE="/var/www/html/.websitebox-setup-complete" MARKER_PARTIAL="/var/www/html/.websitebox-setup-partial" # Run the default WordPress docker-entrypoint.sh first # This sets up wp-config.php, copies WordPress files, then execs php-fpm docker-entrypoint.sh php-fpm & WP_PID=$! # Forward signals to PHP-FPM for graceful shutdown trap 'kill -TERM $WP_PID; wait $WP_PID; exit $?' TERM INT # Wait for WordPress files AND wp-config.php to be available echo "WebsiteBox: Waiting for WordPress files..." for i in $(seq 1 60); do if [ -f /var/www/html/wp-includes/version.php ] && [ -f /var/www/html/wp-config.php ]; then echo "WebsiteBox: WordPress files ready." break fi if [ "$i" -eq 60 ]; then echo "ERROR: WordPress files did not appear after 120 seconds." exit 1 fi sleep 2 done # Copy mu-plugins into place mkdir -p /var/www/html/wp-content/mu-plugins cp -f /usr/src/websitebox-mu-plugins/*.php /var/www/html/wp-content/mu-plugins/ 2>/dev/null || true chown -R www-data:www-data /var/www/html/wp-content/mu-plugins/ # Check if setup is already complete if [ -f "${MARKER_COMPLETE}" ]; then echo "WebsiteBox: Setup already complete. Starting normally." wait $WP_PID exit $? fi echo "WebsiteBox: Running first-boot setup..." # If partial marker exists, we're retrying if [ -f "${MARKER_PARTIAL}" ]; then echo "WebsiteBox: Previous setup was partial. Re-running setup idempotently..." fi # Wait for MariaDB to be ready echo "WebsiteBox: Waiting for database..." DB_READY=false for i in $(seq 1 30); do if su -s /bin/sh -c 'wp db check --path=/var/www/html 2>/dev/null' www-data; then DB_READY=true echo "WebsiteBox: Database is ready." break fi echo "WebsiteBox: Database not ready, attempt ${i}/30..." sleep 2 done if [ "${DB_READY}" != "true" ]; then echo "ERROR: WebsiteBox could not connect to database after 30 attempts." echo "Check that the db container is running: docker compose ps db" exit 1 fi # Track if any step fails SETUP_FAILED=false # Install WordPress core if not already installed # Using env vars directly (inherited by su without -l) avoids shell quoting issues echo "WebsiteBox: Installing WordPress core..." if ! su -s /bin/sh -c 'wp core is-installed --path=/var/www/html 2>/dev/null' www-data; then # shellcheck disable=SC2016 # Single quotes intentional: inner shell (via su) expands env vars if ! su -s /bin/sh www-data -c 'wp core install \ --path=/var/www/html \ --url="https://${DOMAIN}" \ --title="${SITE_TITLE:-My Portfolio}" \ --admin_user="${ADMIN_USER}" \ --admin_password="${ADMIN_PASSWORD}" \ --admin_email="${ADMIN_EMAIL}" \ --skip-email'; then echo "ERROR: WordPress core install failed." SETUP_FAILED=true fi else echo "WebsiteBox: WordPress core already installed." fi # Install and activate GeneratePress theme if [ "${SETUP_FAILED}" != "true" ]; then echo "WebsiteBox: Installing GeneratePress theme..." su -s /bin/sh -c 'wp theme install generatepress --path=/var/www/html 2>/dev/null' www-data || true fi # Copy and activate child theme echo "WebsiteBox: Installing WebsiteBox child theme..." cp -r /usr/src/websitebox-theme/ /var/www/html/wp-content/themes/websitebox/ chown -R www-data:www-data /var/www/html/wp-content/themes/websitebox/ if [ "${SETUP_FAILED}" != "true" ]; then su -s /bin/sh -c 'wp theme activate websitebox --path=/var/www/html' www-data || { echo "WARNING: Could not activate child theme. Activating GeneratePress instead." su -s /bin/sh -c 'wp theme activate generatepress --path=/var/www/html' www-data || true } fi # Install and activate plugins if [ "${SETUP_FAILED}" != "true" ]; then echo "WebsiteBox: Installing plugins..." for plugin in age-gate wordfence updraftplus; do echo "WebsiteBox: Installing ${plugin}..." if ! su -s /bin/sh -c "wp plugin install ${plugin} --activate --path=/var/www/html 2>/dev/null" www-data; then echo "WARNING: Failed to install ${plugin}. Will continue with remaining setup." SETUP_FAILED=true fi done fi # Configure WordPress settings if [ "${SETUP_FAILED}" != "true" ]; then echo "WebsiteBox: Configuring WordPress settings..." # Set permalink structure su -s /bin/sh -c "wp rewrite structure '/%postname%/' --path=/var/www/html" www-data || true # Delete default content su -s /bin/sh -c 'wp post delete 1 --force --path=/var/www/html 2>/dev/null' www-data || true su -s /bin/sh -c 'wp post delete 2 --force --path=/var/www/html 2>/dev/null' www-data || true # Set timezone su -s /bin/sh -c "wp option update timezone_string 'UTC' --path=/var/www/html" www-data || true # Discourage search engines until user is ready su -s /bin/sh -c "wp option update blog_public 0 --path=/var/www/html" www-data || true fi # Configure Age Gate if [ "${SETUP_FAILED}" != "true" ] && [ "${AGE_GATE_ENABLED}" = "true" ]; then echo "WebsiteBox: Configuring Age Gate..." # shellcheck disable=SC2016 su -s /bin/sh -c 'wp option update age_gate_min_age "${AGE_GATE_MIN_AGE:-18}" --path=/var/www/html' www-data || true su -s /bin/sh -c 'wp option update age_gate_restrict_all "1" --path=/var/www/html' www-data || true fi # Disable Age Gate if not enabled if [ "${AGE_GATE_ENABLED}" != "true" ]; then echo "WebsiteBox: Age Gate disabled. Deactivating plugin..." su -s /bin/sh -c 'wp plugin deactivate age-gate --path=/var/www/html 2>/dev/null' www-data || true fi # Configure UpdraftPlus backup path echo "WebsiteBox: Configuring UpdraftPlus backup path..." su -s /bin/sh -c "wp option update updraft_dir '/var/backups/websitebox' --path=/var/www/html" www-data || true # Set backup retention RETENTION="${BACKUP_RETENTION_DAYS:-30}" DB_RETAIN=$((RETENTION > 30 ? 30 : RETENTION)) FILE_RETAIN=$((RETENTION / 7)) [ "${FILE_RETAIN}" -lt 1 ] && FILE_RETAIN=1 su -s /bin/sh -c "wp option update updraft_retain '${FILE_RETAIN}' --path=/var/www/html" www-data || true su -s /bin/sh -c "wp option update updraft_retain_db '${DB_RETAIN}' --path=/var/www/html" www-data || true # Create marker file if [ "${SETUP_FAILED}" = "true" ]; then touch "${MARKER_PARTIAL}" chown www-data:www-data "${MARKER_PARTIAL}" echo "WARNING: WebsiteBox setup completed with errors." echo "Some plugins/themes may not have installed correctly." echo "To retry: docker compose restart wordpress" else rm -f "${MARKER_PARTIAL}" touch "${MARKER_COMPLETE}" chown www-data:www-data "${MARKER_COMPLETE}" echo "WebsiteBox: First-run setup complete!" fi # Wait for the background PHP-FPM process wait $WP_PID