• 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 Magento 2 Systems on Modern Linode Infrastructure

Dockerizing and Orchestrating Legacy Magento 2 Systems on Modern Linode Infrastructure

Assessing Legacy Magento 2 for Containerization

Before diving into Dockerfiles and orchestration, a thorough assessment of the existing Magento 2 installation is paramount. Legacy systems often carry technical debt that can complicate containerization. Key areas to scrutinize include:

  • PHP Version Compatibility: Determine the exact PHP version(s) used. Magento 2 has specific version requirements. Ensure your chosen Docker image supports this or plan for necessary upgrades.
  • Extensions: Identify all installed third-party extensions. Some extensions might have hardcoded paths, rely on specific system libraries not present in minimal Docker images, or have complex installation procedures that need to be adapted.
  • Customizations: Analyze any custom themes or module modifications. These need to be packaged correctly within the container build process.
  • Database Dependencies: Note the specific MySQL/MariaDB version and any custom configurations or stored procedures.
  • Caching Mechanisms: Understand the current caching setup (e.g., Varnish, Redis, Memcached). These will likely become separate services in your containerized environment.
  • File System Permissions: Magento 2 is notoriously sensitive to file permissions. Document the current setup and plan how to replicate it within the container’s user context.
  • Environment Variables: Identify configuration settings that are currently managed via environment variables or direct file edits. These should be externalized for containerized deployments.

Crafting the Dockerfile for Magento 2

A robust Dockerfile is the foundation of your containerized Magento 2 application. We’ll aim for a multi-stage build to keep the final image lean. This example assumes a common setup using Apache, PHP, and Composer.

First, the build stage to install dependencies and compile Magento:

# Stage 1: Build dependencies and compile Magento
FROM composer:2.7 as builder

WORKDIR /app

# Copy composer.json and composer.lock first to leverage Docker cache
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader --prefer-dist

# Copy the rest of the Magento application code
COPY . .
RUN composer dump-autoload --optimize --no-dev

# Install Magento if it's not already present (e.g., for a fresh install or specific build)
# RUN bin/magento setup:di:compile \
#     && bin/magento setup:static-content:deploy -f en_US en_GB \
#     && bin/magento indexer:reindex \
#     && bin/magento cache:flush

# Stage 2: Production image
FROM php:8.2-apache

# Install necessary PHP extensions and system packages
RUN apt-get update && apt-get install -y \
    libzip-dev \
    unzip \
    git \
    libpng-dev \
    libjpeg-dev \
    libfreetype6-dev \
    libwebp-dev \
    libicu-dev \
    libxslt1-dev \
    acl \
    && rm -rf /var/lib/apt/lists/* \
    && docker-php-ext-configure gd --with-freetype --with-webp --with-jpeg \
    && docker-php-ext-install -j$(nproc) gd zip intl opcache bcmath sockets

# Configure Apache
COPY --from=builder /app/vendor/ /var/www/html/vendor/
COPY --from=builder /app/app/ /var/www/html/app/
COPY --from=builder /app/lib/ /var/www/html/lib/
COPY --from=builder /app/pub/ /var/www/html/pub/
COPY --from=builder /app/bin/ /var/www/html/bin/
COPY --from=builder /app/generated/ /var/www/html/generated/
COPY --from=builder /app/setup/ /var/www/html/setup/
COPY --from=builder /app/update/ /var/www/html/update/
COPY --from=builder /app/composer.json /var/www/html/composer.json
COPY --from=builder /app/composer.lock /var/www/html/composer.lock

# Copy Magento root files (excluding vendor, generated, etc.)
# This assumes your Magento root is the same as the builder's WORKDIR
COPY . /var/www/html/

# Ensure correct ownership for Magento files
RUN chown -R www-data:www-data /var/www/html \
    && chmod -R 0775 /var/www/html/var \
    && chmod -R 0775 /var/www/html/pub/static \
    && chmod -R 0775 /var/www/html/pub/media \
    && chmod -R 0775 /var/www/html/generated

# Configure Apache virtual host for Magento
COPY docker/apache/000-default.conf /etc/apache2/sites-available/000-default.conf
RUN a2enmod rewrite expires headers \
    && a2dissite 000-default.conf \
    && a2ensite 000-default.conf \
    && apache2ctl graceful

# Set environment variables for Magento configuration
ENV MAGENTO_ROOT=/var/www/html \
    MAGENTO_BASE_URL=http://localhost \
    APP_ENV=production

# Expose port 80
EXPOSE 80

# Default command to run Apache
CMD ["apache2-foreground"]

The `docker/apache/000-default.conf` would contain a standard Apache configuration for Magento:

# docker/apache/000-default.conf
<VirtualHost *:80>
    DocumentRoot /var/www/html/pub
    DirectoryIndex index.php

    <Directory /var/www/html/pub>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^(.*) index.php [L]
    </Directory>

    # Other Magento-specific Apache configurations can go here
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Orchestrating with Docker Compose

Docker Compose is ideal for defining and running multi-container Docker applications. For Magento 2, we typically need services for the web server, PHP-FPM (if not using Apache directly in the image), database, Redis, and potentially Varnish.

Here’s a sample `docker-compose.yml` for a basic setup:

version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: magento2_app
    ports:
      - "8080:80"
    volumes:
      - ./app_code:/var/www/html/app/code # Mount custom modules
      - ./pub_static:/var/www/html/pub/static # Persist static content
      - ./media:/var/www/html/pub/media # Persist media files
      - ./var:/var/www/html/var # Persist var directory (logs, cache, etc.)
    environment:
      - MAGENTO_ROOT=/var/www/html
      - MAGENTO_BASE_URL=http://localhost:8080
      - APP_ENV=production
      - DB_HOST=db
      - DB_NAME=magento
      - DB_USER=magento
      - DB_PASSWORD=magento_password
      - REDIS_FRONTEND_HOST=redis
      - REDIS_DEFAULT_HOST=redis
    depends_on:
      - db
      - redis
    networks:
      - magento_network

  db:
    image: mysql:8.0
    container_name: magento2_db
    environment:
      MYSQL_ROOT_PASSWORD: root_password
      MYSQL_DATABASE: magento
      MYSQL_USER: magento
      MYSQL_PASSWORD: magento_password
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - magento_network

  redis:
    image: redis:7.2
    container_name: magento2_redis
    networks:
      - magento_network

  # Optional: Varnish service
  # varnish:
  #   image: varnish:7.4
  #   container_name: magento2_varnish
  #   ports:
  #     - "80:80" # Varnish listens on port 80
  #   environment:
  #     - VCL_CONFIG=/etc/varnish/default.vcl
  #   volumes:
  #     - ./docker/varnish/default.vcl:/etc/varnish/default.vcl
  #   depends_on:
  #     - app
  #   networks:
  #     - magento_network

volumes:
  db_data:

networks:
  magento_network:
    driver: bridge

Key considerations for `docker-compose.yml`:

  • Volumes: Crucial for persisting database data, media files, generated code, and logs. Mounting `app_code` allows for live development of custom modules.
  • Environment Variables: Externalize database credentials, cache configurations, and base URLs. These should be managed securely, ideally via a `.env` file.
  • `depends_on`: Ensures services start in the correct order.
  • Networks: Creates a dedicated network for containers to communicate.
  • Static Content Deployment: The `pub/static` and `generated` directories are critical. In a production setup, you’d typically pre-compile static content during the Docker build or via a separate CI/CD step, rather than relying on runtime generation. The volumes here are for development convenience or to ensure persistence.

Database Migration and Initial Setup

Migrating an existing Magento 2 database into a Dockerized environment requires careful planning. The most straightforward approach for initial setup is to:

  • Dump the existing database: Use `mysqldump` on your current production or staging server.
  • Import into the Docker container: Start the `db` service, then use `docker exec` to import the dump.

Example import command:

# Assuming your dump file is named magento_dump.sql
docker exec -i magento2_db sh -c 'exec mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE"' < magento_dump.sql

After the database is imported, you’ll need to configure Magento to use the new database credentials and potentially update the base URL. This can be done via environment variables passed to the `app` service or by running Magento CLI commands within the container.

To run Magento CLI commands:

docker-compose exec app bin/magento setup:store-config:set --base-url=http://localhost:8080/
docker-compose exec app bin/magento setup:upgrade
docker-compose exec app bin/magento cache:flush

Linode Kubernetes Engine (LKE) Deployment Strategy

For production deployments on Linode, migrating from Docker Compose to Kubernetes is the logical next step for scalability and resilience. Linode Kubernetes Engine (LKE) provides a managed Kubernetes control plane.

Your `docker-compose.yml` translates into Kubernetes manifests (Deployments, Services, PersistentVolumeClaims, etc.).

Key Kubernetes Resources:

  • Deployments: For the Magento application, Redis, and potentially Varnish. These manage replica sets and rolling updates.
  • StatefulSets: Typically used for the MySQL database to ensure stable network identifiers and persistent storage.
  • Services: To expose your application internally (e.g., `app-service` pointing to the `app` Deployment) and externally (e.g., an Ingress controller or LoadBalancer Service).
  • PersistentVolumeClaims (PVCs): To request storage for your database, media, and logs. Linode Block Storage can be provisioned dynamically or statically.
  • ConfigMaps/Secrets: To manage environment variables and sensitive data like database passwords.
  • Ingress Controller: To manage external access to your services, handle SSL termination, and route traffic (e.g., Nginx Ingress Controller, Traefik).

A simplified example of a Magento Deployment manifest:

# kubernetes/deployment-app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: magento-app
  labels:
    app: magento
spec:
  replicas: 2 # Scale as needed
  selector:
    matchLabels:
      app: magento
  template:
    metadata:
      labels:
        app: magento
    spec:
      containers:
      - name: magento
        image: your-docker-registry/magento2:latest # Replace with your image
        ports:
        - containerPort: 80
        envFrom:
        - configMapRef:
            name: magento-config
        - secretRef:
            name: magento-secrets
        volumeMounts:
        - name: pub-static-volume
          mountPath: /var/www/html/pub/static
        - name: media-volume
          mountPath: /var/www/html/pub/media
        - name: var-volume
          mountPath: /var/www/html/var
      volumes:
      - name: pub-static-volume
        persistentVolumeClaim:
          claimName: magento-static-pvc
      - name: media-volume
        persistentVolumeClaim:
          claimName: magento-media-pvc
      - name: var-volume
        persistentVolumeClaim:
          claimName: magento-var-pvc

And a corresponding Service:

# kubernetes/service-app.yaml
apiVersion: v1
kind: Service
metadata:
  name: magento-app-service
spec:
  selector:
    app: magento
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP # Typically exposed via Ingress

You would create similar manifests for Redis, MySQL (using a StatefulSet), and potentially Varnish. The database service would likely be a managed database service provided by Linode or another cloud provider for better reliability and management.

Performance Tuning and Monitoring

Containerizing Magento 2 on Linode opens up opportunities for performance tuning. Key areas include:

  • PHP-FPM Configuration: Tune `pm.max_children`, `pm.start_servers`, `pm.min_spare_servers`, `pm.max_spare_servers`, and `pm.max_requests` within the PHP-FPM pool configuration (if using PHP-FPM).
  • OpCache: Ensure OpCache is enabled and properly configured in `php.ini` within your Docker image.
  • Redis Tuning: Optimize Redis configuration for caching and session storage.
  • Database Optimization: Indexing, query optimization, and proper MySQL configuration (`innodb_buffer_pool_size`, etc.).
  • Varnish Configuration: Fine-tune VCL for optimal caching and request handling.
  • Resource Allocation: Properly size your LKE nodes and container resource requests/limits in Kubernetes.
  • Monitoring: Implement robust monitoring using tools like Prometheus and Grafana, integrated with your LKE cluster, to track container resource usage, application performance metrics (APM), and error rates.

By systematically containerizing and orchestrating your legacy Magento 2 system on Linode, you can achieve greater scalability, improved deployment efficiency, and a more resilient infrastructure.

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

  • Leveraging Laravel Octane and Docker Swarm for High-Performance, Scalable WordPress Headless Deployments
  • Migrating Legacy WordPress to Headless with Laravel: A Performance and Security Deep Dive
  • Leveraging PHP 8’s JIT Compiler and Vector APIs for Extreme Web Application Performance
  • Leveraging PHP 8 JIT and AWS Lambda for High-Performance, Serverless WordPress REST API Backends
  • Beyond the Basics: Leveraging PHP 8.3’s JIT Compiler and Fibers for High-Concurrency Laravel Applications

Categories

  • apache (1)
  • Business & Monetization (390)
  • Centos (4)
  • Comparisons & Decision Making (55)
  • Debian (2)
  • Debugging & Troubleshooting (664)
  • Desktop Applications (14)
  • DevOps (11)
  • DevOps & Cloud Scaling (962)
  • Django (1)
  • Laravel (6)
  • Migration & Architecture (192)
  • Mobile Applications (24)
  • MySQL (1)
  • Performance & Optimization (873)
  • PHP (15)
  • PHP Development (49)
  • Plugins & Themes (244)
  • Programming Languages (10)
  • Python (20)
  • Ruby on Rails (1)
  • Security & Compliance (650)
  • SEO & Growth (492)
  • Server (118)
  • Softwares (1)
  • Ubuntu (9)
  • Uncategorized (20)
  • VB6 & VB.NET (8)
  • Web Applications & Frontend (19)
  • Web Assembly (Wasm) (2)
  • WordPress (26)
  • WordPress Plugin Development (728)
  • WordPress Theme Development (357)

Recent Posts

  • Leveraging Laravel Octane and Docker Swarm for High-Performance, Scalable WordPress Headless Deployments
  • Migrating Legacy WordPress to Headless with Laravel: A Performance and Security Deep Dive
  • Leveraging PHP 8's JIT Compiler and Vector APIs for Extreme Web Application Performance

Top Categories

  • DevOps & Cloud Scaling (962)
  • Performance & Optimization (873)
  • WordPress Plugin Development (728)
  • Debugging & Troubleshooting (664)
  • Security & Compliance (650)
  • SEO & Growth (492)

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