A Docker setup for WordPress theme development.
-
Clone this repo next to the theme/project folder:
cd path/to/project git clone https://github.com/Denman-Digital/wp-theme-docker.git docker # the folder name "docker" is optional
This should give you a folder structure like this:
project/ └─┬ docker/ └ theme/
Make sure that your theme folder is either named
theme, or you update the volumes in the docker-compose file.. You'll also want to make sure that the path that it is being mapped to matches the eventual server path for the theme.Typically, since we version control the plugins too, the folder structure actually usually looks like:
project/ └─┬ docker-project/ └ app-project/ └─┬ themes/project-theme/ ├ plugins/ └ mu-plugins/with the following volumes set up:
wp: volumes: - ../app-project/themes:/var/www/html/wp-content/themes - ../app-project/plugins:/var/www/html/wp-content/plugins - ../app-project/mu-plugins:/var/www/html/wp-content/mu-plugins
-
Set up local and prod URLs in
docker-compose.yml(Optional)services: wp: environment: PROD_URL: "https://project.ca" DEV_URL: "http://localhost:8000"
This is only required to enable the use of the some of the included scripts, for importing the database (
npm run db:restore), replacing stored production/staging URLs (npm run db:devify), and doing our darnedest to turn off local SSL (npm run wp:no-ssl) -
Set up compose project name in
.env(Optional)COMPOSE_PROJECT_NAME=project -
Build & start the docker containers:
cd docker # THEN docker compose up # OR npm start # alias
-
(Optional, but recommended). Delete the
.gitfolder.
This is just a starting point for a development environment. You'll probably need or want to tweak it for each project, or even each user. Changes you make are probably going to be project-specific and wont need to be pushed upstream, and changes upstream are likely not necessary to pull down, especially if it's already working for you.
That's it. (so far)
The dev site will be served at localhost:8000. A database admin GUI is available at localhost:8080.
NOTE: If there isn't a folder named
/appwith an existing WordPress install, docker will create one.
There are 4 bash scripts included to help get a dev environment up and running.
All scripts require that the containers be up and running when they are called.
npm run db:restore $file
# - OR -
bash ./bin/restore_db.sh $file$file must be the path to an sql file. Typically this is stored in the /data folder:
npm run db:restore ./data/export.sqlThis script will replace the current db with the contents of a database SQL dump, then search and replace the production URL with a local development URL as defined by the PROD_URL and DEV_URL environment variables respectively. These variables are set in docker-compose.yml and must be quoted strings.
| Variable | Default Value |
|---|---|
PROD_URL |
"https://project1.com" |
DEV_URL |
"http://localhost:8000" |
NOTE: if you want to set up a different local url, update this to match.
npm run wp:plugins
# - OR -
bash ./bin/plugins.shThis script will uninstall Hello Dolly, deactivate any production specific plugins (as defined in by the PROD_PLUGINS environment variable), and install and activate any development specific plugins (as defined in by the DEV_PLUGINS environment variable). These variables are set in docker-compose.yml and should be quoted strings with space-separated plugin IDs.
| Variable | Default Value |
|---|---|
PROD_PLUGINS |
"better-wp-security really-simple-ssl breeze" |
DEV_PLUGINS |
"debug-bar debug-bar-actions-and-filters-addon health-check" |
npm run wp:no-ssl
# - OR -
bash ./bin/no-ssl.shThis script does its best to turn off SSL when developing locally, as it is a huge pain to set up in a local environment, and generally not worth it.
It runs a search/replace for any https:// URLs in the database, turns off the Really Simple Security plugin (formerly Really Simple SSL), and sets a number of FORCE_SSL flags in wp-config.php
npm run db:devify
# - OR -
bash ./bin/devify.shThis script runs the last part of the DB Restore script, a search/replace replacing instances of the PROD_URL with the DEV_URL as set in the docker-compose.yml.
The following are some helpful commands for working with the Docker containers. Your docker containers may have different names, in which case you can use the docker ps command to see any currently running docker containers.
The WordPress Command Line Interface is installed on the Apache container. To access it, you can use the following script:
npm run db:bashNOTE: This is just an alias for this command
docker exec -it --user=dev project_wp_1 bashWhere
project_wp_1is the container name, as generated from theCOMPOSE_PROJECT_NAMEvariable in the .env file.
This starts an interactive bash session in the container as the "dev" user, which will stop WP-CLI from chastising you for running it as the root user.
For example, the wp-sync-db plugin sometimes breaks when WP_DEBUG is enabled and — as this is a development environment — WP_DEBUG is enabled by default. Either you can stop the servers and change the settings in docker-compose.yml, or just disable it from the command line:
$ npm run wp:bash
dev@<container id> wp config set WP_DEBUG false --raw
# later...
dev@<container id> wp config set WP_DEBUG true --rawNOTE: Actually don't use WP-CLI for this specific use-case, WP_DEBUG is set on the fly from the
WP_DEBUGenvironment variable. Change that from the command line withdev@<container id> $WP_DEBUG = 0 # for false, 1 for true
In the event you need to fiddle around in the database manually, you can use Adminer by going to localhost:8080 or you can execute SQL from the command line by accessing the database container much like above:
$ docker exec -it project_db_1 mysql -p
Enter password:This has also been aliased to:
$ npm run db:mysqlFor either method, the MySQL root user password is set in docker-compose.yml and defaults to admin, and the database name is wordpress.
You may find you need to rebuild your containers if things go pear-shaped:
docker compose up --force-recreate --build
# OR
npm run rebuild # aliasIf you need to tear down everything, do the following first:
docker compose down
# OR
npm run teardown # aliasIf you need to burn everything down to the ground, including the database:
docker compose down --volumesYou can get a reminder of this command by running npm run burndown