Production Environment

Host multiple WordPress sites on a single low-cost server with auto-SSL, hardened PHP, and object caching.

Architecture

Internet → Caddy (auto-SSL) → OpenLiteSpeed (LSPHP) → MariaDB
                                     ↕
                                   Redis (object cache)
Service Image Purpose
Caddy caddy:2-alpine Reverse proxy, automatic Let’s Encrypt SSL
OpenLiteSpeed Ubuntu 24.04 + OLS PHP processing with LSCache
MariaDB mariadb:11.4 Database (internal network only)
Redis redis:7-alpine Object cache (internal network only)

Setup

1. Server requirements

Recommended: AWS Lightsail ARM 1GB ($3.50/mo) or Hetzner CAX11 ($4.10/mo).

2. Install

git clone https://github.com/jmcoimbra/LAMP-env.git
cd LAMP-env
cp .env.example .env

Edit .env:

MARIADB_ROOT_PASSWORD=<generate-a-strong-password>
ACME_EMAIL=you@example.com
PHP_VERSION=8.3

Start the stack:

docker compose -f docker-compose.prod.yml up -d

3. Add a WordPress site

./scripts/add-site.sh yourdomain.com

The script:

  1. Creates a Caddy config with auto-SSL and security headers
  2. Downloads the latest WordPress
  3. Creates a dedicated database and user with a random password
  4. Generates wp-config.php with unique salts and hardening options
  5. Reloads Caddy

Point your DNS A record to the server’s IP. SSL provisions automatically once DNS resolves.

4. Add more sites

Run add-site.sh again for each domain. All sites share the same server resources.

Sites Recommended Instance Monthly Cost Per Site
1-5 1GB ARM ($3.50) ~$4.50 $0.90-$4.50
5-15 2GB ARM ($7) ~$8 $0.53-$1.60
15-30 4GB ARM ($14) ~$15 $0.50-$1.00

Security

The production stack includes these hardening measures out of the box:

Network

SSL / TLS

HTTP headers

Every response includes:

WordPress

PHP

MariaDB

Port Source Protocol
80 0.0.0.0/0 TCP
443 0.0.0.0/0 TCP
22 Your IP only TCP

Block everything else.

Performance

OPcache

Enabled by default in openlitespeed/lsphp.ini:

Install the free LiteSpeed Cache plugin. It’s purpose-built for OpenLiteSpeed and provides page caching, image optimization, and CSS/JS minification.

Redis runs in the stack. Install Redis Object Cache and enable it. Connection settings:

MariaDB tuning

The mariadb/production.cnf file is pre-tuned for 1-4GB RAM instances:

For larger instances, increase innodb_buffer_pool_size to ~50% of available RAM.

Backups

Local backup

./scripts/backup.sh

Backup to S3

./scripts/backup.sh my-s3-bucket-name

Automated daily backup (cron)

0 3 * * * cd /path/to/LAMP-env && ./scripts/backup.sh my-bucket

Backups include all databases, site files, and Caddy configs. Local backups older than 7 days are auto-deleted.

Configuration files

File Purpose
docker-compose.prod.yml Service definitions and networking
openlitespeed/httpd_config.conf OLS server config (listeners, LSAPI, modules)
openlitespeed/vhconf.conf WordPress virtual host (rewrites, security, PHP overrides)
openlitespeed/lsphp.ini PHP settings (limits, security, OPcache)
caddy/Caddyfile Main Caddy config (imports site configs)
caddy/sites/*.caddy Per-site reverse proxy configs
mariadb/production.cnf MariaDB tuning

Post-install checklist

  1. Install LiteSpeed Cache plugin on each site
  2. Install Redis Object Cache plugin and enable
  3. Set up fail2ban on the host for SSH protection
  4. Configure AWS Security Group (ports 80, 443, 22 only)
  5. Set up daily backup cron job
  6. Test backup restore procedure