Two bugs found: 1. wp-config-docker.php was being copied to /usr/src/wordpress/wp-config-docker.php, REPLACING the official WordPress config template. Our file only had security hardening settings (DISALLOW_FILE_EDIT, etc.) but no DB constants, auth keys, or table prefix. The generated wp-config.php had zero database configuration, so WordPress could never connect. Fix: Copy our config to /usr/src/websitebox-config.php instead, and load it via WORDPRESS_CONFIG_EXTRA=require_once in docker-compose.yml. 2. .user.ini set auto_prepend_file=wordfence-waf.php, but the file didn't exist until Wordfence plugin was installed. Every PHP request during initial setup returned a 500 fatal error. Fix: Add a stub wordfence-waf.php placeholder in the Docker image that gets copied with WordPress files. Wordfence replaces it during plugin activation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
106 lines
3.2 KiB
YAML
106 lines
3.2 KiB
YAML
services:
|
|
nginx:
|
|
build:
|
|
context: ./nginx
|
|
container_name: websitebox-nginx
|
|
ports:
|
|
- "80:80"
|
|
- "443:443"
|
|
volumes:
|
|
- ./websitebox-data/certs:/etc/letsencrypt
|
|
- ./websitebox-data/certbot-webroot:/var/www/certbot
|
|
- ./websitebox-data/certbot-signal:/var/run/certbot-signal
|
|
- ./websitebox-data/wordpress:/var/www/html:ro
|
|
environment:
|
|
- DOMAIN=${DOMAIN}
|
|
- ADMIN_EMAIL=${ADMIN_EMAIL}
|
|
depends_on:
|
|
wordpress:
|
|
condition: service_started
|
|
restart: unless-stopped
|
|
networks:
|
|
- websitebox_internal
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost/nginx-health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
|
|
wordpress:
|
|
build:
|
|
context: ./wordpress
|
|
container_name: websitebox-wordpress
|
|
volumes:
|
|
- ./websitebox-data/wordpress:/var/www/html
|
|
- ./websitebox-data/backups:/var/backups/websitebox
|
|
environment:
|
|
- DOMAIN=${DOMAIN}
|
|
- SITE_TITLE=${SITE_TITLE}
|
|
- ADMIN_USER=${ADMIN_USER}
|
|
- ADMIN_EMAIL=${ADMIN_EMAIL}
|
|
- ADMIN_PASSWORD=${ADMIN_PASSWORD}
|
|
- WORDPRESS_DB_HOST=db
|
|
- WORDPRESS_DB_NAME=${DB_NAME}
|
|
- WORDPRESS_DB_USER=${DB_USER}
|
|
- WORDPRESS_DB_PASSWORD=${DB_PASSWORD}
|
|
- WORDPRESS_TABLE_PREFIX=wbox_
|
|
- WORDPRESS_CONFIG_EXTRA=require_once '/usr/src/websitebox-config.php';
|
|
- AGE_GATE_ENABLED=${AGE_GATE_ENABLED}
|
|
- AGE_GATE_MIN_AGE=${AGE_GATE_MIN_AGE}
|
|
- BACKUP_RETENTION_DAYS=${BACKUP_RETENTION_DAYS}
|
|
- WORDPRESS_AUTH_KEY=${AUTH_KEY}
|
|
- WORDPRESS_SECURE_AUTH_KEY=${SECURE_AUTH_KEY}
|
|
- WORDPRESS_LOGGED_IN_KEY=${LOGGED_IN_KEY}
|
|
- WORDPRESS_NONCE_KEY=${NONCE_KEY}
|
|
- WORDPRESS_AUTH_SALT=${AUTH_SALT}
|
|
- WORDPRESS_SECURE_AUTH_SALT=${SECURE_AUTH_SALT}
|
|
- WORDPRESS_LOGGED_IN_SALT=${LOGGED_IN_SALT}
|
|
- WORDPRESS_NONCE_SALT=${NONCE_SALT}
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
restart: unless-stopped
|
|
networks:
|
|
- websitebox_internal
|
|
healthcheck:
|
|
test: ["CMD", "php-fpm-healthcheck"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
|
|
db:
|
|
image: mariadb:11
|
|
container_name: websitebox-db
|
|
volumes:
|
|
- ./websitebox-data/database:/var/lib/mysql
|
|
environment:
|
|
- MARIADB_DATABASE=${DB_NAME}
|
|
- MARIADB_USER=${DB_USER}
|
|
- MARIADB_PASSWORD=${DB_PASSWORD}
|
|
- MARIADB_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
|
|
restart: unless-stopped
|
|
networks:
|
|
- websitebox_internal
|
|
healthcheck:
|
|
test: ["CMD", "mariadb-admin", "ping", "-h", "localhost", "-u", "root", "-p${DB_ROOT_PASSWORD}"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 10
|
|
start_period: 30s
|
|
|
|
certbot:
|
|
image: certbot/certbot
|
|
container_name: websitebox-certbot
|
|
volumes:
|
|
- ./websitebox-data/certs:/etc/letsencrypt
|
|
- ./websitebox-data/certbot-webroot:/var/www/certbot
|
|
- ./websitebox-data/certbot-signal:/var/run/certbot-signal
|
|
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew --deploy-hook \"touch /var/run/certbot-signal/reload\"; sleep 12h & wait $${!}; done;'"
|
|
restart: unless-stopped
|
|
networks:
|
|
- websitebox_internal
|
|
|
|
networks:
|
|
websitebox_internal:
|
|
driver: bridge
|