Rija Mnag
Dockerfile to create a container with Nginx and php-fpm running a Wordpress web application. TLS encryption is provided (and automatically renewed) using free certificates provided by Let's Encrypt. Page caching (using Nginx's FastCGI cache) and Opcode caching with Zend Opcache are enabled and configured.
The container can be deployed with either a vanilla installation of Wordpress or an existing Wordpress-based codebase.
The container doesn't have a database server, but the supplied docker compose file allow instantiating a MariaDB 10.2 database server on the same network as the Wordpress container.
When choosing to use an existing Wordpress-based web site, the codebase is baked into the image when the image is built, so that the deployed container is immutable, making it play nicely in a versioned deployment pipelines.
When choosing to use a vanilla installation of Wordpress, the latest wordpress software is baked at build time, and additional security and caching related plugins are installed during deployment of the container.
Headline features:
Available Docker Hub tags: v1, v2, latest
$ docker run --name a-mariadb-server \
-e MYSQL_ROOT_PASSWORD=my-secret-pw \
-e MYSQL_USER=wp_user \
-e MYSQL_PASSWORD=wp_password \
-e MYSQL_DATABASE=wp_database \
-d mariadb:10.2
$ docker run -d \
--link a-mariadb-server:dbserver \
--name a-wordpress-container \
-e SERVER_NAME=example.com \
-e [email protected] \
-e ADMIN_PASSWORD=changemenow \
-e DB_HOSTNAME=dbserver \
-e DB_USER=wp_user \
-e DB_PASSWORD=wp_password \
-e DB_DATABASE=wp_database \
-v /etc/letsencrypt:/etc/letsencrypt \
-v /${HOME}:/root/sql \
-p 443:443 -p 80:80 \
rija/docker-nginx-fpm-caches-wordpress
Notes:
The ADMIN_EMAIL
variable is used by WP-CLI for the initial setup of the Wordpress install and by Let's Encrypt's Certbot for managing TLS certificates renewal. It is also supplied alongside ADMIN_PASSWORD
to the Wordpress install associated with the admin user.
$ cd docker-nginx-fpm-caches-wordpress
$ ./make_env
$ docker-compose up -d
One can adjust the values in the .env file updated (and created if non-existent) by ./make_env
$ ansible-playbook --extra-vars="registry_url=registry.gitlab.com registry_user=foobar force_build=yes download_wp=yes" ansible/press-site.yml
One can adjust the values in the .env file updated (and created if non-existent) by ./make_env
$ ansible-playbook -i digital_ocean.py --extra-vars="registry_url=registry.gitlab.com registry_user=foobar docker_host_user=docker" ansible/deploy-site.yml
where digital_ocean.py is downloaded from https://github.com/ansible/ansible/blob/devel/contrib/inventory/digital_ocean.py
$ curl -O https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/digital_ocean.py
$ chmod u+x digital_ocean.py
if you don't deploy on Digital Ocean, you can find the relevant dynamic inventory for your cloud service on https://github.com/ansible/ansible/tree/devel/contrib/inventory
make sure you have the web site in a directory called wordpress
inside the website
directory. Then ensure the database dump to be imported is there as well under the name wordpress.sql
:
website/
README.md
wordpress
VERSION
wordpress.sql
Then ensure you have an .env
file with appropriate variables:
$ ./make_env
The script above will also keep the build specific variables up-to-date.
Now, you can bake an image and upload it to a registry
$ ansible-playbook --extra-vars="registry_url=registry.gitlab.com registry_user=foobar force_build=yes" ansible/press-site.yml
to deploy, use:
$ ansible-playbook -vvv -i digital_ocean.py --extra-vars="registry_url=registry.gitlab.com registry_user=foobar docker_host_user=someuser update_image=yes" ansible/deploy-site.yml
Note: There is a known issue, such that sometimes the install script will fails to load the database dump and the docker logs will show the following error:
install_wordpress stdout | this is an existing Wordpress web site, loading the database dump if not loaded already ...
install_wordpress stderr | ERROR install_wordpress stderr | 2003 (HY000) install_wordpress stderr | : Can't connect to MySQL server on 'dbs' (111)
2018-04-27 16:18:14,558 INFO exited: install_wordpress (exit status 1; not expected)
When that happens, simply re-run the installation script /install_wordpress
and the database will be loaded correctly.
There is an issue raised for this: #11
This step is not necessary if you used the ansible playbook above.
It is advised to have read Lets Encrypt's FAQ and user guide beforehand.
after the Wordpress container has been started, run the following command on the host and follow the on-screen instructions:
$ docker exec -it a-wordpress-container bash -c "/setup_web_cert"
After the command as returned with a successful message regarding acquisition of certificate, nginx will be reloaded with encryption enabled and configured.
Notes:
/etc/letsencrypt/cli.ini
. Review and amend that file according to needs./etc/letsencrypt
First, make sure there is a Wordpress codebase under the website/
directory.
Check the website/README.md for more details.
$ cd docker-nginx-fpm-caches-wordpress
$ ./make_env && docker-compose up --build -d
One should adjust the values in the .env file updated (and created if non-existent) by ./make_env make_env should be executed at every build so that the dynamic docker labels for build date and vcs ref are populated accurately.
The user is admin
and the initial password can be supplied as ADMIN_PASSWORD
in the .env file generated by ./make_env
MIT (see the LICENSE file)