WordPress in Docker Setup

Every few months, I find myself needing to set up a local copy of a WordPress site. Usually, to do local development of a custom plugin or WordPress API integration. The issue is that I’m not constantly doing it, so I usually forget one of the steps, resulting in me having to re-solve a problem I had already solved in the past. Finally, I’m going to document the whole thing on my site so I can have one place to go back to with all the steps.

Instructions

  1. Download a copy of your site. Thankfully, most hosts will offer downloadable backups of your WordPress site. Even better, this backup tends to include the SQL backup and the full directory contents.
  2. Create a new directory on your drive where you can host the Docker and WordPress files.
    • Note: It is probably best not to set up this directory anywhere you sync data with a cloud provider. WordPress directories can be massive, so no need to sync that with iCloud or Dropbox.
  3. Place the below Docker composer file in the directory; you may have to edit the ports to open ones within your Docker environment. Once placed, run docker compose up -d to start the containers.
services:
  wordpress_db:
    image: mysql:latest
    volumes:
      - wordpress_db:/var/lib/mysql # Volume for Docker to store MySQL Data
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root_pass
      MYSQL_DATABASE: db_name
      MYSQL_USER: db_user
      MYSQL_PASSWORD: db_pass
    ports:
      - "3308:3306" # Port format "<Local Machine>:3306" 3306 being the in container port for MySQL
  wordpress:
    depends_on:
      - wordpress_db
    image: wordpress:latest
    volumes:
      - ./wordpress_data:/var/www/html
    ports:
      - "8008:80" # Custom port for Wordpress site
    restart: always
    environment:
      WORDPRESS_DB_HOST: wordpress_db # Will hookup host with wordpress_db container
      WORDPRESS_DB_USER: db_user
      WORDPRESS_DB_PASSWORD: db_pass
      WORDPRESS_DB_NAME: db_name
volumes:
  wordpress_db: {}
  wordpress_data: {}
  1. Unzip the backup, and place the WordPress main directory (the directory with the wp-config.php, etc., files) inside a directory called wordpress_data within your working directory.
  2. Open your SQL backup in a good text editor. You could use VIM or something else, but I tend to use BBEdit for these edits as it can quickly find and replace on large files.
  3. Do a complete find and replace on the main domain for the WordPress site you are recreating. I tend to do the following replacements:
https://<domain>/ -> http://localhost:<docker port>
<domain> -> localhost:<docker port>
  1. Import your SQL file with your choice of SQL editors or via the terminal.
  2. Update your wp-config.php file to replace all the define calls with the below, which references your Docker compose file:
// a helper function to lookup "env_FILE", "env", then fallback
if (!function_exists('getenv_docker')) {
	// https://github.com/docker-library/wordpress/issues/588 (WP-CLI will load this file 2x)
	function getenv_docker($env, $default) {
		if ($fileEnv = getenv($env . '_FILE')) {
			return rtrim(file_get_contents($fileEnv), "\r\n");
		}
		else if (($val = getenv($env)) !== false) {
			return $val;
		}
		else {
			return $default;
		}
	}
}

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

/** Database username */
define( 'DB_USER', getenv_docker('WORDPRESS_DB_USER', 'example username') );

/** Database password */
define( 'DB_PASSWORD', getenv_docker('WORDPRESS_DB_PASSWORD', 'example password') );

/**
 * Docker image fallback values above are sourced from the official WordPress installation wizard:
 * https://github.com/WordPress/WordPress/blob/1356f6537220ffdc32b9dad2a6cdbe2d010b7a88/wp-admin/setup-config.php#L224-L238
 * (However, using "example username" and "example password" in your database is strongly discouraged.  Please use strong, random credentials!)
 */

/** Database hostname */
define( 'DB_HOST', getenv_docker('WORDPRESS_DB_HOST', 'mysql') );

/** Database charset to use in creating database tables. */
define( 'DB_CHARSET', getenv_docker('WORDPRESS_DB_CHARSET', 'utf8') );

/** The database collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', getenv_docker('WORDPRESS_DB_COLLATE', '') );
  1. Now visit your new WordPress container, and your site should load mostly intact!

Troubleshooting

define('WP_HOME','http://localhost:8008');
define('WP_SITEURL','http://localhost:8008');