wp-env lets you easily set up a local WordPress environment for building and testing plugins and themes. It’s simple to install and requires no configuration.
Quick (tl;dr) instructions
Ensure that Docker is running, then:
$ cd /path/to/a/wordpress/plugin
$ npm -g i @wordpress/env
$ wp-env start
The local environment will be available at http://localhost:8888 (Username: admin, Password: password).
The database credentials are: user root, password password. For a comprehensive guide on connecting directly to the database, refer to Accessing the MySQL Database.
Prerequisites
wp-env relies on a few commonly used developer tools:
- Docker.
wp-envis powered by Docker. There are instructions available for installing Docker on Windows (we recommend the WSL2 backend), macOS, and Linux. - Node.js.
wp-envis written as a Node script. We recommend using a Node version manager like nvm to install the latest LTS version. Alternatively, you can download it directly here. - git. Git is used for downloading software from source control, such as WordPress, plugins, and themes. You can find the installation instructions here.
Installation
Installation as a global package
After confirming that the prerequisites are installed, you can install wp-env globally like so:
$ npm -g i @wordpress/env
You’re now ready to use wp-env!
Installation as a local package
If your project already has a package.json, it’s also possible to use wp-env as a local package. First install wp-env locally as a dev dependency:
$ npm i @wordpress/env --save-dev
If you have also installed wp-env globally, running it will automatically execute the local, project-level package. Alternatively, you can execute wp-env via npx, a utility automatically installed with npm.npx finds binaries like wp-env installed through node modules. As an example: npx wp-env start --update.
If you don’t wish to use the global installation or npx, modify your package.json and add an extra command to npm scripts (https://docs.npmjs.com/misc/scripts):
"scripts": {
"wp-env": "wp-env"
}
When installing wp-env in this way, all wp-env commands detailed in these docs must be prefixed with npm run, for example:
# You must add another double dash to pass flags to the script (wp-env) rather than to npm itself
$ npm run wp-env start -- --update
instead of:
$ wp-env start --update
Usage
Starting the environment
First, ensure that Docker is running. You can do this by clicking on the Docker icon in the system tray or menu bar.
Then, change to a directory that contains a WordPress plugin or theme:
$ cd ~/gutenberg
Then, start the local environment:
$ wp-env start
Finally, navigate to http://localhost:8888 in your web browser to see WordPress running with the local WordPress plugin or theme running and activated. Default login credentials are username: admin password: password.
Stopping the environment
To stop the local environment:
$ wp-env stop
Troubleshooting common problems
Many common problems can be fixed by running through the following troubleshooting steps in order:
1. Check that wp-env is running
First, check that wp-env is running. One way to do this is to have Docker print a table with the currently running containers:
$ docker ps
In this table, by default, you should see three entries: wordpress with port 8888, tests-wordpress with port 8889 and mariadb with port 3306.
2. Check the port number
By default wp-env uses port 8888, meaning that the local environment will be available at http://localhost:8888.
You can configure the port that wp-env uses so that it doesn’t clash with another server by specifying the WP_ENV_PORT environment variable when starting wp-env:
$ WP_ENV_PORT=3333 wp-env start
Running docker ps and inspecting the PORTS column allows you to determine which port wp-env is currently using.
You may also specify the port numbers in your .wp-env.json file, but the environment variables will take precedence.
3. Restart wp-env with updates
Restarting wp-env will restart the underlying Docker containers which can fix many issues.
To restart wp-env, just run wp-env start again. It will automatically stop and start the container. If you also pass the --update argument, it will download updates and configure WordPress again.
$ wp-env start --update
4. Restart Docker
Restarting Docker will restart the underlying Docker containers and volumes which can fix many issues.
To restart Docker:
- Click on the Docker icon in the system tray or menu bar.
- Select Restart.
Once restarted, start wp-env again:
$ wp-env start
5. Reset the database
Resetting the database which the local environment uses can fix many issues, especially when they are related to the WordPress installation.
To reset the database:
⚠️ WARNING: This will permanently delete any posts, pages, media, etc. in the local WordPress installation.
$ wp-env clean all
$ wp-env start
6. Destroy everything and start again 🔥
When all else fails, you can use wp-env destroy to forcibly remove all of the underlying Docker containers, volumes, and files. This will allow you to start from scratch.
To do so:
⚠️ WARNING: This will permanently delete any posts, pages, media, etc. in the local WordPress installation.
$ wp-env destroy
# This new instance is a fresh start with no existing data:
$ wp-env start
Using included WordPress PHPUnit test files
Out of the box wp-env includes the WordPress’ PHPUnit test files corresponding to the version of WordPress installed. There is an environment variable, WP_TESTS_DIR, which points to the location of these files within each container. By including these files in the environment, we remove the need for you to use a package or install and mount them yourself. If you do not want to use these files, you should ignore the WP_TESTS_DIR environment variable and load them from the location of your choosing.
Customizing the wp-tests-config.php file
While we do provide a default wp-tests-config.php file within the environment, there may be cases where you want to use your own. WordPress provides a WP_TESTS_CONFIG_FILE_PATH constant that you can use to change the wp-config.php file used for testing. Set this to a desired path in your bootstrap.php file and the file you’ve chosen will be used instead of the one included in the environment.
Using composer, phpunit, and wp-cli tools.
For ease of use, Composer, PHPUnit, and wp-cli are available for in the environment. To run these executables, use wp-env run <env> <tool> <command>. For example, wp-env run cli composer install, or wp-env run tests-cli phpunit. You can also access various shells like wp-env run cli bash or wp-env run cli wp shell.
For the env part, cli and wordpress share a database and mapped volumes, but more tools are available in the cli environment. You should use the tests-cli / tests-wordpress environments for a separate testing database.
By default, the cwd of the run command is the root of the WordPress install. If you’re working on a plugin, you likely need to pass --env-cwd to make sure composer/phpunit commands are executed relative to the plugin you’re working on. For example, wp-env run cli --env-cwd=wp-content/plugins/gutenberg composer install.
To make this easier, it’s often helpful to add scripts in your package.json file:
{
"scripts": {
"composer": "wp-env run cli --env-cwd=wp-content/plugins/gutenberg composer"
}
}
Then, npm run composer install would run composer install in the environment. You could also do this for phpunit, wp-cli, etc.
Using Xdebug
Xdebug is installed in the wp-env environment, but it is turned off by default. To enable Xdebug, you can use the --xdebug flag with the wp-env start command. Here is a reference to how the flag works:
# Sets the Xdebug mode to "debug" (for step debugging):
wp-env start --xdebug
# Sets the Xdebug mode to "off":
wp-env start
# Enables each of the Xdebug modes listed:
wp-env start --xdebug=profile,trace,debug
When you’re running wp-env using npm run, like when working in the Gutenberg repo or when wp-env is a local project dependency, don’t forget to add an extra double dash before the --xdebug command:
npm run wp-env start -- --xdebug
# Alternatively, use npx:
npx wp-env start --xdebug
If you forget about that, the --xdebug parameter will be passed to npm instead of the wp-env start command and it will be ignored.
You can see a reference on each of the Xdebug modes and what they do in the Xdebug documentation.
Since we are only installing Xdebug 3, Xdebug is only supported for PHP versions greater than or equal to 7.2 (the default). Xdebug won’t be installed if phpVersion is set to a legacy version.
Xdebug IDE support
To connect to Xdebug from your IDE, you can use these IDE settings. This bit of JSON was tested for VS Code’s launch.json format (which you can learn more about here) along with this PHP Debug extension. Its path mapping also points to a specific plugin — you should update this to point to the source you are working with inside of the wp-env instance.
You should only have to translate port and pathMappings to the format used by your own IDE.
{
"name": "Listen for XDebug",
"type": "php",
"request": "launch",
"port": 9003,
"pathMappings": {
"/var/www/html/wp-content/plugins/gutenberg": "${workspaceFolder}/"
}
}
After you create a .vscode/launch.json file in your repository, you probably want to add it to your global gitignore file so that it stays private for you and is not committed to the repository.
Once your IDEs Xdebug settings have been enabled, you should just have to launch the debugger, put a breakpoint on any line of PHP code, and then refresh your browser!
Here is a summary:
- Start wp-env with xdebug enabled:
wp-env start --xdebug - Install a suitable Xdebug extension for your IDE if it does not include one already.
- Configure the IDE debugger to use port
9003and the correct source files in wp-env. - Launch the debugger and put a breakpoint on any line of PHP code.
- Refresh the URL wp-env is running at and the breakpoint should trigger.
Command reference
wp-env creates generated files in the wp-env home directory. By default, this is ~/.wp-env. The exception is Linux, where files are placed at ~/wp-env for compatibility with Snap Packages. The wp-env home directory contains a subdirectory for each project named /$md5_of_project_path. To change the wp-env home directory, set the WP_ENV_HOME environment variable. For example, running WP_ENV_HOME="something" wp-env start will download the project files to the directory ./something/$md5_of_project_path (relative to the current directory).
wp-env start
The start command installs and initializes the WordPress environment, which includes downloading any specified remote sources. By default, wp-env will not update or re-configure the environment except when the configuration file changes. Tell wp-env to update sources and apply the configuration options again with wp-env start --update. This will not overwrite any existing content.
wp-env start
Starts WordPress for development on port 8888 (http://localhost:8888)
(override with WP_ENV_PORT) and tests on port 8889 (http://localhost:8889)
(override with WP_ENV_TESTS_PORT). The current working directory must be a
WordPress installation, a plugin, a theme, or contain a .wp-env.json file. After
first install, use the '--update' flag to download updates to mapped sources and
to re-apply WordPress configuration options.
Options:
--debug Enable debug output. [boolean] [default: false]
--update Download source updates and apply WordPress configuration.
[boolean] [default: false]
--xdebug Enables Xdebug. If not passed, Xdebug is turned off. If no modes
are set, uses "debug". You may set multiple Xdebug modes by passing
them in a comma-separated list: `--xdebug=develop,coverage`. See
https://xdebug.org/docs/all_settings#mode for information about
Xdebug modes. [string]
--spx Enables SPX profiling. If not passed, SPX is turned off. If no
mode is set, uses "enabled". SPX is a simple profiling extension
with a built-in web UI. See
https://github.com/NoiseByNorthwest/php-spx for more information.
[string]
--scripts Execute any configured lifecycle scripts. [boolean] [default: true]
wp-env stop
wp-env stop
Stops running WordPress for development and tests and frees the ports.
Options:
--debug Enable debug output. [boolean] [default: false]
wp-env clean [environment]
wp-env clean [environment]
Cleans the WordPress databases.
Positionals:
environment Which environments' databases to clean.
[string] [choices: "all", "development", "tests"] [default: "tests"]
Options:
--debug Enable debug output. [boolean] [default: false]
--scripts Execute any configured lifecycle scripts. [boolean] [default: true]
wp-env run <container> [command…]
The run command can be used to open shell sessions, invoke WP-CLI commands, or run any arbitrary commands inside of a container.
In some cases wp-env run may conflict with options that you are passing to the container.
When this happens, wp-env will treat the option as its own and take action accordingly.
For example, if you try wp-env run cli php --help, you will receive the wp-env help text.
You can get around this by passing any conflicting options after a double dash. wp-env will not process anything after
the double dash and will simply pass it on to the container. To get the PHP help text you would use wp-env run cli php -- --help.
wp-env run <container> [command...]
Runs an arbitrary command in one of the underlying Docker containers. A double
dash can be used to pass arguments to the container without parsing them. This
is necessary if you are using an option that is defined below. You can use
`bash` to open a shell session and both `composer` and `phpunit` are available
in all WordPress and CLI containers. WP-CLI is also available in the CLI
containers.
Positionals:
container The Docker service to run the command on.
[string] [required] [choices: "mysql", "tests-mysql", "wordpress",
"tests-wordpress", "cli", "tests-cli", "composer", "phpmyadmin"]
command The command to run. [required]
Options:
--debug Enable debug output. [boolean] [default: false]
--env-cwd The command's working directory inside of the container. Paths
without a leading slash are relative to the WordPress root.
[string] [default: "."]
For example:
Displaying the users on the development instance:
wp-env run cli wp user list
⠏ Running `wp user list` in 'cli'.
ID user_login display_name user_email user_registered roles
1 admin admin [email protected] 2020-03-05 10:45:14 administrator
✔ Ran `wp user list` in 'cli'. (in 2s 374ms)
Creating a post on the tests instance:
wp-env run tests-cli "wp post create --post_type=page --post_title='Ready'"
ℹ Starting 'wp post create --post_type=page --post_title='Ready'' on the tests-cli container.
Success: Created post 5.
✔ Ran `wp post create --post_type=page --post_title='Ready'` in 'tests-cli'. (in 3s 293ms)
Opening the WordPress shell on the tests instance and running PHP commands:
wp-env run tests-cli wp shell
ℹ Starting 'wp shell' on the tests-cli container. Exit the WordPress shell with ctrl-c.
Starting 31911d623e75f345e9ed328b9f48cff6_mysql_1 ... done
Starting 31911d623e75f345e9ed328b9f48cff6_tests-wordpress_1 ... done
wp> echo( 'hello world!' );
hello world!
wp> ^C
✔ Ran `wp shell` in 'tests-cli'. (in 16s 400ms)
Installing a plugin or theme on the development instance
wp-env run cli wp plugin install custom-post-type-ui
Creating 500cd328b649d63e882d5c4695871d04_cli_run ... done
Installing Custom Post Type UI (1.9.2)
Downloading installation package from https://downloads.wordpress.org/plugin/custom-post-type-ui.zip...
The authenticity of custom-post-type-ui.zip could not be verified as no signature was found.
Unpacking the package...
Installing the plugin...
Plugin installed successfully.
Success: Installed 1 of 1 plugins.
✔ Ran `plugin install custom-post-type-ui` in 'cli'. (in 6s 483ms)
Changing the permalink structure
You might want to do this to enable access to the REST API (wp-env/wp/v2/) endpoint in your wp-env environment. The endpoint is not available with plain permalinks.
Examples
To set the permalink to just the post name:
wp-env run cli "wp rewrite structure /%postname%/"
To set the permalink to the year, month, and post name:
wp-env run cli "wp rewrite structure /%year%/%monthnum%/%postname%/"
wp-env destroy
wp-env destroy
Destroy the WordPress environment. Deletes docker containers, volumes, and
networks associated with the WordPress environment and removes local files.
Options:
--debug Enable debug output. [boolean] [default: false]
--scripts Execute any configured lifecycle scripts. [boolean] [default: true]
wp-env logs [environment]
wp-env logs
displays PHP and Docker logs for given WordPress environment.
Positionals:
environment Which environment to display the logs from.
[string] [choices: "development", "tests", "all"] [default: "development"]
Options:
--debug Enable debug output. [boolean] [default: false]
--watch Watch for logs as they happen. [boolean] [default: true]
wp-env install-path
Get the path where all of the environment files are stored. This includes the Docker files, WordPress, PHPUnit files, and any sources that were downloaded.
Example:
$ wp-env install-path
/home/user/.wp-env/63263e6506becb7b8613b02d42280a49
.wp-env.json
You can customize the WordPress installation, plugins and themes that the development environment will use by specifying a .wp-env.json file in the directory that you run wp-env from.
.wp-env.json supports fields for options applicable to both the tests and development instances.
| Field | Type | Default | Description |
|---|---|---|---|
"core" |
string\|null |
null |
The WordPress installation to use. If null is specified, wp-env will use the latest production release of WordPress. |
"phpVersion" |
string\|null |
null |
The PHP version to use. If null is specified, wp-env will use the default version used with production release of WordPress. |
"plugins" |
string[] |
[] |
A list of plugins to install and activate in the environment. |
"themes" |
string[] |
[] |
A list of themes to install in the environment. |
"port" |
integer |
8888 (8889 for the tests instance) |
The primary port number to use for the installation. You’ll access the instance through the port: ‘http://localhost:8888’. |
"testsPort" |
integer |
8889 |
The port number for the test site. You’ll access the instance through the port: ‘http://localhost:8889’. |
"config" |
Object |
See below. | Mapping of wp-config.php constants to their desired values. |
"mappings" |
Object |
"{}" |
Mapping of WordPress directories to local directories to be mounted in the WordPress instance. |
"mysqlPort" |
integer |
null (randomly assigned) |
The MySQL port number to expose. The setting is only available in the env.development and env.tests objects. |