While getting in touch with Docker and playing around with different methods to dockerize web services and websites, I came across some interesting articles, blog posts and tutorials. As mentioned in the introduction of my little series of self-hosted web services, I did not find the perfect tutorial covering all my wishes.
That was the reason for me to share my experiences as a Docker beginner and led to start blogging again. Maybe some individuals with similar wishes out there find useful information in my posts.
When I initially had the idea to blog about my solutions as a Docker beginner, of course there was no other way than running the blog in a Docker container. Due to a widespread use of WordPress, a ton of different ways exist.
By the time I’m writing this post, some months have passed since I initially created my dockerized WordPress blog. So unfortunately, I can’t reproduce if I found an almost-ready solution or if I created the
docker-compose.yml partly by myself.
Nevertheless, I will now describe how I’m running this WordPress blog in Docker. For the setup I’m using, three Docker containers are required:
- Web server
For an easy startup and maintenance, those containers are bundled in a
docker-compose.yml file. The web server is the only container allowed to speak to Traefik. It is linked to WordPress and includes WordPress’ files within the corresponding directory of nginx. WordPress again is linked to the database.
As you might expect, WordPress is providing a Docker image on Docker Hub. The configuration is pretty straightforward. I created a named volume to provide the web server access to the WordPress files. Of course, a link to the database container is required. As shown in the figure, Traefik is not aware of the WordPress container.
volumes: wordpress_files: driver: local-persist driver_opts: mountpoint: /path/to/wordpress services: wordpress: image: wordpress:fpm restart: always volumes: - wordpress_files:/var/www/html links: - db:mysql networks: - internal labels: - traefik.enable=false
2. Web server
Because WordPress’ Docker image I’m using is shipped without a web server, I need to create one in a separate Docker container. For this, I’m using an already existing nginx image from Docker Hub, tailored to the official WordPress container.
As shown in the figure, I need to link the web server container to the WordPress container and use the existing named image to get access to WordPress’ files.
The remaining configuration just increases PHP’s
post_max_size and specifies the connection to Traefik.
nginx: image: raulr/nginx-wordpress restart: always links: - wordpress volumes: - wordpress_files:/var/www/html environment: POST_MAX_SIZE: 128m networks: - internal - proxy labels: - traefik.enable=true - traefik.backend=blog - traefik.frontend.rule=Host:blog.domain.net - traefik.docker.network=proxy
Accessing the database should at least be secured by a password protected user. So username and password, as well as the name of the database and a root password need to be set. Because my
docker-compose.yml file is tracked via Git, I put those variables in a separate file (
wp_db.txt). This file is then
MYSQL_ROOT_PASSWORD=123456 MYSQL_PASSWORD=654321 MYSQL_DATABASE=mydatabase MYSQL_USER=user
By nature, when a Docker container stops, crashes or is being deleted, the files changed within the container are also being deleted. In this case, our database would have been gone. That’s why I need to create a volume, to still have MariaDB’s files outside the Docker container when deleting the container.
db: image: mariadb:10.3.8 restart: always secrets: - wp_db volumes: - /my/local/path/to/mysql:/var/lib/mysql networks: - internal labels: - traefik.enable=false
Setting up WordPress in Docker was rather easy. There is a ton of tutorials, examples, Docker images, Dockerfiles etc. and setting up websites in Docker containers follow a certain pattern.
Putting all three parts together, my
docker-compose.yml file is looking like this:
version: '3.1' networks: proxy: external: true internal: external: false volumes: wordpress_files: driver: local-persist driver_opts: mountpoint: /my/local/path/to/wordpress services: wordpress: image: wordpress:fpm restart: always volumes: - wordpress_files:/var/www/html links: - db:mysql networks: - internal labels: - traefik.enable=false nginx: image: raulr/nginx-wordpress restart: always links: - wordpress volumes: - wordpress_files:/var/www/html environment: POST_MAX_SIZE: 128m networks: - internal - proxy labels: - traefik.enable=true - traefik.backend=blog - traefik.frontend.rule=Host:blog.florianfranke.net - traefik.docker.network=proxy db: image: mariadb:10.3.8 restart: always secrets: - wp_db volumes: - /my/local/path/to/mysql:/var/lib/mysql networks: - internal labels: - traefik.enable=false secrets: wp_db: file: wp_db.txt