- Requirements
- Environment setup
- Use the environment
- Import an existing WP site
- WP Cli
- Fix permission problem
- Nginx
- SSL
- PhpMyAdmin
- MySQL dump
To use this environment you need Docker an Docker compose installed.
You can find all the settings in the .env file in the root folder of this repository. The default settings are:
Label | Required | Default | Description |
---|---|---|---|
ENV |
yes |
PROD |
Valid values are: PROD or DEV. Changing this varialbe the environment will use a different WP image. In DEV environment is used the docker image with embadded Apache, in prod env is used the php-fpm docker image |
WORDPRESS_IMAGE |
yes |
wordpress |
The default docker image to use. |
WORDPRESS_PROD_VERSION |
yes |
php7.4-fpm |
Production docker image version (php-fpm) |
WORDPRESS_DEV_VERSION |
yes |
php7.4 |
Development docker image version (embadded apache) |
WORDPRESS_CLI_VERSION |
yes |
cli-php7.4 |
WP client docker image version |
WORDPRESS_DB_NAME |
no |
wordpress |
WP database name |
WORDPRESS_TABLE_PREFIX |
no |
wp_ |
WP mysql table prefix |
WORDPRESS_DB_HOST |
no |
myslq |
MySQL container name |
WORDPRESS_DB_USER |
no |
wordpress |
MySQL WP user |
WORDPRESS_DB_PASSWORD |
no |
password |
MySQL WP user |
MARIADB_VERSION |
no |
latest |
MariaDB container version |
MYSQL_ROOT_PASSWORD |
no |
s3cretPassW0rd |
Development docker image version (embadded apache) |
MYSQL_DATA_DIR |
no |
./wordpress-sql |
Local path for MySQL backup/restore |
MYSQL_DUMP_DIR |
no |
./mysql-dumps |
Local where dump_mysql.sh store the MySQL dumps |
NGINX_VERSION |
no |
latest |
Nginx container version |
SERVER_NAME |
yes |
example.com |
Second level domain name (Example: example.com) |
SERVER_ALT_NAME |
yes |
www.example.com |
Third level domain name (Example: www.example.com) |
WP_CONTAINER_NAME |
yes |
wordpress |
WP container name (defined in docker-compose.yml) |
SECURE_SUBNET |
no |
192.168.0.0/16 |
Secure subnet to allow traffic to wp-admin, wp-login.php and xmlrpc.php |
NGINX_CONF_DIR |
no |
./config/nginx/cfg/ |
Nginx custom configuration path |
NGINX_TEMPLATE_DIR |
no |
./config/nginx/tpl/ |
Nginx template configuration path |
WORDPRESS_UID |
no |
1000 |
UID of the user running docker |
WORDPRESS_GID |
no |
1000 |
GID of the user running docker |
WORDPRESS_USER |
no |
app |
Username used inside the WP docer container |
WORDPRESS_GROUP |
no |
app |
Group assigned to WORDPRESS_USER |
CUSTOM_WORDPRESS_IMAGE |
no |
my-wordpress |
WP custom docker image name |
If you would like to use this environment for local test or if you are developing a new plugin or theme you have to use the develompment version. To use this version create a symlink from docker-compose-dev.yml to docker-compose.yml
ln -s docker-compose-dev.yml docker-compose.yml
and change in the .env file the ENV value to DEV:
ENV=DEV
you can now start the environment with:
docker compose up -d
you can check the logs with:
docker compose logs -f
Now you have:
- wordpress listening on port 80 (with embadded Apache). Access your wordpress on http://localhost
- PhpMyAdmin listening on port 8080. Access PMA on http://localhost:8080 (see PhpMyAdmin section)
- MySQL running but is not listening on any interface
- Wordpress CLI container available (see WP Cli section)
If you are developing a new theme or plugin is possible that you're facing a permission problem, if you check the files permission under wordpress-src you see that the files are owned by www-data:
drwxr-xr-x 5 www-data www-data 4096 Oct 12 15:34 wordpress-src
To fix this issue see the "Fix permission problem" section
If you are ready to spin up a production environment simply create a symlink from docker-compose-prod.yml to docker-compose.yml:
ln -s docker-compose-prod.yml docker-compose.yml
and check in the .env file that the ENV variable is set to PROD:
ENV=PROD
On production environment you have to configure also nginx. To do so, check the environment variables attached to the nginx container.
The environment variables are:
- SERVER_NAME: Second level domain name (Example: example.com)
- SERVER_ALT_NAME: Third level domain name (Example: www.example.com)
- WP_CONTAINER_NAME: WP container name (defined in docker-compose.yml)
- SECURE_SUBNET: Secure subnet to allow traffic to wp-admin, wp-login.php and xmlrpc.php (Default 192.168.0.0/16)
you can now start the environment with:
docker compose up -d
you can check the logs with:
docker compose logs -f
Now you have:
- nginx listening on ports 80 and 443 (optional). (see nignx section)
- wordpress running with php-fpm container
- PhpMyAdmin running, traffic to PhpMyAdmin is filtered by nginx (see PhpMyAdmin section)
- MySQL running but is not listening on any interface
- Wordpress CLI container available (see WP Cli section)
If you have a running WP site and you want to use this environment you have to extract your existing sources in wordpress-src directory and the MySQL dump in wordpress-sql directory.
NOTE before spin up the environment, check wordpress-src directory permission. If you have build a custom image remember to:
chown -R uid:gid wordpress-src/
if you use the standard wordpress image all files and directory must be owned by user and group (www-data). Your system might be have a different uid and git for the www-data user and group (or you might don't have this user and group), so to fix the permission problem use the uid and gid directly:
chown -R 33:33 wordpress-src/
MySQL NOTE dump can be in plain text or gzipped. The extension must be *.sql or *.gz
MySQL NOTE2 dump will be restored only on the first startup. If you want to restore a new dump you have to:
- stop mysql container (docker-compose stop mysql)
- remove the mysql volume (docker volume rm wordpress-docker_mysql). Tip you can find the volume name with: docker volume ls.
- place the new dump in wordpress-sql
- start the container (docker-compose up -d)
Check the Wordpress Client referenche here
To use the wordpress CLI use for example:
docker-compose run --rm wordpress-cli wp core install --url=http://localhost --title=test --admin_user=admin [email protected]
Creating wordpress-docker_wordpress-cli_run ... done
Admin password: &kWu5@BldBHixvvaim
Warning: Unable to create directory wp-content/uploads/2021/10. Is its parent directory writable by the server?
Success: WordPress installed successfully.
To fix the permission problem the solution is to build a custom image. This image will then run all the processes inside the container with a user with a user with the same uid and gid of your local computer's user.
First we need to check our uid and gid (use the id command):
id
uid=1000(your-local-user) gid=1000(your-local-group) groups=1000(your-local-group),4(adm),24(cdrom),27(sudo)
then in the .env file adjust the variables:
- WORDPRESS_UID
- WORDPRESS_GID
with your uid and gid. Now we can build our custom image:
bash build.sh
this will produce two new images, one for wordpress (my-wordpress:php7.4) and one for the wordpress cli (my-wordpress:cli-php7.4). A sample output will be:
Step 4/10 : ARG WORDPRESS_UID
---> Using cache
---> 7eb312bf432b
Step 5/10 : ARG WORDPRESS_GID
---> Using cache
---> 917ace616147
Step 6/10 : ARG WORDPRESS_USER
---> Using cache
---> aad8c3c33e3a
Step 7/10 : ARG WORDPRESS_GROUP
---> Using cache
---> 14248a4f8db9
Step 8/10 : COPY ./adduser.sh /
---> Using cache
---> 255a4a665ac6
Step 9/10 : RUN /adduser.sh && rm -rf /adduser.sh
---> Using cache
---> 8e84c8cce8b2
Step 10/10 : USER ${WORDPRESS_USER}
---> Using cache
---> d36fbaf33c9e
Successfully built d36fbaf33c9e
Successfully tagged my-wordpress:cli-php7.4
Now to use this new image you have to change the WORDPRESS_IMAGE in the .env file:
WORDPRESS_IMAGE=my-wordpress
Now stop the environment, fix wordpress-src directory permission and bring up the environment with the new image:
docker-compose down
sudo chown -R your-local-user:your-local-group wordpress-src
[sudo] password for your-local-user:
docker-compose up -d
NOTE you can change the custom image name by editing the .env file and change the CUSTOM_WORDPRESS_IMAGE variable.
By default Nginx will expose only the http port (port 80). The default configuration is config/nginx/tpl/nginx-http.conf.template. This template will be rendered on every nginx startup. For more information the nignx documentation is available here
By default this template use many security enhancements, removing access to many WP paths and files. You can find the configurations under: config/nginx/cfg/
To disable this security enhancements edit the config/nginx/tpl/nginx-http.conf.template and comment or delete the lines:
# Security
include /etc/nginx/custom.conf.d/nginx-custom-configs.conf;
include /etc/nginx/custom.conf.d/nginx-wp-hardening.conf;
In the default template the following locations are protected:
- /pma/ (PhpMyAdmin)
- /xmlrpc.php
- /wp-admin/
- wp-login.php
The traffic to this location is filtered by the SECURE_SUBNET environment variable (Default 192.168.0.0/16). Only the client in this subnet will be able to access this locations.
To disable this filter edit the config/nginx/tpl/nginx-http.conf.template file and comment or delete this lines:
allow ${SECURE_SUBNET};
allow 127.0.0.1;
deny all;
A configuration example is placed on config/nginx/tpl/nginx-https.conf.example to enable SSL rename this file with the .template extension.
Note remember to delete or rename the nginx-http.conf.template
Uncomment certbot service in docker-compose.yml
If you have to create a new SSL certificate, modify init_letsencrypt.sh with your domain(s) name(s) and change the email variable. Require the new certificate with:
bash init_letsencrypt.sh
for nginx auto reload, uncomment the command on the nginx service. This is necessary for auto reload nginx when certot renew the ssl certificates.
Now restart nginx and certbot:
docker-compose up -d
If you have your own SSL certificate modifiy config/nginx/tpl/nginx-https.conf.example and adjust the nginx volumes in docker-compose.yml.
Note remember to rename config/nginx/tpl/nginx-http.conf.example file with the .template extension.
You can now start the services with:
docker-compose up -d
The default username is root, and the password is the value of MYSQL_ROOT_PASSWORD in the .env file
You can access phpMyAdmin at http://127.0.0.1:8080
You can access phpMyAdmin at http://example.com/pma (access filtered by ip)
To dump the current MySQL state you can use the dump.sh file. The dump will be saved in mysql-dumps directory (you can customize the dump directory in the .env file)
bash dump_mysql.sh
ls -la mysql-dumps/
-rw-rw-r-- 1 lorenzo lorenzo 473 Oct 18 12:21 wordpress.20211018122109.gz
-rw-rw-r-- 1 lorenzo lorenzo 299673 Oct 18 12:22 wordpress.20211018122247.gz