In regards to working on my personal projects, my main machine runs on Manjaro and configuring it to a LAMP setup is really a pain especially with PHP and its related plugins. Manjaro is more of a hobbyist Linux distro for the most part since it’s doesn’t receive official support on the vast majority of hardware and software vendors. My approach to Dockerizing WordPress for “local development” is a bit unconventional since besides doing it on my main machine, I may do it on a Virtualbox VM with a Linux Distro like Ubuntu or AlmaLinux running Docker. Also, I give the WordPress and phpMyAdmin Containers their own static IPs which are accessible on my LAN.

Directory Setup and Plugins

To make Dockerizing a WordPress site as self-contained as possible to my liking, I’d make a new directory located under the home directory or a mounted drive that doesn’t require root access on my main machine or in a VM hosted by my main machine. Moreover, that new directory would be used to house WordPress (its subdirectories and files), the docker-compose.yml file, and the mysql dump file.

dir_files_dump_setup

In addition, I would rename/disable plugins that could possibly affect the migration from online to local development machine such W3 Total, Cache, Jetpack, etc.

 

Things to edit in wp-config.php

On live websites, I often use the W3 Total Cache plugin, so when in local development besides renaming its plugin directory/folder, I also have to edit the wp-config.php file to disable it and it’s usually near the top.

define('WP_CACHE', false); // Added by W3 Total Cache


Conventionally in Apache, you’d use “localhost” for MySQL hostname, but in Docker, you’d use the service name of the container(not the container name) instead. To allow myself to login to the admin page of the WordPress site, I would have to change to the define(‘FORCE_SSL_ADMIN’, true) line to false.

//Force SSL
define('FORCE_SSL_ADMIN', false);

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'wpsite' );

/** MySQL database username */
define( 'DB_USER', 'wpdbuser' );

/** MySQL database password */
define( 'DB_PASSWORD', 'password' );

/** MySQL hostname */
define( 'DB_HOST', 'wp_db' );

/** Database Charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8mb4' );

/** The Database Collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );

define('FS_METHOD', 'direct'); //Allows WordPress to update, gets around FTP error
define('WP_HOME', 'http://192.168.1.53');
define('WP_SITEURL', 'http://192.168.1.53');


Prevents WordPress from nagging you for FTP credentials when trying to update WordPress versions and plugins inside the WordPress admin dashboard

define('FS_METHOD', 'direct');


To fix the URLs/permalinks on the local machine/VM

define('WP_HOME', 'http://192.168.1.53');
define('WP_SITEURL', 'http://192.168.1.53');


Overview of the Docker compose file I’d use for local development

version: '3.8'

services:
  wp_db:
    image: mariadb:latest
    container_name: "WordPress_DB"
    volumes:
      - ./wpdump.sql:/docker-entrypoint-initdb.d/backup.sql
      - ./dbdata:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: wpsite
      MYSQL_USER: wpdbuser
      MYSQL_PASSWORD: password
    networks:
      wp_network:
        ipv4_address: 192.168.1.51


  phpmyadmin:
    depends_on:
      - wp_db
    image: phpmyadmin:latest
    container_name: phpmyadmin
    environment:
      PMA_HOST: wp_db
      MYSQL_ROOT_PASSWORD: password
    restart: always
    networks:
      wp_network:
        ipv4_address: 192.168.1.52
      

  wordpress:
    depends_on: 
      - wp_db
    image: wordpress:latest
    container_name: "WordPress_Website"
    restart: always
    volumes:
      - ./wordpress:/var/www/html/
    environment:
      WORDPRESS_DB_HOST: wp_db
      WORDPRESS_DB_USER: wpdbuser
      WORDPRESS_DB_PASSWORD: password
      WORDPRESS_DB_NAME: wpsite
    networks:  
      wp_network:
        ipv4_address: 192.168.1.53


# Persistent storage
volumes:
  dbdata: 
  wordpress:  


# WordPress network
networks:
 wp_network:
   driver: ipvlan
   driver_opts:
     parent: enp0s3 #device name of the NIC the host is using
   ipam:
     config:
       - subnet: 192.168.1.0/24
         gateway: 192.168.1.1 

Fix permissions to allow WordPress to download and update plugins and files after launching the Docker compose file

sudo docker exec –it WordPress_Site /binbash #Login to WordPress container and use shell
sudo chown -R www-data:www-data /var/www/html #Execute when logged into WordPress Container, in this case WordPress_site

With this setup, the MySQL dump file is restored automatically and persistent volumes for MySQL and WordPress are created. Furthermore,