• Skip to secondary menu
  • Skip to main content
  • Skip to primary sidebar
  • Home
  • Projects
  • Products
  • Themes
  • Tools
  • Request for Quote

Vengala Vinay

Having 12+ Years of Experience in Software Development

  • Home
  • WordPress
  • PHP
    • Codeigniter
  • Django
  • Magento
  • Selenium
  • Server
Home » Dockerizing and Orchestrating Legacy WordPress Systems on Modern OVH Infrastructure

Dockerizing and Orchestrating Legacy WordPress Systems on Modern OVH Infrastructure

Assessing Legacy WordPress for Containerization

Before embarking on the Dockerization journey for a legacy WordPress installation, a thorough assessment is paramount. This involves identifying dependencies, understanding the existing infrastructure, and pinpointing potential compatibility issues with containerized environments. Legacy systems often have hardcoded paths, specific PHP version requirements, and custom configurations that need careful extraction and adaptation.

Key areas to scrutinize include:

  • PHP Version: Determine the exact PHP version and any required extensions (e.g., gd, imagick, mysqli, mbstring). Legacy sites might be tied to older, unsupported PHP versions, necessitating careful consideration of security implications and potential upgrade paths.
  • Database: Identify the database type (typically MySQL/MariaDB) and version. Note any specific configurations or stored procedures.
  • File System: Map out the WordPress core, themes, plugins, and uploads directories. Understand any custom directory structures or symbolic links.
  • External Dependencies: Document any external services or APIs the WordPress site interacts with (e.g., caching layers, email services, CDNs, custom API endpoints).
  • Custom Code: Analyze any custom themes, plugins, or modifications to core WordPress files. These are often the most challenging aspects to containerize due to potential hardcoded paths or system-level dependencies.
  • Cron Jobs: Identify any server-level cron jobs that interact with the WordPress site, such as WP-CLI commands or custom scripts.

Crafting the Dockerfile for WordPress Core and Plugins

We’ll start by building a robust Dockerfile that encapsulates the WordPress application. This involves selecting an appropriate base image, installing necessary software, and configuring the WordPress environment.

Consider a multi-stage build to keep the final image lean. The first stage can handle dependency installation and compilation, while the second stage copies only the necessary artifacts.

Here’s a sample Dockerfile, assuming a PHP 8.1 environment with common extensions. Adjust the PHP version and extensions based on your legacy system’s requirements.

Dockerfile Example

# Stage 1: Builder
FROM php:8.1-fpm-buster AS builder

# Install system dependencies for PHP extensions
RUN apt-get update && apt-get install -y \
    libzip-dev \
    libpng-dev \
    libjpeg-dev \
    libfreetype6-dev \
    libwebp-dev \
    libssl-dev \
    libonig-dev \
    unzip \
    git \
    && rm -rf /var/lib/apt/lists/*

# Install PHP extensions
RUN docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp \
    && docker-php-ext-install -j$(nproc) gd zip pdo_mysql mbstring exif opcache \
    && pecl install redis \
    && docker-php-ext-enable redis

# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer

# Set working directory
WORKDIR /var/www/html

# Copy WordPress core and plugins (assuming they are in a local 'wordpress' directory)
# For legacy systems, you might need to copy your existing WordPress installation here.
COPY wordpress/ .

# Install Composer dependencies for plugins if any
# RUN composer install --no-dev --optimize-autoloader

# Clean up apt cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Stage 2: Production Image
FROM php:8.1-fpm-buster

# Install only runtime dependencies
RUN apt-get update && apt-get install -y \
    libzip4 \
    libpng16-16 \
    libjpeg62-turbo \
    libfreetype6 \
    libwebp6 \
    libssl1.1 \
    libonig5 \
    && rm -rf /var/lib/apt/lists/*

# Copy PHP extensions from builder stage
COPY --from=builder /usr/local/lib/php/extensions/no-debug-non-zts-20210902/ /usr/local/lib/php/extensions/no-debug-non-zts-20210902/

# Enable PHP extensions
RUN docker-php-ext-enable gd zip pdo_mysql mbstring exif redis opcache

# Set working directory
WORKDIR /var/www/html

# Copy WordPress core and plugins from builder stage
COPY --from=builder /var/www/html/ .

# Ensure correct ownership for WordPress files
RUN chown -R www-data:www-data /var/www/html

# Expose port 9000 for PHP-FPM
EXPOSE 9000

# Default command to start PHP-FPM
CMD ["php-fpm"]

Configuring Nginx as a Reverse Proxy

A separate Nginx container will serve as the web server and reverse proxy to the PHP-FPM container. This separation provides flexibility and allows for easier management of web server configurations.

Nginx Configuration Example

server {
    listen 80;
    server_name your-domain.com; # Replace with your domain

    root /var/www/html;
    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass wordpress:9000; # 'wordpress' is the service name in docker-compose
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # Deny access to sensitive files
    location ~ /\.ht {
        deny all;
    }

    # Caching for static assets (optional, but recommended)
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2)$ {
        expires 30d;
        add_header Cache-Control "public, no-transform";
    }
}

Setting up the Database Container (MariaDB/MySQL)

A dedicated database container is crucial for a robust WordPress deployment. We’ll use MariaDB as an example, a popular drop-in replacement for MySQL.

Database Container Configuration

services:
  db:
    image: mariadb:10.6 # Use a specific version for stability
    container_name: wordpress_db
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: your_root_password # Change this
      MYSQL_DATABASE: wordpress_db
      MYSQL_USER: wordpress_user
      MYSQL_PASSWORD: your_db_password # Change this
    ports:
      - "3306:3306" # Expose only if external access is needed for debugging

volumes:
  db_data:

Orchestrating with Docker Compose

Docker Compose is the ideal tool for defining and running multi-container Docker applications. It allows us to define our WordPress, Nginx, and database services in a single YAML file.

docker-compose.yml Example

version: '3.8'

services:
  wordpress:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: wordpress_app
    volumes:
      - wp_content:/var/www/html/wp-content # Persist uploads and themes/plugins
      - ./custom-config/php.ini:/usr/local/etc/php/conf.d/custom.ini # For custom PHP settings
    depends_on:
      - db
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_NAME: wordpress_db
      WORDPRESS_DB_USER: wordpress_user
      WORDPRESS_DB_PASSWORD: your_db_password # Must match db service password
    restart: always
    networks:
      - app-network

  nginx:
    image: nginx:stable-alpine
    container_name: wordpress_nginx
    ports:
      - "80:80"
      - "443:443" # If using SSL
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d # Mount Nginx configuration
      - ./certs:/etc/nginx/certs # Mount SSL certificates if used
      - wp_content:/var/www/html/wp-content # Share wp-content for static asset caching
    depends_on:
      - wordpress
    restart: always
    networks:
      - app-network

  db:
    image: mariadb:10.6
    container_name: wordpress_db
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: your_root_password
      MYSQL_DATABASE: wordpress_db
      MYSQL_USER: wordpress_user
      MYSQL_PASSWORD: your_db_password
    networks:
      - app-network

volumes:
  wp_content:
  db_data:

networks:
  app-network:

Migrating Legacy Data and Configuration

This is often the most critical and time-consuming phase. For legacy systems, direct copying of files might not suffice. We need to ensure data integrity and compatibility.

Database Migration

1. Export Existing Database: Use mysqldump to create a backup of your current WordPress database.

mysqldump -u [your_db_user] -p [your_db_name] > wordpress_backup.sql

2. Import into Containerized DB: Once the database container is running, you can import the data. The easiest way is to mount the SQL file into a temporary container or use kubectl exec if deploying on Kubernetes.

# Using docker exec (assuming db container is named 'wordpress_db')
docker exec -i wordpress_db sh -c 'exec mysql -u root -p"$MYSQL_ROOT_PASSWORD" "$MYSQL_DATABASE"' < wordpress_backup.sql

File System Migration

1. Copy WordPress Files: Copy your existing WordPress installation (excluding the database dump) into the `wordpress` directory that your Dockerfile expects, or directly into the volume mount for the `wordpress` service if you’re not building from source.

# Assuming your legacy WordPress is in /var/www/html/legacy-wp
cp -R /var/www/html/legacy-wp/* . # Copy into the directory where Dockerfile expects it

2. Update `wp-config.php`: Ensure your `wp-config.php` file within the copied WordPress files uses the correct database credentials defined in your `docker-compose.yml`.

// Inside your wp-config.php
define( 'DB_HOST', 'db:3306' ); // Use the service name and port
define( 'DB_NAME', 'wordpress_db' );
define( 'DB_USER', 'wordpress_user' );
define( 'DB_PASSWORD', 'your_db_password' );

3. Handle Uploads: The `wp_content` volume mount will ensure that your existing `wp-content` directory (themes, plugins, uploads) is persisted. If you’re migrating from a very old setup, ensure file permissions are correctly set after copying.

Deploying on OVH Infrastructure

OVH offers several solutions suitable for containerized WordPress deployments, ranging from managed Kubernetes (OVHcloud Managed Kubernetes) to Virtual Private Servers (VPS) where you can run Docker directly.

Option 1: OVHcloud Managed Kubernetes (EKS)

For production environments requiring scalability, high availability, and robust orchestration, Managed Kubernetes is the recommended path. The process involves:

  • Setting up a Managed Kubernetes Cluster: Provision a cluster through the OVHcloud control panel.
  • Creating Kubernetes Manifests: Convert your docker-compose.yml into Kubernetes YAML files (Deployments, Services, PersistentVolumeClaims, Ingress).
  • Deploying to the Cluster: Use kubectl apply -f your-manifests.yaml to deploy your application.
  • Configuring Ingress: Use OVH’s Load Balancer or an Ingress Controller (like Nginx Ingress) to expose your WordPress application to the internet.

Example Kubernetes Deployment Snippet (WordPress Service):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
spec:
  replicas: 2 # Scale as needed
  selector:
    matchLabels:
      app: wordpress
  template:
    metadata:
      labels:
        app: wordpress
    spec:
      containers:
      - name: wordpress
        image: your-dockerhub-repo/wordpress:latest # Your custom image
        ports:
        - containerPort: 9000
        env:
        - name: WORDPRESS_DB_HOST
          value: wordpress-db-service:3306
        - name: WORDPRESS_DB_NAME
          value: wordpress_db
        - name: WORDPRESS_DB_USER
          value: wordpress_user
        - name: WORDPRESS_DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: wordpress-db-secrets
              key: db-password
        volumeMounts:
        - name: wp-content-volume
          mountPath: /var/www/html/wp-content
      volumes:
      - name: wp-content-volume
        persistentVolumeClaim:
          claimName: wordpress-content-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: wordpress-service
spec:
  selector:
    app: wordpress
  ports:
    - protocol: TCP
      port: 9000
      targetPort: 9000
  type: ClusterIP

Option 2: Docker on OVH VPS

For simpler deployments or development environments, running Docker directly on an OVH VPS is a viable option. The steps are:

  • Provision an OVH VPS: Choose a VPS instance with sufficient resources.
  • Install Docker and Docker Compose: Follow the official Docker installation guides for your VPS’s operating system (e.g., Ubuntu).
  • Copy Project Files: Transfer your Dockerfile, docker-compose.yml, and Nginx configuration to the VPS.
  • Build and Run: Navigate to your project directory on the VPS and execute docker-compose up -d.
  • Configure Firewall: Ensure ports 80 and 443 are open in the VPS firewall.

Post-Deployment Considerations and Best Practices

Once your legacy WordPress system is containerized and deployed, several ongoing tasks and best practices are essential for maintaining a healthy and secure environment.

Logging and Monitoring

Centralized logging is crucial. Configure your containers to log to stdout and stderr, and use a log aggregation tool (like ELK stack, Grafana Loki, or cloud-native logging services) to collect and analyze logs from all containers. Monitor container health, resource utilization (CPU, memory), and application-specific metrics.

Backups

Implement a robust backup strategy for both the database and the persistent volumes (especially `wp-content` and `db_data`). For Docker on VPS, this might involve scheduled scripts that dump the database and archive volume data. On Kubernetes, leverage PersistentVolume snapshots or dedicated backup solutions.

Security Updates

Regularly update your base Docker images, PHP versions, and WordPress core, themes, and plugins. Automate security scanning of your container images to detect vulnerabilities. For legacy systems, this might involve testing updates in a staging environment before deploying to production.

Performance Tuning

Leverage Nginx caching, PHP OPcache, and consider external caching solutions like Redis or Memcached (which can also be run as separate containers). Optimize database queries and WordPress configurations for performance within the containerized environment.

Environment Variables

Utilize environment variables for sensitive information (database credentials, API keys) and configuration settings. This keeps secrets out of your Dockerfiles and configuration files, making them more portable and secure.

Primary Sidebar

A little about the Author

Having 12+ Years of Experience in Software Development, Vinay is a principal software architect, senior systems engineer, and elite technical consultant. He specializes in bespoke PHP/WordPress development, high-performance Magento 2 & Shopify architectures, custom plugin/theme development from scratch, and legacy code modernization (including VB6, VB.NET, PyQt, and Crystal Reports). Known for solving complex database bottlenecks, speed optimization (Core Web Vitals), and advanced security code auditing, Vinay engineers production-ready systems designed to scale under heavy concurrent load conditions.



Chat on WhatsApp

Recent Posts

  • Go Goroutines vs. Node.js Event Loop: Scaling I/O-Bound Microservices Under High Load
  • Elixir Phoenix vs. Go Gin: Concurrency Models and Fault Tolerance Under Peak Request Volume
  • Python Celery vs. Go Channels: Distributed Task Queue Overhead and Memory Reliability
  • Scala Pekko vs. Go Goroutines: Actor Model vs. CSP for Event-Driven Reactive Systems
  • Java Loom Virtual Threads vs. Go Goroutines: Under-the-Hood Scheduler and Thread Overhead Comparison

Categories

  • apache (1)
  • Business & Monetization (390)
  • Centos (4)
  • Comparisons & Decision Making (55)
  • Debian (2)
  • Debugging & Troubleshooting (584)
  • Desktop Applications (14)
  • DevOps (7)
  • DevOps & Cloud Scaling (962)
  • Django (1)
  • Laravel (4)
  • Migration & Architecture (192)
  • Mobile Applications (24)
  • MySQL (1)
  • Performance & Optimization (806)
  • PHP (5)
  • PHP Development (21)
  • Plugins & Themes (244)
  • Programming Languages (9)
  • Python (19)
  • Ruby on Rails (1)
  • Security & Compliance (543)
  • SEO & Growth (491)
  • Server (23)
  • Ubuntu (9)
  • VB6 & VB.NET (8)
  • Web Applications & Frontend (19)
  • Web Assembly (Wasm) (2)
  • WordPress (22)
  • WordPress Plugin Development (7)
  • WordPress Theme Development (357)

Recent Posts

  • Go Goroutines vs. Node.js Event Loop: Scaling I/O-Bound Microservices Under High Load
  • Elixir Phoenix vs. Go Gin: Concurrency Models and Fault Tolerance Under Peak Request Volume
  • Python Celery vs. Go Channels: Distributed Task Queue Overhead and Memory Reliability

Top Categories

  • DevOps & Cloud Scaling (962)
  • Performance & Optimization (806)
  • Debugging & Troubleshooting (584)
  • Security & Compliance (543)
  • SEO & Growth (491)
  • Business & Monetization (390)

Our Products

  • ERP & LMS Systems (4)
  • Directories & Marketplaces (4)
  • Healthcare Portals (3)
  • Point of Sale (POS) (2)
  • E-Commerce Engines (2)

Our Services

  • E-Commerce Development (10)
  • WordPress Development (8)
  • Python & Desktop GUI (7)
  • General Consulting (7)
  • Legacy Modernization (5)
  • Mobile App Development (4)

Copyright © 2026 · Vinay Vengala