π Original Reference: Originally published with full volume mapping specs and storage pool benchmarks at alexmaina.dev/wordpress-su-nas.
Many developers who spin up WordPress on a home or small-business NAS (QNAP Container Station, Synology Container Manager, or Proxmox) face painful TTFB (Time to First Byte) latency of 2 to 5 seconds. Pages feel sluggish, and admin dashboards grind to a halt.
The root cause is rarely the CPU: it is almost always disk I/O bottlenecks on consumer NAS drives combined with default MySQL settings that write every single transient query to spinning mechanical disks.
Here is the tuned, production-ready docker-compose.yml stack with MariaDB performance tweaks and Redis in-memory object caching that brings response times under 200ms on local hardware.
1. The High-Performance Docker Compose Stack
Create a directory on your NAS fast storage volume (preferably an SSD pool or NVMe cache tier):
mkdir -p /share/Container/wordpress-stack && cd /share/Container/wordpress-stack
nano docker-compose.yml
Paste the following optimized stack:
version: '3.8'
services:
db:
image: mariadb:10.11-jammy
container_name: wp_mariadb
restart: always
environment:
MYSQL_ROOT_PASSWORD: YourSuperSecureRootPassword_123!
MYSQL_DATABASE: wordpress
MYSQL_USER: wp_user
MYSQL_PASSWORD: YourSuperSecureUserPassword_123!
volumes:
- ./mariadb_data:/var/lib/mysql
- ./mariadb_conf/my.cnf:/etc/mysql/conf.d/my.cnf:ro
networks:
- wp_internal
redis:
image: redis:7-alpine
container_name: wp_redis
restart: always
command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru
networks:
- wp_internal
wordpress:
image: wordpress:php8.3-fpm-alpine
container_name: wp_core
restart: always
depends_on:
- db
- redis
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: wp_user
WORDPRESS_DB_PASSWORD: YourSuperSecureUserPassword_123!
WORDPRESS_CONFIG_EXTRA: |
define('WP_REDIS_HOST', 'redis');
define('WP_REDIS_PORT', 6379);
define('WP_REDIS_TIMEOUT', 1);
define('WP_REDIS_READ_TIMEOUT', 1);
define('WP_CACHE', true);
volumes:
- ./wp_data:/var/www/html
networks:
- wp_internal
- web_proxy
networks:
wp_internal:
internal: true
web_proxy:
external: true
2. Tuning MariaDB: Stop Killing Your Disk I/O
Default MariaDB installations allocate only 128MB to the InnoDB buffer pool. On a NAS, this forces MariaDB to constantly read and write table indices directly to slow SATA hard drives.
Create ./mariadb_conf/my.cnf:
[mysqld]
# Allocate 50-70% of available RAM allocated to this container
innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
# Connection and query cache settings
max_connections = 100
query_cache_type = 0
query_cache_size = 0
# Prevent slow reverse DNS lookups on internal container network
skip-name-resolve
β‘ The Secret Sauce:
innodb_flush_log_at_trx_commit = 2writes log buffers to disk once per second instead of on every single transaction commit. This reduces disk write IOPS by over 80% while remaining completely safe against OS crashes.
3. Enable Redis Object Caching
Instead of querying MariaDB for post metadata, taxonomy terms, and options on every page load, Redis stores the parsed PHP objects in RAM:
- Log into your WordPress admin dashboard (
/wp-admin). - Go to Plugins β Add New and search for Redis Object Cache by Till KrΓΌss.
- Click Install β Activate.
- Go to Settings β Redis and click Enable Object Cache.
- You should see
Status: Connectedwith zero configuration needed (since we already injected the constants viaWORDPRESS_CONFIG_EXTRA).
Your database queries will drop from 60-120 per page down to 2-4 queries.
4. Automated Daily Backup Script
Never rely solely on NAS snapshots. Run a cron job that creates a clean SQL dump and compresses wp-content:
#!/bin/bash
BACKUP_DIR="/share/Backup/wordpress"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p "$BACKUP_DIR"
# Dump database without locking tables
docker exec wp_mariadb mariadb-dump -u wp_user -pYourSuperSecureUserPassword_123! --single-transaction wordpress | gzip > "$BACKUP_DIR/wp_db_$DATE.sql.gz"
# Keep last 7 days of backups
find "$BACKUP_DIR" -type f -name "*.sql.gz" -mtime +7 -delete
Conclusion
Running WordPress on a NAS doesn't have to be slow. By using a lightweight Alpine-based FPM container, tuning MariaDB's InnoDB buffer pool to keep queries in memory, and offloading repetitive lookups to Redis, you get cloud-grade performance right from your local hardware.
Author: Alessandro Mainardi β Software Developer & Systems Architect. Read the complete self-hosting and containerization guides at alexmaina.dev/wordpress-su-nas.
Top comments (0)