https://github.com/garutilorenzo/wordpress-docker
Full stack (LEMP) Wordpress docker environment for dev and production use
https://github.com/garutilorenzo/wordpress-docker
devops docker-compose dockerfile dokcer hacktoberfest lemp lemp-stack letsencrypt nginx phpmyadmin ssl wordpress workflow
Last synced: about 1 month ago
JSON representation
Full stack (LEMP) Wordpress docker environment for dev and production use
- Host: GitHub
- URL: https://github.com/garutilorenzo/wordpress-docker
- Owner: garutilorenzo
- License: gpl-3.0
- Created: 2021-10-12T12:55:53.000Z (almost 4 years ago)
- Default Branch: master
- Last Pushed: 2021-10-18T10:31:12.000Z (almost 4 years ago)
- Last Synced: 2025-05-04T05:46:06.343Z (5 months ago)
- Topics: devops, docker-compose, dockerfile, dokcer, hacktoberfest, lemp, lemp-stack, letsencrypt, nginx, phpmyadmin, ssl, wordpress, workflow
- Language: Shell
- Homepage:
- Size: 42 KB
- Stars: 27
- Watchers: 4
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# wordpress-docker
[](https://github.com/garutilorenzo/wordpress-docker/actions/workflows/ci.yml)
[](https://github.com/garutilorenzo/wordpress-docker/issues)

[](https://github.com/garutilorenzo/wordpress-docker/network)
[](https://github.com/garutilorenzo/wordpress-docker/stargazers)# Table of Contents
* [Requirements](#requirements)
* [Environment setup](#environment-setup)
* [Use the environment](#use-the-environment)
* [Import an existing WP site](#import-an-existing-wp-site)
* [WP Cli](#wp-cli)
* [Fix permission problem](#fix-permission-problem)
* [Nginx](#nginx)
* [SSL](#ssl)
* [Certbot/Let's encrypt](#certbotlets-encrypt)
* [Owned SSL certificates](#owned-ssl-certificates)
* [PhpMyAdmin](#phpmyadmin)
* [MySQL dump](#mysql-dump)### Requirements
To use this environment you need [Docker](https://docs.docker.com/get-docker/) an [Docker compose](https://docs.docker.com/compose/install/) installed.
### Environment setup
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](https://hub.docker.com/_/wordpress) 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 |### Use the environment
#### Development
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
#### Production
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)### Import an existing WP site
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](#fix-permission-problem) 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)### WP Cli
Check the Wordpress Client referenche [here](https://developer.wordpress.org/cli/commands/)
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 --admin_email=test@example.com
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.
```### Fix permission problem
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):
```
iduid=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_GIDwith 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.
### Nginx
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](https://hub.docker.com/_/nginx)
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.phpThe 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;
```### SSL
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
#### Certbot/Let's encrypt
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:```console
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:
```console
docker-compose up -d
```#### Owned SSL certificates
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:
```console
docker-compose up -d
```### PhpMyAdmin
The default username is root, and the password is the value of MYSQL_ROOT_PASSWORD in the .env file
#### Development
You can access phpMyAdmin at http://127.0.0.1:8080
#### Production
You can access phpMyAdmin at http://example.com/pma (access filtered by ip)
### MySQL dump
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
```