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

Vengala Vinay

Having 9+ Years of Experience in Software Development

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

Dockerizing and Orchestrating Legacy Magento 2 Systems on Modern OVH Infrastructure

Assessing Legacy Magento 2 for Containerization

Before embarking on the Dockerization journey for a legacy Magento 2 installation, a thorough assessment of its architecture and dependencies is paramount. Legacy systems often harbor custom modules, outdated PHP extensions, and specific OS-level packages that may not translate directly into a clean containerized environment. Key areas to scrutinize include:

  • PHP Version Compatibility: Identify the exact PHP version and all required extensions. Magento 2 has strict version requirements.
  • Third-Party Integrations: Document all external services, APIs, and their connection methods (e.g., SOAP, REST, direct database access).
  • Custom Modules: Analyze custom modules for hardcoded paths, OS-specific commands, or dependencies on system libraries.
  • File Permissions and Ownership: Magento is notoriously sensitive to file permissions. Document the expected ownership and permissions for the entire Magento directory structure.
  • Cron Jobs: List all Magento and system cron jobs that need to be replicated within the containerized environment.
  • Database Schema and Data: Understand the database structure and any specific configurations or stored procedures.
  • Caching Mechanisms: Identify the caching layers in use (e.g., Redis, Varnish, Memcached) and their configurations.
  • Static Content Deployment: Note the process for deploying static content and its dependencies.

This initial audit will inform the structure of your Dockerfile and the overall orchestration strategy.

Crafting the Dockerfile for Magento 2

A robust Dockerfile is the cornerstone of a successful containerization effort. For Magento 2, this typically involves a multi-stage build to keep the final image lean. We’ll start with a base PHP image and layer on the necessary components.

Consider the following Dockerfile structure:

Base Image and PHP Configuration

We’ll use an official PHP-FPM image, ensuring the correct version and enabling essential extensions. For a legacy system, you might need to compile some extensions if they aren’t readily available.

# Stage 1: Build dependencies
FROM php:8.1-fpm-alpine AS builder

# Install system dependencies for PHP extensions
RUN apk update && apk add --no-cache \
    libzip-dev \
    libpng-dev \
    libjpeg-turbo-dev \
    freetype-dev \
    icu-dev \
    imagemagick-dev \
    git \
    composer:latest \
    && docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install -j$(nproc) gd \
    && docker-php-ext-install zip \
    && docker-php-ext-install intl \
    && docker-php-ext-install opcache \
    && pecl install imagick \
    && docker-php-ext-enable imagick

# Set working directory
WORKDIR /var/www/html

# Copy composer.json and composer.lock
COPY composer.json composer.lock ./

# Install Composer dependencies
RUN composer install --no-dev --prefer-dist --optimize-autoloader --no-progress --no-interaction

# Copy Magento application code
COPY . .

# Run Magento setup commands (if applicable during build, though often done at runtime)
# RUN bin/magento setup:upgrade && bin/magento setup:di:compile && bin/magento setup:static-content:deploy en_US -f

# Stage 2: Production image
FROM php:8.1-fpm-alpine AS production

# Install runtime dependencies
RUN apk update && apk add --no-cache \
    libzip \
    libpng \
    libjpeg-turbo \
    freetype \
    icu \
    imagemagick \
    # Add any other runtime dependencies identified during audit

# 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/

# Copy Composer dependencies and application code from builder stage
COPY --from=builder /var/www/html /var/www/html

# Set correct permissions (adjust as needed for your specific setup)
RUN chown -R www-data:www-data /var/www/html && chmod -R 755 /var/www/html

# Expose port
EXPOSE 9000

# Set entrypoint (optional, can be handled by docker-compose)
# ENTRYPOINT ["php-fpm"]

Nginx Configuration for Magento 2

A separate Nginx container is essential for serving Magento 2. The Nginx configuration needs to be optimized for Magento, handling static files efficiently and proxying dynamic requests to the PHP-FPM container.

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

    # Magento root directory
    root /var/www/html/pub;

    index index.php index.html index.htm;

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

    # Serve static files directly
    location ~ ^/(media|static)/ {
        expires 30d;
        access_log off;
        add_header Cache-Control "public";
    }

    # Pass PHP scripts to FPM
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php-fpm:9000; # 'php-fpm' 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 ~* /\. {
        deny all;
    }

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

Orchestrating with Docker Compose

Docker Compose simplifies the management of multi-container Docker applications. For Magento 2, we’ll need services for the web server (Nginx), PHP-FPM, database (MySQL), and potentially caching layers like Redis.

version: '3.8'

services:
  web:
    image: nginx:latest
    container_name: magento2_web
    ports:
      - "80:80"
      - "443:443" # If using SSL
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d # Mount custom Nginx config
      - ./magento:/var/www/html # Mount Magento code
      - ./ssl:/etc/nginx/ssl # Mount SSL certificates if applicable
    depends_on:
      - php-fpm
    networks:
      - magento-network

  php-fpm:
    build:
      context: .
      dockerfile: Dockerfile # Path to your Dockerfile
    container_name: magento2_php_fpm
    volumes:
      - ./magento:/var/www/html # Mount Magento code
    expose:
      - "9000"
    depends_on:
      - db
      - redis
    networks:
      - magento-network

  db:
    image: mysql:8.0
    container_name: magento2_db
    environment:
      MYSQL_ROOT_PASSWORD: your_root_password
      MYSQL_DATABASE: magento2_db
      MYSQL_USER: magento_user
      MYSQL_PASSWORD: your_db_password
    volumes:
      - magento2_db_data:/var/lib/mysql
    networks:
      - magento-network

  redis:
    image: redis:latest
    container_name: magento2_redis
    networks:
      - magento-network

volumes:
  magento2_db_data:

networks:
  magento-network:
    driver: bridge

Database Migration and Setup

Migrating the database from a legacy environment to a containerized MySQL instance requires careful planning. For production, it’s often best to perform this during a maintenance window.

Dumping and Restoring the Database

First, dump your existing Magento 2 database. Ensure you exclude any large, unnecessary tables if possible (e.g., `report_event`, `log_*` tables if not needed for auditing).

# On your legacy server
mysqldump -u your_db_user -p your_magento_db > magento_db_backup.sql

Then, restore this dump into your Dockerized MySQL container. You can do this by copying the SQL file into the container and executing it, or by using `docker exec` to pipe the dump directly.

# After starting your docker-compose services
docker cp magento_db_backup.sql magento2_db:/tmp/magento_db_backup.sql
docker exec -i magento2_db mysql -u root -p'your_root_password' magento2_db < /tmp/magento_db_backup.sql
# Or, if you have the user/password configured in docker-compose:
# docker exec -i magento2_db mysql -u magento_user -p'your_db_password' magento2_db < /tmp/magento_db_backup.sql

Updating Database Configuration

After restoring the database, you’ll need to update Magento’s database configuration. This is typically done by editing the `app/etc/env.php` file within your Magento codebase. Ensure the database connection details match your Docker Compose setup.

<?php
return [
    'modules' => [
        // ... module configurations
    ],
    'db' => [
        'connection' => [
            'default' => [
                'host' => 'db', // Service name from docker-compose
                'dbname' => 'magento2_db',
                'username' => 'magento_user',
                'password' => 'your_db_password',
                'model' => 'mysql4',
                'initStatements' => 'SET NAMES utf8',
                'engine' => 'innodb',
            ],
        ],
        'table_prefix' => '',
    ],
    'cache' => [
        'frontend' => [
            'default' => [
                'backend' => 'Magento\Framework\Cache\Backend\Redis',
                'backend_options' => [
                    'server' => 'redis', // Service name from docker-compose
                    'database' => '0',
                    'port' => '6379',
                ],
            ],
            'page_cache' => [
                'backend' => 'Magento\Framework\Cache\Backend\Redis',
                'backend_options' => [
                    'server' => 'redis',
                    'database' => '1',
                    'port' => '6379',
                ],
            ],
        ],
    ],
    // ... other configurations
];
?>

Post-Deployment Steps and Considerations

Once your containers are up and running, several crucial steps are needed to finalize the deployment and ensure optimal performance.

Running Magento Commands

You’ll need to execute several Magento CLI commands within the PHP-FPM container. This is best done using `docker exec`.

# Recompile dependency injection
docker exec -it magento2_php_fpm bin/magento setup:di:compile

# Deploy static content (adjust locale as needed)
docker exec -it magento2_php_fpm bin/magento setup:static-content:deploy en_US -f

# Clear cache
docker exec -it magento2_php_fpm bin/magento cache:clean
docker exec -it magento2_php_fpm bin/magento cache:flush

# Reindex (if necessary)
# docker exec -it magento2_php_fpm bin/magento indexer:reindex

Cron Job Management

Magento’s cron jobs need to run reliably. Instead of relying on host cron jobs, it’s better to manage them within the containerized environment. You can achieve this by running a separate cron container or by adding a cron process to your existing PHP-FPM Dockerfile and entrypoint.

A common approach is to have a dedicated cron container:

# Add to your docker-compose.yml
  cron:
    build:
      context: .
      dockerfile: Dockerfile # Ensure your Dockerfile has cron capabilities or a separate one
    container_name: magento2_cron
    volumes:
      - ./magento:/var/www/html
    command: >
      sh -c "while true; do
        php bin/magento cron:run && sleep 60;
      done"
    depends_on:
      - php-fpm
    networks:
      - magento-network

SSL/TLS Configuration

For production environments, securing your Magento instance with SSL/TLS is non-negotiable. You can manage SSL certificates within the Nginx container. Mount your certificates to `/etc/nginx/ssl` and update your Nginx configuration to listen on port 443 and use the certificates.

# Add to your Nginx server block in nginx/conf.d/default.conf
listen 443 ssl http2;
server_name your_domain.com;

ssl_certificate /etc/nginx/ssl/your_domain.crt;
ssl_certificate_key /etc/nginx/ssl/your_domain.key;

# ... other SSL settings (protocols, ciphers, etc.)

# Redirect HTTP to HTTPS
server {
    listen 80;
    server_name your_domain.com;
    return 301 https://$host$request_uri;
}

Logging and Monitoring

Implement a robust logging strategy. Configure Nginx and PHP-FPM to log to stdout/stderr, which Docker can then capture and forward to a centralized logging system (e.g., ELK stack, Splunk, Datadog). For monitoring, Prometheus and Grafana are excellent choices for tracking container resource usage, application performance metrics, and error rates.

OVH Infrastructure Integration

When deploying on OVH, consider leveraging their managed services where appropriate. For databases, you might opt for OVH’s managed MySQL or PostgreSQL services instead of running MySQL in Docker, which can simplify management and scaling. For persistent storage, OVH’s block storage or object storage can be integrated for media files or backups. Networking within OVH’s cloud requires careful configuration of security groups and load balancers to ensure proper traffic flow to your Dockerized Magento application.

Primary Sidebar

A little about the Author

Having 9+ Years of Experience in Software Development.
Expertised in Php Development, WordPress Custom Theme Development (From scratch using underscores or Genesis Framework or using any blank theme or Premium Theme), Custom Plugin Development. Hands on Experience on 3rd Party Php Extension like Chilkat, nSoftware.

Recent Posts

  • Step-by-Step: Diagnosing thread pools deadlock during concurrent ActiveRecord transaction processing on Linode Servers
  • Securing Your E-commerce APIs: Preventing SQL Injection (SQLi) in customized checkout queries in WooCommerce Implementations
  • Disaster Recovery 101: Architecting Auto-Failovers for MySQL and Ruby Deployments on Linode
  • High-Throughput Caching Strategies: Scaling MySQL for Perl Application APIs
  • Disaster Recovery 101: Architecting Auto-Failovers for DynamoDB and Laravel Deployments on DigitalOcean

Copyright © 2026 · Vinay Vengala