chore: initialize dockerized wordpress stack
This commit is contained in:
26
.gitignore
vendored
Normal file
26
.gitignore
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# Environment files
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
*.env
|
||||||
|
|
||||||
|
# Local docker data volumes
|
||||||
|
/db_data/
|
||||||
|
/wordpress_data/
|
||||||
|
/wordpress_data/wp-config.php
|
||||||
|
/redis_data/
|
||||||
|
|
||||||
|
# WordPress exports / backups
|
||||||
|
*.sql
|
||||||
|
*.tar
|
||||||
|
*.tar.gz
|
||||||
|
*.tgz
|
||||||
|
*.zip
|
||||||
|
|
||||||
|
# Editor / OS cruft
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
# Log files
|
||||||
|
*.log
|
||||||
48
README.md
Normal file
48
README.md
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# DigitechFlow WordPress Stack
|
||||||
|
|
||||||
|
This repository contains a hardened Docker Compose stack for the DigitechFlow WordPress deployment. It runs MySQL, WordPress (PHP-FPM), Nginx, and Valkey (Redis-compatible cache) with sensible defaults.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
- Docker Engine + Docker Compose V2
|
||||||
|
- Traefik network (`traefik_default`) already present for routing/SSL
|
||||||
|
- Host directories writable for `db_data/`, `wordpress_data/`, and `redis_data/`
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
1. Copy the environment template and fill in secrets:
|
||||||
|
```bash
|
||||||
|
cp .env.example .env
|
||||||
|
# Edit .env to use strong unique values (DB creds, salts)
|
||||||
|
```
|
||||||
|
2. Bring up the stack:
|
||||||
|
```bash
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
3. Access WordPress via the configured Traefik domain (e.g., https://digitechflow.com).
|
||||||
|
|
||||||
|
## Services
|
||||||
|
- **db**: `mysql:latest` with persistent volume `db_data/`.
|
||||||
|
- **wordpress**: `wordpress:php8.3-fpm` serving PHP over FastCGI.
|
||||||
|
- **wordpress_nginx**: `nginx:latest` front-end with custom config tuned for Traefik and FastCGI.
|
||||||
|
- **redis**: `valkey/valkey:latest` for object caching with persistence and healthcheck.
|
||||||
|
|
||||||
|
## Configuration Highlights
|
||||||
|
- Secrets and database settings sourced from `.env`; the template (`.env.example`) documents required keys.
|
||||||
|
- `config/nginx/default.conf` contains gzip, caching, and FastCGI tuning. Adjust if you need custom routes.
|
||||||
|
- `wordpress.ini` sets PHP limits and Opcache recommendations.
|
||||||
|
- Local data directories (`db_data/`, `wordpress_data/`, `redis_data/`) plus `wp-config.php` are gitignored to prevent leaking content/secrets.
|
||||||
|
|
||||||
|
## Operations
|
||||||
|
- Update images: `docker compose pull && docker compose up -d`.
|
||||||
|
- View logs: `docker compose logs -f <service>`.
|
||||||
|
- Run WordPress CLI tasks: `docker compose exec wordpress wp <command>` (install WP-CLI first if needed).
|
||||||
|
|
||||||
|
## Security Notes
|
||||||
|
- Always use unique, strong passwords in `.env` and rotate them periodically.
|
||||||
|
- Regenerate WordPress auth salts via https://api.wordpress.org/secret-key/1.1/salt/ and store them in `.env`.
|
||||||
|
- Ensure Traefik enforces HTTPS and apply rate limiting/WAF middleware as needed.
|
||||||
|
- Schedule backups (database dumps + `wordpress_data`) off-host; the stack does not include automated backups by default.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
- Bad gateway from Nginx usually means PHP-FPM isn’t reachable; check `docker compose logs wordpress wordpress_nginx`.
|
||||||
|
- If Compose warns about `version: '3'`, you can remove that line—it’s optional with Compose V2.
|
||||||
|
- Ensure the Traefik network exists: `docker network ls | grep traefik_default`.
|
||||||
49
config/nginx/default.conf
Normal file
49
config/nginx/default.conf
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
root /var/www/html;
|
||||||
|
index index.php index.html;
|
||||||
|
|
||||||
|
# Trust real client IPs forwarded by Traefik
|
||||||
|
set_real_ip_from 172.19.0.0/16;
|
||||||
|
set_real_ip_from 172.21.0.0/16;
|
||||||
|
real_ip_header X-Forwarded-For;
|
||||||
|
real_ip_recursive on;
|
||||||
|
|
||||||
|
# Basic compression for text assets
|
||||||
|
gzip on;
|
||||||
|
gzip_types text/plain text/css application/json application/javascript application/xml+rss image/svg+xml;
|
||||||
|
gzip_comp_level 5;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.php?$args;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ \.php$ {
|
||||||
|
include fastcgi_params;
|
||||||
|
fastcgi_pass wordpress:9000;
|
||||||
|
fastcgi_index index.php;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||||
|
fastcgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for;
|
||||||
|
fastcgi_param HTTP_X_FORWARDED_PROTO $http_x_forwarded_proto;
|
||||||
|
fastcgi_param HTTPS $http_x_forwarded_proto;
|
||||||
|
fastcgi_buffers 16 16k;
|
||||||
|
fastcgi_buffer_size 32k;
|
||||||
|
fastcgi_read_timeout 120s;
|
||||||
|
fastcgi_send_timeout 120s;
|
||||||
|
fastcgi_connect_timeout 60s;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~* \.(?:css|js|jpg|jpeg|gif|png|svg|ico|webp|avif)$ {
|
||||||
|
expires 30d;
|
||||||
|
add_header Cache-Control "public, no-transform";
|
||||||
|
access_log off;
|
||||||
|
try_files $uri =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
client_max_body_size 64m;
|
||||||
|
sendfile on;
|
||||||
|
keepalive_timeout 65;
|
||||||
|
}
|
||||||
12
config/redis.conf
Normal file
12
config/redis.conf
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# Persistent Valkey configuration tuned for WordPress object cache.
|
||||||
|
appendonly yes
|
||||||
|
appendfsync everysec
|
||||||
|
save 900 1
|
||||||
|
save 300 10
|
||||||
|
save 60 10000
|
||||||
|
maxmemory 256mb
|
||||||
|
maxmemory-policy allkeys-lru
|
||||||
|
protected-mode no
|
||||||
|
bind 0.0.0.0
|
||||||
|
port 6379
|
||||||
|
dir /data
|
||||||
99
docker-compose.yaml
Normal file
99
docker-compose.yaml
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
services:
|
||||||
|
# MySQL Service
|
||||||
|
db:
|
||||||
|
image: mysql:latest
|
||||||
|
container_name: digitechflow_db
|
||||||
|
volumes:
|
||||||
|
- ./db_data:/var/lib/mysql
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
|
||||||
|
MYSQL_DATABASE: ${MYSQL_DATABASE}
|
||||||
|
MYSQL_USER: ${MYSQL_USER}
|
||||||
|
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
|
||||||
|
networks:
|
||||||
|
- wordpress_network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
|
||||||
|
# WordPress PHP-FPM Service
|
||||||
|
wordpress:
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
image: wordpress:php8.3-fpm
|
||||||
|
container_name: digitechflow_wordpress
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- ./wordpress_data:/var/www/html
|
||||||
|
- ./wordpress.ini:/usr/local/etc/php/conf.d/wordpress.ini
|
||||||
|
expose:
|
||||||
|
- "9000"
|
||||||
|
environment:
|
||||||
|
WORDPRESS_DB_HOST: ${WORDPRESS_DB_HOST}
|
||||||
|
WORDPRESS_DB_USER: ${WORDPRESS_DB_USER}
|
||||||
|
WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD}
|
||||||
|
WORDPRESS_DB_NAME: ${WORDPRESS_DB_NAME}
|
||||||
|
WORDPRESS_REDIS_HOST: ${WORDPRESS_REDIS_HOST}
|
||||||
|
networks:
|
||||||
|
- wordpress_network
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway" # For crowdsec plugin to connect to host crowdsec api
|
||||||
|
# Nginx front-end for WordPress (Traefik faces this container)
|
||||||
|
wordpress_nginx:
|
||||||
|
depends_on:
|
||||||
|
wordpress:
|
||||||
|
condition: service_started
|
||||||
|
image: nginx:latest
|
||||||
|
container_name: digitechflow_nginx
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- ./wordpress_data:/var/www/html:ro
|
||||||
|
- ./config/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
|
||||||
|
networks:
|
||||||
|
- wordpress_network
|
||||||
|
- traefik_default
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.digitechflow.rule=Host(`digitechflow.com`)"
|
||||||
|
- "traefik.http.routers.digitechflow.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.digitechflow.middlewares=crowdsec@file,retry-fast@file"
|
||||||
|
- "traefik.http.routers.digitechflow.tls.certresolver=letsencrypt"
|
||||||
|
- "traefik.http.services.digitechflow.loadbalancer.server.port=80"
|
||||||
|
- "traefik.http.services.digitechflow.loadbalancer.serversTransport=fast-upstreams@file"
|
||||||
|
- "traefik.docker.network=traefik_default"
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: valkey/valkey:latest
|
||||||
|
container_name: digitechflow_valkey
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- ./redis_data:/data
|
||||||
|
- ./config/redis.conf:/usr/local/etc/redis/redis.conf:ro
|
||||||
|
command: ["valkey-server", "/usr/local/etc/redis/redis.conf"]
|
||||||
|
networks:
|
||||||
|
- wordpress_network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
# Volumes for persistent data
|
||||||
|
volumes:
|
||||||
|
db_data:
|
||||||
|
wordpress_data:
|
||||||
|
redis_data:
|
||||||
|
|
||||||
|
# Network for communication between services
|
||||||
|
networks:
|
||||||
|
wordpress_network:
|
||||||
|
driver: bridge
|
||||||
|
ipam:
|
||||||
|
config:
|
||||||
|
- subnet: 172.21.0.0/16
|
||||||
|
gateway: 172.21.0.1
|
||||||
|
traefik_default:
|
||||||
|
external: true # Assumes Traefik uses an existing network
|
||||||
12
wordpress.ini
Normal file
12
wordpress.ini
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
file_uploads = On
|
||||||
|
memory_limit = 512M
|
||||||
|
upload_max_filesize = 64M
|
||||||
|
post_max_size = 64M
|
||||||
|
max_execution_time = 300
|
||||||
|
max_input_time = 1000
|
||||||
|
; Opcache tuning for better PHP-FPM performance
|
||||||
|
opcache.enable=1
|
||||||
|
opcache.memory_consumption=192
|
||||||
|
opcache.interned_strings_buffer=16
|
||||||
|
opcache.max_accelerated_files=10000
|
||||||
|
opcache.validate_timestamps=0
|
||||||
Reference in New Issue
Block a user