This project provides local development environments for developing WordPress websites. This includes pre-configured Docker-based MySQL and PHP servers, our Docker-Build toolchain and a number of helper scripts.
To update an existing project or start a new one, run the following commands in your working directory.
docker run --rm -it -v ${PWD}:/usr/src/site ideasonpurpose/wordpress:0.7.15 init
npm run bootstrap
NOTE: If ~/.composer dosn't exist, Docker will create it with root ownership causing the Composer task to fail. Either create this directory before running npm run bootstrap or reset it's ownership with sudo chown -R $UID:$GID .composer and then run bootstrap again. See #21
docker run --rm -it -v %cd%:/usr/src/site ideasonpurpose/wordpress:0.7.15 init
npm run bootstrap
The init command copies all the necessary tooling files into place and sets up the default theme directory structure. Then npm run bootstrap prepares the environment by installing npm and composer dependencies and reloading the database.
Docker and npm (node.js) should be installed. The development server runs from Docker images and all workflow commands are called from npm scripts.
In an empty directory, running init will prompt for the new project's name and description, then build out a complete environment with a basic theme skeleton.
For existing projects, running init reads the project's name and description from package.json, updates build tools and script commands to the latest versions and syncs in any missing theme files. The project should be a working Git checkout so any undesirable changes can be easily reverted.
- Docker-compose files will be updated to the latest versions.
- Default package.json scripts will be merged onto existing scripts.
- DevDependencies, Scripts and Prettier properties will be copied onto existing package.json values.
- Default composer.json packages and metadata will be copied onto existing composer.json values.
- Update .gitignore from gist
- Basic theme folder-structure will be non-destructively refreshed with missing folders added.
- Missing ideasonpurpose.config.js files will be created.
- Permissions will be reset for the theme directory and known tooling files.
Before calling npm run start, copy a database snapshot into the top-level _db directory, add any required plugins to Plugins and mirror media files to Uploads.
Plugins and Uploads folders should not be committed to Git, but should be mirrored from production sites so the local environment works as expected.
After configuring your SSH key path in .env, the database, plugins and uploads be can be synced down from a remote server with the npm run pull command. The .env.sample file documents the required credentials.
Copy your MySQL database dumpfiles into before calling Calling npm run start will tell the MySQL Docker image to load all *.sql files from the top-level _db directory in alphabetical order. Later files will overwrite earlier ones.
-
npm run start
Spins up a database and php server, then serves all content through the devServer proxy at http://localhost:8080. Files in the project directory will be watched for changes and trigger reloads when saved. Type control-c to stop the local server. -
npm version [major|minor|patch]Increments the version then uses version-everything to update project files before callingnpm run buildwhich generates a production build and compresses all theme files into a versioned, ready-to-deploy zip archive.
bootstrap
A helper script for starting projects. This will install npm and composer dependencies, reload the MySQL database, activate the development theme and sort the package.json file.build- Generate a production-ready build in a zip archive. Ready-to-deploy.composer
Runscomposer installfrom Docker.composer:install- Installs packages from the composer.lock filecomposer:require- Add new packages and update composer.jsoncomposer:update- Updates composer dependencies to their newest allowable version and rewrites the composer.lock file.
mysql
Opens a mysql shell to the development WordPress databasemysql:dump,mysqldump- Writes a compressed, timestamped database snapshot into the _db directorymysql:reload- Drops, then reloads the database from the most recent dumpfile in _db then attempts to activate the development theme.
phpmyadmin- Starts a phpMyAdmin server at localhost:8002pull
Syncs data from a remote server to the local development environment. The bare command will run these sub-commands:pull:db- Syncs down the most recent mySQL dumpfile, backs up the current dev DB then reloads the DBpull:plugins- Syncs down wp-content/plugins from the remotepull:uploads <$YEAR>- Syncs down the current year's wp-content/uploads/$YEAR from the remote. Sync specific years with the optional year argument.pull:uploads-all- Syncs down the entire wp-content/uploads directory from the remote
logs:wordpress- Stream the WordPress debug.logwp-cli- Runs wp-cli commands. The default command re-activates the development theme.
The npm run pull command brings together several sub-commands to sync remote data to the local development environment. Each command can also be called individually. Connection info needs to be configured in a .env file. Values are documented in the .env.sample file.
Private SSH keys are passed to the image as Docker Secrets, point $SSH_KEY_PATH to a local private key in .env.
Pulling uploads, plugins and database dumps is currently supported on WP Engine and Kinsta.
Connections must be configured on a per-machine basis using a .env file in the project root. For new projects, rename the .env.example to .env and update the settings.
The important properties are:
-
SSH_KEY_PATH
Local path to your private key. If you uploaded aid_rsa_wpengine.pubkey to your WP Engine account, point this to the pair's matching private key:~/.ssh/id_rsa_wpengine -
SSH_LOGIN
This is simply the SSH connection string from WP Engine backend, something likeiop001@iop001.ssh.wpengine.netwhere the elements are${SSH_USER}@${SSH_HOST}. Each item can also be entered indivudally, individual entries take precedence over components extracted from SSH_CONNECT_STRING. -
SSH_USER
The user account which connects to the server. -
SSH_HOST
The server address to connect to. -
SSH_WP_CONTENT_DIR
(default: sites/${SSH_USER}/wp-content) The path to the wordpress wp-content folder. Most likley matches theWP_CONTENT_DIRWordPress constant. Does not include a trailing slash. Can relative to the SSH user home folder or an absolute path.
Both $SSH_LOGIN and $SSH_HOST can be extracted from $SSH_LOGIN. Specifying either will override the value in $SSH_LOGIN.
WP_DEBUG is enabled by default, and can be toggled by setting the WORDPRESS_DEBUG variable in the .env config file.
Projects often rely on plugins which are developed in parallel. Two placeholder environment variables can be used to directly mount plugins into the WordPress environment. This enables better version control and dependency management since the nested and .gitignored wp-content/plugins directory often conflicts with the parent theme.
DATA_MODEL_PLUGINBLOCKS_PLUGIN
To open a shell on any running Docker container, run docker ps to retrieve container IDs or Names, then run docker exec -it <name or ID> bash. Some containers may use sh instead of bash. To open a shell on the running WordPress instance, run docker-compose exec wordpress bash.
The Composer image can also run other, more specific commands directly from docker-compose:
docker-compose -f docker-compose.yml -f docker-compose-util.yml run --rm composer update
docker-compose -f docker-compose.yml -f docker-compose-util.yml run --rm composer require monolog/monolog
# Open a shell in the composer image
docker-compose -f docker-compose.yml -f docker-compose-util.yml run --rm composer bashnote: This no longer works for npm versions >v6. See #29
Webpack devserver runs on port 8080 by default. Multiple projects can be run simultaneously by using npm config to assign different ports the the project's package.json name. For example, three projects named csr-site, pro-bono and ar-project could be run simultaneously on custom ports, after running these commands:
npm config set csr-site:port 8080
npm config set pro-bono:port 8081
npm config set ar-project:port 8082A PHP Info page is available at localhost:8080/info.php.
The default command replaces the wp prefix, so alternate commands would look like this:
npm run wp-cli transient delete --allnpm run wp-cli user list
To iterate on this project locally, build the image using the same name as the Docker Hub remote. Docker will use the local copy. Specify dev if you're using using versions.
docker build . --tag ideasonpurpose/wordpress:devThis project's Dockerfile is based on the official WordPress image. We add Xdebug, the ImageMagick PHP extension, SSH and enable all PHP debug settings.
This project uses or builds from the following docker images:
- composer:2.1.6
- mariadb:10.6.4
- phpmyadmin:5.1.1
- wordpress:5.8.0-php7.4-apache
- wordpress:cli-2.5.0-php7.4
- ideasonpurpose/docker-build:0.9.5
All shell scripts in bin have been checked with ShellCheck and formatted with shfmt via Docker:
docker run --user "$UID" --rm -it -v "$PWD":/scripts peterdavehello/shfmt:latest shfmt -i 2 -w /scripts/bin/<FILE>.shWhile not specific to this project, here are a few useful docker commands for keeping Docker running.
docker-compose downtears down the containersdocker system pruneClean up unused containers and imagesdocker system prune -aClean everything, will need to download stuff againdocker psList running containersdocker exec -it <container> bashOpen a shell on a running container
The docker-entrypoint.sh script in the base WordPress docker image checks for a WordPress installation by checking for index.php and wp-includes/version.php.