Skip to content

Instantly share code, notes, and snippets.

@emschu
Last active March 25, 2022 20:29
Show Gist options
  • Save emschu/b966161783563841cb0dd8fcdfe1340f to your computer and use it in GitHub Desktop.
Save emschu/b966161783563841cb0dd8fcdfe1340f to your computer and use it in GitHub Desktop.
Wordpress Plugin Development Docker Container with wp-cli

Wordpress Plugin Development Docker Image with wp-cli

Use flexible docker development containers for WP Plugin development by using wp-cli to automate setup instructions and use reproducible environments

Your local plugin directory will be mounted as a volume, so your code changes are available immediately.

This container is a non-root container by default.

The following files help you to generate a fresh wordpress installation with admin:password (Mail: test@test.local) as initial login credentials and some common debug options enabled. Wordpress container port is expected to be 8000 on your container host.

You'll need a unique plugin name/slug and you replace <your-plugin-name> in the following files with it. Copy and modify the following files into a directory and add create a new directory with the value of <your-plugin-name>. The latter directory is the one where your plugin code is residing and needs to follow common WP plugin development rules. Best solution: Keep all this in a VCS, like git.

NOTE: If you uninstall your plugin, your local directory will be deleted! Make sure to commit your code changes BEFORE uninstalling it.

Usage

  • Pull (MariaDB) and Build (WP Image): docker-compose pull, docker-compose build
  • Start up in foreground with docker-compose up or start it in background by appending -d
  • Stop all: docker-compose down
  • Remove all persistent storage (Maria DB contents): docker-compose down --volumes
  • Sometimes useful: docker-compose up --force-recreate and --remove-orphans
  • If you change the contents of wp-entrypoint.sh you'll need to rebuild the image.
  • After the first start the container needs 10 + 5 + x seconds for provisioning with wp-cli

Site URL: http://127.0.0.1:8000

Backend URL: http://127.0.0.1:8000/wp-admin

Dockerfile

At least you should replace "" in the following template with your plugin slug.

FROM wordpress:latest

# installing wp-cli and mysql client
RUN apt-get update; apt-get install --no-install-recommends -y libcap2-bin mariadb-client-10.3 less bash dos2unix vim; rm -rf /var/lib/apt/lists/*; \
 curl -o /bin/wp-cli.phar https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar; \
 chmod +x /bin/wp-cli.phar; \
 mv /bin/wp-cli.phar /usr/local/bin/wp; \
 # create a user of group www-data (apache web server user)
 useradd -m -g www-data wordpresser

# allow apache2 web server to bind to privileged port as non-root user
# and set proper permissions for wordpress directory for file system changes
RUN setcap 'cap_net_bind_service=+ep' /usr/sbin/apache2; chown -R wordpresser:www-data /usr/src/wordpress
COPY wp-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/wp-entrypoint.sh; chown wordpresser:www-data /usr/local/bin/wp-entrypoint.sh; \
    dos2unix /usr/local/bin/wp-entrypoint.sh; mkdir -p /var/www/<your-plugin-name>;

VOLUME /var/www/<your-plugin-name>

USER wordpresser
WORKDIR /var/www/html

ENTRYPOINT ["wp-entrypoint.sh"]

wp-entrypoint.sh

Feel free to add your own wp-cli instructions to this script, but ensure the exit code of your command is 0. Replace <your-plugin-name> in this script.

#!/bin/bash
set -euo pipefail

# NOTE: If you change this file, the wordpress container needs to be rebuilt

# run default wordpress entrypoint script
bash /usr/local/bin/docker-entrypoint.sh apache2-foreground &
# "wait" for the other script's finish. Note: the previous script does not terminate.
sleep 10

echo "Basic setup started. Starting custom WP Setup"

# variables
WP_PATH="/var/www/html"

# setup routine
wp --info
wp core config --path="$WP_PATH" --dbname=wordpress --dbuser=wordpress --dbpass=wordpress --dbhost=db \
  --dbprefix=dev_db_ \
  --skip-check --force --extra-php <<PHP
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
PHP

wp core install --path="$WP_PATH" --url="http://127.0.0.1:8000" --title="My Development Plugin" --admin_user=admin --admin_password=password --admin_email="test@test.local"
#wp option update timezone_string "Europe/Paris"

wp config set DISABLE_WP_CRON true || true

# remove all plugins
wp plugin list

wp plugin deactivate --quiet akismet hello || true
wp plugin delete --quiet akismet hello || true
wp maintenance-mode deactivate || true

# install and activate woocommerce plugin
#wp plugin install --activate woocommerce
wp plugin install --activate debug-bar
wp plugin install --activate debug-bar-cron
wp plugin install --activate wp-mail-logging
wp plugin install --activate wp-crontrol

# link plugin to wp-content/plugins
if [ ! -L /var/www/html/wp-content/plugins/<your-plugin-name> ]; then
  echo "creating symlink dir for plugin development"
  ln -s /var/www/<your-plugin-name>/ /var/www/html/wp-content/plugins/<your-plugin-name>
fi
# .. and activate it
wp plugin activate <your-plugin-name> || true

# set proper theme
# wp theme install --activate shophistic-lite

# Trap Ctrl-c
trap terminate INT

function terminate() {
  echo "Exiting now."
  exit 0
}
echo "Running forever (press Ctrl-C to leave) ..."
while(true); do
  sleep 5
done

docker-compose.yml

Replace <your-plugin-name>.

version: '3.3'

services:
   db:
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     build: .
     depends_on:
       - db
     ports:
       - "8000:80"
     restart: always
     volumes:
       - ./<your-plugin-name>/:/var/www/<your-plugin-name>/:rw
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
       WORDPRESS_DB_NAME: wordpress
volumes:
    db_data: {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment