Modern SME websites increasingly combine content management, eCommerce, digital marketing, customer engagement, analytics and business integration. Joomla and WordPress remain strong CMS platforms, while WooCommerce provides a mature eCommerce layer for WordPress.

A development team should therefore avoid treating each website as an isolated server installation. A better approach is to establish a repeatable Docker-based development, testing, staging and production methodology.

This paper presents such a methodology.

The proposed platform uses:

  • Docker Engine
  • Docker Compose
  • Joomla
  • WordPress
  • WooCommerce
  • PHP-FPM
  • Nginx
  • Varnish
  • Redis
  • MariaDB
  • Git
  • automated testing
  • staging environments
  • VPS deployment
  • backups and disaster recovery
  • security controls
  • performance testing
  • CI/CD

The architecture separates application, web, caching and database services:

INTERNET │ ▼ HTTPS / NGINX │ ▼ VARNISH │ ▼ NGINX │ ▼ PHP-FPM │ ┌────────────┴────────────┐ │ │ REDIS MARIADB │ │ ▼ ▼ Application Cache Persistent Data │ ▼ ┌──────────────────────────────┐ │ Joomla │ │ WordPress │ │ WordPress + WooCommerce │ └──────────────────────────────┘

The objective is not merely to "put Joomla or WordPress into Docker."

The objective is to create a repeatable DevOps platform capable of moving a project safely through:

Development ↓ Testing ↓ Git ↓ Staging ↓ Acceptance ↓ Production VPS ↓ Monitoring ↓ Backup / Recovery

Technical Research & Implementation White Paper

Docker-Based Web Development and Production Platform for Joomla, WordPress, WooCommerce and SME eCommerce

Version: 1.0
Date: August 2026
Audience: SME Owners, CTOs, IT Managers, Digital Transformation Managers, Web Developers, DevOps Engineers and System Administrators

Executive Summary

Modern SME websites increasingly combine content management, eCommerce, digital marketing, customer engagement, analytics and business integration. Joomla and WordPress remain strong CMS platforms, while WooCommerce provides a mature eCommerce layer for WordPress.

A development team should therefore avoid treating each website as an isolated server installation. A better approach is to establish a repeatable Docker-based development, testing, staging and production methodology.

This paper presents such a methodology.

The proposed platform uses:

  • Docker Engine
  • Docker Compose
  • Joomla
  • WordPress
  • WooCommerce
  • PHP-FPM
  • Nginx
  • Varnish
  • Redis
  • MariaDB
  • Git
  • automated testing
  • staging environments
  • VPS deployment
  • backups and disaster recovery
  • security controls
  • performance testing
  • CI/CD

The architecture separates application, web, caching and database services:

INTERNET │ ▼ HTTPS / NGINX │ ▼ VARNISH │ ▼ NGINX │ ▼ PHP-FPM │ ┌────────────┴────────────┐ │ │ REDIS MARIADB │ │ ▼ ▼ Application Cache Persistent Data │ ▼ ┌──────────────────────────────┐ │ Joomla │ │ WordPress │ │ WordPress + WooCommerce │ └──────────────────────────────┘

The objective is not merely to "put Joomla or WordPress into Docker."

The objective is to create a repeatable DevOps platform capable of moving a project safely through:

Development ↓ Testing ↓ Git ↓ Staging ↓ Acceptance ↓ Production VPS ↓ Monitoring ↓ Backup / Recovery

1. Introduction

SMEs increasingly depend on their websites for:

  • lead generation
  • product presentation
  • eCommerce
  • customer communication
  • SEO
  • marketing
  • online ordering
  • customer accounts
  • payments
  • shipping
  • digital transformation

A website failure can therefore become a business failure.

Traditional deployments often look like:

Ubuntu ├── Apache/Nginx ├── PHP ├── MariaDB ├── Redis ├── Joomla └── WordPress

This can work, but it becomes difficult to reproduce and maintain.

A Docker-based architecture instead treats each service as an independently managed component.

2. Business Objectives

The platform should provide:

Development

Developers should be able to create an identical environment quickly.

Testing

Changes should be tested before deployment.

Staging

Production-like testing should occur before release.

Production

The VPS should run a controlled, secure environment.

Recovery

A failed VPS should be recoverable from Git and backups.

Scalability

The architecture should be capable of supporting larger sites later.

3. Platform Scope

This paper covers three application categories.

3.1 Joomla

Suitable for:

  • corporate websites
  • portals
  • content-heavy websites
  • associations
  • government/non-profit sites
  • structured content

3.2 WordPress

Suitable for:

  • SME websites
  • blogs
  • marketing websites
  • landing pages
  • content marketing
  • SEO-driven sites

3.3 WooCommerce

Suitable for:

  • online stores
  • B2C commerce
  • B2B commerce
  • product catalogs
  • subscriptions and extensions
  • order management

The same infrastructure methodology can support all three.

4. Reference Architecture

The reference architecture is:

USERS │ ▼ DNS / DOMAIN │ ▼ HTTPS FRONTEND │ ▼ NGINX │ ▼ VARNISH │ ▼ NGINX │ ▼ PHP-FPM │ ┌───────────────┼────────────────┐ │ │ │ ▼ ▼ ▼ JOOMLA WORDPRESS WOOCOMMERCE │ │ │ └───────────────┼────────────────┘ │ APPLICATION LAYER │ ┌───────────┴───────────┐ ▼ ▼ REDIS MARIADB

5. Why Nginx?

Nginx performs several important functions:

  • HTTP server
  • static file delivery
  • reverse proxy
  • PHP-FPM communication
  • request filtering
  • security headers
  • upload limits
  • connection management

Nginx should not be responsible for application logic.

Its role is:

Request ↓ Nginx ↓ PHP-FPM

6. Why PHP-FPM?

Joomla and WordPress are PHP applications.

PHP-FPM provides a process manager for PHP.

The architecture becomes:

Browser ↓ Nginx ↓ PHP-FPM ↓ CMS

This separates the web server from the PHP execution environment.

7. Why Varnish?

Varnish is an HTTP accelerator.

Without Varnish:

Browser ↓ Nginx ↓ PHP ↓ Database

With Varnish:

Browser ↓ Varnish │ ├── HIT → response │ └── MISS ↓ Nginx ↓ PHP ↓ Database

The objective is to reduce:

  • PHP execution
  • database queries
  • CPU consumption
  • response time

8. Why Redis?

Redis provides an in-memory data store.

It can be used for:

  • object cache
  • application cache
  • sessions
  • temporary state

The architecture becomes:

Application │ ▼ Redis │ └── Cache hit │ ▼ Response

If data isn't available:

Application ↓ Redis MISS ↓ MariaDB ↓ Application ↓ Redis

9. Why MariaDB?

MariaDB provides persistent relational storage.

It stores:

Joomla

  • articles
  • users
  • configuration
  • extensions
  • categories

WordPress

  • posts
  • pages
  • users
  • metadata
  • plugin configuration

WooCommerce

  • products
  • orders
  • customers
  • inventory
  • settings
  • transactional information

The database is therefore a critical production asset.

10. Development Environment

A recommended project structure is:

projects/ │ ├── joomla-docker/ │ ├── wordpress-docker/ │ └── woocommerce-docker/

Each project contains:

compose.yaml compose.prod.yaml .env .env.example docker/ scripts/ tests/ database/

This allows independent lifecycle management.

11. Joomla Docker Environment

11.1 Directory

mkdir -p ~/projects/joomla-docker cd ~/projects/joomla-docker

Create:

mkdir -p \ docker/nginx \ docker/varnish \ docker/php \ scripts \ tests \ database/backups

12. Joomla Environment Variables

.env:

COMPOSE_PROJECT_NAME=joomla JOOMLA_SITE_NAME=Joomla Development JOOMLA_ADMIN_USER=Administrator JOOMLA_ADMIN_USERNAME=admin JOOMLA_ADMIN_PASSWORD=CHANGE_ME JOOMLA_ADMIN_EMAIL=This email address is being protected from spambots. You need JavaScript enabled to view it. DB_NAME=joomla DB_USER=joomla DB_PASSWORD=CHANGE_ME DB_ROOT_PASSWORD=CHANGE_ME TZ=America/Winnipeg

Never commit production credentials to Git.

13. Joomla Docker Compose

compose.yaml:

services: joomla: image: joomla:6.1.2-php8.4-fpm container_name: joomla-dev restart: unless-stopped environment: JOOMLA_DB_HOST: db JOOMLA_DB_USER: ${DB_USER} JOOMLA_DB_PASSWORD: ${DB_PASSWORD} JOOMLA_DB_NAME: ${DB_NAME} JOOMLA_SITE_NAME: ${JOOMLA_SITE_NAME} JOOMLA_ADMIN_USER: ${JOOMLA_ADMIN_USER} JOOMLA_ADMIN_USERNAME: ${JOOMLA_ADMIN_USERNAME} JOOMLA_ADMIN_PASSWORD: ${JOOMLA_ADMIN_PASSWORD} JOOMLA_ADMIN_EMAIL: ${JOOMLA_ADMIN_EMAIL} volumes: - joomla_data:/var/www/html depends_on: db: condition: service_healthy redis: condition: service_healthy networks: - backend nginx: image: nginx:1.29-alpine container_name: joomla-nginx-dev restart: unless-stopped volumes: - joomla_data:/var/www/html:ro - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro depends_on: - joomla networks: - frontend - backend varnish: image: varnish:7.7-alpine container_name: joomla-varnish-dev restart: unless-stopped volumes: - ./docker/varnish/default.vcl:/etc/varnish/default.vcl:ro command: - varnishd - -F - -f - /etc/varnish/default.vcl - -s - malloc,256m ports: - "8080:80" depends_on: - nginx networks: - frontend redis: image: redis:7-alpine container_name: joomla-redis-dev restart: unless-stopped command: - redis-server - --appendonly - "yes" volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 networks: - backend db: image: mariadb:11.4 container_name: joomla-db-dev restart: unless-stopped environment: MARIADB_DATABASE: ${DB_NAME} MARIADB_USER: ${DB_USER} MARIADB_PASSWORD: ${DB_PASSWORD} MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} volumes: - db_data:/var/lib/mysql healthcheck: test: [ "CMD", "healthcheck.sh", "--connect", "--innodb_initialized" ] interval: 10s timeout: 5s retries: 10 networks: - backend phpmyadmin: image: phpmyadmin:latest container_name: joomla-phpmyadmin-dev restart: unless-stopped environment: PMA_HOST: db PMA_PORT: 3306 ports: - "8081:80" depends_on: db: condition: service_healthy networks: - frontend - backend volumes: joomla_data: db_data: redis_data: networks: frontend: driver: bridge backend: driver: bridge internal: true

14. Joomla Nginx

server { listen 80; server_name _; root /var/www/html; index index.php index.html; client_max_body_size 64M; location / { try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { try_files $uri =404; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param HTTP_PROXY ""; fastcgi_pass joomla:9000; } location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|webp)$ { expires 30d; add_header Cache-Control "public"; access_log off; } location ~ /\. { deny all; } }

15. Joomla Varnish

vcl 4.1; backend default { .host = "nginx"; .port = "80"; } sub vcl_recv { if (req.url ~ "^/administrator") { return (pass); } if (req.request != "GET" && req.request != "HEAD") { return (pass); } if (req.http.Cookie ~ "joomla_user_state") { return (pass); } if (req.http.Cookie ~ "joomla_remember_me") { return (pass); } if (req.http.Authorization) { return (pass); } return (hash); } sub vcl_backend_response { if (beresp.status >= 400) { set beresp.ttl = 0s; set beresp.uncacheable = true; return (deliver); } set beresp.ttl = 5m; set beresp.grace = 30m; return (deliver); } sub vcl_deliver { if (obj.hits > 0) { set resp.http.X-Cache = "HIT"; } else { set resp.http.X-Cache = "MISS"; } }

16. WordPress Docker Environment

Create:

mkdir -p ~/projects/wordpress-docker cd ~/projects/wordpress-docker

Create the same basic structure:

wordpress-docker/ ├── compose.yaml ├── compose.prod.yaml ├── .env ├── docker/ ├── scripts/ ├── tests/ └── database/

17. WordPress Environment

COMPOSE_PROJECT_NAME=wordpress WORDPRESS_DB_NAME=wordpress WORDPRESS_DB_USER=wordpress WORDPRESS_DB_PASSWORD=CHANGE_ME WORDPRESS_DB_ROOT_PASSWORD=CHANGE_ME WORDPRESS_TABLE_PREFIX=wp_ WORDPRESS_DEBUG=true TZ=America/Winnipeg

18. WordPress Compose

services: wordpress: image: wordpress:php8.4-fpm restart: unless-stopped environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: ${WORDPRESS_DB_USER} WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD} WORDPRESS_DB_NAME: ${WORDPRESS_DB_NAME} WORDPRESS_TABLE_PREFIX: ${WORDPRESS_TABLE_PREFIX} WORDPRESS_DEBUG: ${WORDPRESS_DEBUG} volumes: - wordpress_data:/var/www/html depends_on: db: condition: service_healthy redis: condition: service_healthy networks: - backend nginx: image: nginx:1.29-alpine restart: unless-stopped volumes: - wordpress_data:/var/www/html:ro - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro depends_on: - wordpress networks: - frontend - backend varnish: image: varnish:7.7-alpine restart: unless-stopped volumes: - ./docker/varnish/default.vcl:/etc/varnish/default.vcl:ro command: - varnishd - -F - -f - /etc/varnish/default.vcl - -s - malloc,256m ports: - "8080:80" depends_on: - nginx networks: - frontend redis: image: redis:7-alpine restart: unless-stopped command: - redis-server - --appendonly - "yes" volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 networks: - backend db: image: mariadb:11.4 restart: unless-stopped environment: MARIADB_DATABASE: ${WORDPRESS_DB_NAME} MARIADB_USER: ${WORDPRESS_DB_USER} MARIADB_PASSWORD: ${WORDPRESS_DB_PASSWORD} MARIADB_ROOT_PASSWORD: ${WORDPRESS_DB_ROOT_PASSWORD} volumes: - db_data:/var/lib/mysql healthcheck: test: [ "CMD", "healthcheck.sh", "--connect", "--innodb_initialized" ] interval: 10s timeout: 5s retries: 10 networks: - backend volumes: wordpress_data: db_data: redis_data: networks: frontend: driver: bridge backend: driver: bridge internal: true

19. WordPress Nginx

server { listen 80; server_name _; root /var/www/html; index index.php index.html; client_max_body_size 128M; location / { try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { try_files $uri =404; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param HTTP_PROXY ""; fastcgi_pass wordpress:9000; } location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|webp)$ { expires 30d; add_header Cache-Control "public"; access_log off; } location ~ /\. { deny all; } }

20. WooCommerce

WooCommerce runs as a WordPress plugin.

Therefore:

WordPress │ └── WooCommerce │ ├── Products ├── Cart ├── Checkout ├── Customers ├── Orders ├── Payments └── Shipping

The development environment must therefore test WordPress and WooCommerce separately.

21. WooCommerce Varnish

This is one of the most important additions.

Never blindly cache:

/cart /checkout /my-account wp-admin wp-login.php

Also bypass:

wc-ajax

and relevant WooCommerce cookies.

Example:

sub vcl_recv { if (req.url ~ "^/wp-admin") { return (pass); } if (req.url ~ "^/wp-login.php") { return (pass); } if (req.url ~ "^/wp-cron.php") { return (pass); } if (req.url ~ "^/cart") { return (pass); } if (req.url ~ "^/checkout") { return (pass); } if (req.url ~ "^/my-account") { return (pass); } if (req.url ~ "wc-ajax") { return (pass); } if (req.request != "GET" && req.request != "HEAD") { return (pass); } if (req.http.Cookie ~ "wordpress_logged_in") { return (pass); } if (req.http.Cookie ~ "woocommerce_items_in_cart") { return (pass); } if (req.http.Cookie ~ "woocommerce_cart_hash") { return (pass); } if (req.http.Cookie ~ "wp_woocommerce_session") { return (pass); } return (hash); }

This configuration must be tested against the actual WooCommerce theme, extensions and payment/shipping plugins used by the site.

22. Redis Architecture for WooCommerce

Use Redis for object/application caching.

WooCommerce │ ▼ Redis │ ├── Cached objects ├── Frequently used data └── Application cache │ ▼ MariaDB

Varnish performs a different job:

Varnish ↓ HTTP response caching

Therefore:

Browser ↓ Varnish ↓ WordPress ↓ Redis ↓ MariaDB

23. WordPress Development Method

Use:

Git │ ├── main │ ├── develop │ └── feature/*

Example:

git checkout develop git checkout -b feature/woocommerce-product-template

Test locally.

Then:

git add . git commit -m "Add WooCommerce product template" git push origin feature/woocommerce-product-template

24. WordPress Theme Development

Do not modify a third-party theme directly.

Use:

Child Theme

or develop a custom theme.

Example:

wp-content/ └── themes/ └── keen-theme/ ├── style.css ├── functions.php ├── templates/ ├── assets/ └── inc/

25. WooCommerce Development Areas

Test:

Catalog

Products Categories Attributes Variations Images Pricing Inventory Coupons

Customers

Registration Login Account Addresses Password reset

Commerce

Cart Checkout Payment Order Refund Email

Operations

Shipping Tax Inventory Order status Customer notification

26. Payment Testing

Use payment-provider sandbox/test environments during development.

Test:

Successful transaction Failed transaction Cancelled transaction Refund Webhook Duplicate webhook Timeout Order status Email notification

Never use live payment credentials during ordinary development.

27. Shipping Testing

Test:

Canada USA International

and:

Free shipping Flat rate Local pickup Weight-based shipping Threshold-based shipping

28. Common Development Test Suite

For Joomla:

[ ] Homepage [ ] Administrator [ ] Login [ ] SEO URLs [ ] Forms [ ] Extensions [ ] Template [ ] Redis [ ] Database [ ] Varnish

For WordPress:

[ ] Homepage [ ] wp-admin [ ] Login [ ] Search [ ] Forms [ ] Theme [ ] Plugins [ ] Redis [ ] Database [ ] Varnish

For WooCommerce:

[ ] Product [ ] Category [ ] Variation [ ] Cart [ ] Checkout [ ] Coupon [ ] Shipping [ ] Tax [ ] Payment sandbox [ ] Order [ ] Refund [ ] Email

29. Common Testing Script

Create:

nano scripts/test.sh #!/usr/bin/env bash set -e echo "====================================" echo " Docker CMS Test Suite" echo "====================================" echo echo "Container status" docker compose ps echo echo "HTTP test" curl \ --fail \ --silent \ --show-error \ http://localhost:8080/ \ > /dev/null echo "HTTP: PASS" echo echo "Redis test" RESULT=$(docker compose exec -T redis redis-cli ping) if [ "$RESULT" = "PONG" ]; then echo "Redis: PASS" else echo "Redis: FAIL" exit 1 fi echo echo "Database test" docker compose exec -T db \ mariadb \ -u"${DB_USER:-${WORDPRESS_DB_USER}}" \ -p"${DB_PASSWORD:-${WORDPRESS_DB_PASSWORD}}" \ "${DB_NAME:-${WORDPRESS_DB_NAME}}" \ -e "SELECT 1;" \ > /dev/null echo "Database: PASS" echo echo "====================================" echo " TESTS PASSED" echo "===================================="

30. Development → Staging → Production

The recommended deployment lifecycle is:

Git Repository │ ▼ DEVELOPMENT │ ▼ Automated Tests │ ▼ STAGING │ ▼ Acceptance Testing │ ▼ PRODUCTION │ ▼ VPS

Never make significant changes directly on production.

31. VPS Production Architecture

Production should expose only:

80/tcp 443/tcp

and SSH should preferably be restricted to trusted administrative access.

Never expose:

3306 6379 9000 phpMyAdmin

publicly.

32. Production Directory

Use:

/opt/sites/ │ ├── client-a-joomla/ │ ├── client-b-wordpress/ │ ├── client-c-woocommerce/ └── client-d-magento/

Each site gets:

Docker Compose Database Redis Volumes Environment Backups Logs

This provides isolation between clients.

33. Production Deployment

On the VPS:

cd /opt/sites/client-c-woocommerce

Pull the latest approved version:

git pull origin main

Then:

docker compose \ -f compose.yaml \ -f compose.prod.yaml \ pull

Start:

docker compose \ -f compose.yaml \ -f compose.prod.yaml \ up -d

Verify:

docker compose ps

34. Production Security

Implement:

SSH keys UFW Fail2ban HTTPS Security headers Strong passwords Secret management Regular updates Image pinning Backups Monitoring

Disable:

Joomla debug WordPress debug PHP display_errors Public phpMyAdmin Public Redis Public MariaDB

35. Backup Strategy

Use the 3-2-1 approach:

3 copies 2 storage types 1 off-site

For a WooCommerce site, backups are particularly important because orders and customer data represent business records.

Backup:

Database Uploaded media Themes Custom plugins/extensions Configuration Deployment configuration

Do not rely on the database alone.

36. Database Backup

For Joomla:

docker compose exec -T db \ mariadb-dump \ -ujoomla \ -p"${DB_PASSWORD}" \ joomla \ | gzip > database/backups/joomla.sql.gz

For WordPress:

docker compose exec -T db \ mariadb-dump \ -u"${WORDPRESS_DB_USER}" \ -p"${WORDPRESS_DB_PASSWORD}" \ "${WORDPRESS_DB_NAME}" \ | gzip > database/backups/wordpress.sql.gz

37. Disaster Recovery

The recovery process should be:

New VPS ↓ Docker ↓ Git repository ↓ Environment configuration ↓ Application volumes ↓ Database backup ↓ Restore ↓ Start containers ↓ DNS ↓ HTTPS ↓ Testing

The ultimate goal is:

A new production server can be reconstructed without depending on undocumented manual configuration.

38. Performance Engineering

Performance should be measured rather than assumed.

Test:

Page response time Time to first byte Requests/second Varnish HIT ratio PHP response time Database queries Redis hit ratio CPU RAM Disk I/O

Tools include:

curl ApacheBench wrk k6 Browser developer tools Docker stats

Example:

wrk -t4 -c20 -d30s https://example.com/

39. Cache Architecture

The complete cache model is:

Browser │ ▼ Browser Cache │ ▼ Varnish │ ▼ Nginx │ ▼ PHP-FPM │ ▼ Redis │ ▼ MariaDB

Each layer has a different purpose.

Layer

Purpose

Browser

Static assets

Varnish

Public HTTP responses

Redis

Application/object cache

MariaDB

Persistent data

40. Critical WooCommerce Cache Rule

WooCommerce introduces a major architectural distinction.

Public product content can often be cached.

But:

Cart Checkout My Account Customer-specific data Payment Order status AJAX

must be treated as dynamic.

Therefore:

Product page ↓ Potentially CACHE Cart ↓ PASS Checkout ↓ PASS My Account ↓ PASS

This distinction should be part of every WooCommerce deployment checklist.

41. CI/CD

A mature platform should eventually implement:

Git Push │ ▼ CI │ ├── YAML validation ├── PHP checks ├── Security scan ├── Docker validation ├── Application tests └── Smoke tests │ ▼ Build │ ▼ Staging │ ▼ Acceptance │ ▼ Production

Production should deploy only from an approved branch or release.

42. Recommended Git Strategy

main │ ├── release/* │ └── develop │ ├── feature/joomla-template ├── feature/wp-theme ├── feature/woocommerce ├── feature/payment ├── feature/shipping └── feature/seo

43. Joomla Development Lifecycle

Requirement ↓ Architecture ↓ Docker Development ↓ Template / Extension ↓ Functional Test ↓ Performance Test ↓ Security Test ↓ Staging ↓ Acceptance ↓ Production

44. WordPress Development Lifecycle

Requirement ↓ Theme/Plugin Design ↓ Docker Development ↓ WordPress Test ↓ Plugin Compatibility ↓ Performance ↓ Security ↓ Staging ↓ Production

45. WooCommerce Development Lifecycle

Product Model ↓ Catalog ↓ Cart ↓ Checkout ↓ Payment Sandbox ↓ Shipping ↓ Tax ↓ Order ↓ Email ↓ Refund ↓ Performance ↓ Security ↓ Staging ↓ Production

46. Production Deployment Checklist

[ ] Git release approved [ ] Database backup completed [ ] Files backed up [ ] Staging tests passed [ ] Payment sandbox tests passed [ ] WooCommerce tests passed [ ] Varnish rules tested [ ] Redis tested [ ] Database tested [ ] HTTPS tested [ ] Firewall checked [ ] Production credentials verified [ ] Debug disabled [ ] Deployment completed [ ] Homepage tested [ ] Admin tested [ ] Checkout tested [ ] Order tested [ ] Email tested [ ] Monitoring enabled

47. Troubleshooting Methodology

Do not restart every container immediately.

Trace the request.

Browser ↓ DNS ↓ HTTPS ↓ Varnish ↓ Nginx ↓ PHP-FPM ↓ Application ↓ Redis ↓ MariaDB

Test each layer independently.

Docker

docker compose ps

Logs

docker compose logs --tail=100

Redis

docker compose exec redis redis-cli ping

Database

docker compose exec db \ mariadb \ -uUSER \ -pPASSWORD \ DATABASE \ -e "SELECT 1;"

HTTP

curl -I http://localhost:8080

Varnish

curl -I http://localhost:8080/

48. Recommended Multi-Platform Standard

For an SME-focused IT company, the infrastructure can become a standardized service:

SME WEB PLATFORM │ ┌────────────────┼─────────────────┐ │ │ │ Joomla WordPress Magento │ │ │ │ WooCommerce │ │ │ │ └────────────────┼─────────────────┘ │ Docker / VPS │ ┌──────────────┼───────────────┐ │ │ │ Nginx Varnish Redis │ │ └──────────────┬───────────────┘ │ MariaDB

This is particularly useful for a managed SME service provider because the operational knowledge becomes reusable across clients.

49. Platform Standardization

The following should be standardized across projects:

Infrastructure

Docker Docker Compose Nginx Redis MariaDB Git

Development

Feature branches Environment variables Automated testing Local Docker Code review

Deployment

Staging Production Rollback Backups Monitoring

Security

Firewall HTTPS Secrets Least privilege Updates Backups

Platform-specific items remain separate:

Joomla extensions Joomla caching WordPress plugins WooCommerce sessions Magento cache Magento indexing

50. Recommended Directory Model for a VPS

/opt/sites/ │ ├── joomla-company-a/ │ ├── compose.yaml │ ├── compose.prod.yaml │ ├── .env │ └── docker/ │ ├── wordpress-company-b/ │ ├── compose.yaml │ ├── compose.prod.yaml │ ├── .env │ └── docker/ │ ├── woocommerce-company-c/ │ ├── compose.yaml │ ├── compose.prod.yaml │ ├── .env │ └── docker/ │ └── monitoring/

Each customer environment remains isolated.

51. Strategic Value for an SME

The Docker approach provides more than technical convenience.

It creates a repeatable business process:

Standard Architecture ↓ Lower Development Risk ↓ Faster Deployment ↓ Repeatable Testing ↓ Predictable Maintenance ↓ Better Security ↓ Better Disaster Recovery ↓ Scalable SME IT Service

Instead of selling only:

"We build websites."

the organization can offer:

Managed, containerized, tested and monitored digital commerce platforms.

52. Recommended Technology Roadmap

Phase 1 — Development

Docker Joomla WordPress WooCommerce Nginx Redis MariaDB Varnish Git

Phase 2 — Testing

Automated smoke tests Performance testing Security testing Backup/restore testing

Phase 3 — Staging

Production-like VPS HTTPS Monitoring Realistic data Payment sandbox

Phase 4 — Production

HTTPS Firewall Backups Monitoring Varnish Redis Database

Phase 5 — DevOps

GitHub Actions CI/CD Automated deployments Security scanning Automated backups Rollback

Phase 6 — Advanced Platform

Central monitoring Prometheus Grafana Log aggregation Container registry Infrastructure as Code Automated VPS provisioning

53. Final Reference Architecture

The completed SME platform can be represented as:

CLIENT │ ▼ DNS │ ▼ ┌──────────────┐ │ HTTPS / TLS │ └──────┬───────┘ │ ▼ ┌───────┐ │ NGINX │ └───┬───┘ │ ▼ ┌─────────┐ │ VARNISH │ └────┬────┘ │ ▼ ┌───────┐ │ NGINX │ └───┬───┘ │ ▼ PHP-FPM │ ┌───────────────┼────────────────┐ │ │ │ ▼ ▼ ▼ JOOMLA WORDPRESS WOOCOMMERCE │ │ │ └───────────────┼────────────────┘ │ ┌──────┴──────┐ ▼ ▼ REDIS MARIADB │ │ └──────┬──────┘ ▼ APPLICATION

54. Conclusion

A professional Joomla, WordPress and WooCommerce environment should be designed as a software delivery platform, not simply as a collection of installed packages.

Docker Compose provides the foundation for reproducibility.

Nginx provides the web-serving and PHP-FPM integration layer.

Varnish provides public HTTP caching.

Redis provides application/object caching.

MariaDB provides persistent relational storage.

Git provides version control.

Staging provides a controlled pre-production environment.

Automated testing provides release confidence.

Backups and disaster recovery protect business data.

A VPS provides a cost-effective production platform for many SME workloads.

The most important architectural principle is separation:

Development ≠ Staging ≠ Production

and:

Public HTTP Cache ≠ Application Cache ≠ Persistent Database

For Joomla:

Varnish → public Joomla content Redis → application/object cache MariaDB → Joomla data

For WordPress:

Varnish → public WordPress pages Redis → object/application cache MariaDB → WordPress data

For WooCommerce:

Varnish → safe anonymous public pages Redis → object/application cache MariaDB → products/orders/customers

while:

Cart Checkout My Account Payment Order processing AJAX Customer-specific information

remain dynamic and must bypass inappropriate HTTP caching.

The resulting methodology provides a foundation for a professional SME web and eCommerce DevOps service, where Joomla, WordPress/WooCommerce and future platforms such as Magento/Hyvä can be developed locally, tested systematically, promoted to staging and deployed reproducibly to VPS infrastructure.

For an organization such as KeenComputer, this approach can become a standardized delivery framework for SME digital transformation: website development + eCommerce + DevOps + performance + security + backup + managed VPS operations, rather than treating each customer website as an individually configured server.