The "why" part
I am sure that if you've not been using docker so far, you’ve heard about docker and most probably you’ve read about it. It’s been a very popular topic for at least few years now. So I assume you have at least some knowledge about it. I don’t want to describe the architecture of docker. There have been thousands of articles, webinars and screen casts about it.
I heard and read about it but wasn’t actually so much in love until I bought my first VPS and had to start installing all the services, tools and packages from scratch and then, obviously, configuring them. What one usually needs when starting a project is a LAMP. Depending on its size some load balancing and efficient caching could be required. Additionally, one would like to have a mail server plus some apps should be able to send emails. And more than that, these days SSL is a must, so let’s assume we want that too. When you prepare a list like this, and you start thinking about how much work is that you may ask yourself: what if I need to move all these things to another VPS? For any reason…This is exactly the reason I’ve started considering docker and containerized setup, but there are really many different advantages of this approach. Ok - let’s start. And please remember - we don’t want any single thing (except docker) installed on the host (in my case it’s ubuntu server 14.04.1 LTS). So the complete list of our toys is the following:
- mysql (percona)
- nginx
- php
- mail server (postfix, curier)
- memcached
- let’s encrypt ssl certificates
- haproxy
Now it’s up to you to decide if you want to have some of the tools coupled or all of them independent. I’ve decided to have them independent all but the nginx together with php fpm.
The searching part
Depending on the approach you may look for compound images containing many of the above together or single ones. You may also build your own image – I am gonna describe one of my own images later on, but as it’s not the scope of this article it will be rather basic explanation. Do not forget to have a look at the references in the end of the article where I’ve put all those used.
The gluing part
We need something that will build, create, start and maintain all containers, and keep most of the configuration and also linking between separate services. The tool for this is docker-compose and we are going to have everything in a yaml based file.
MySQL (Percona)
One has to be careful when using the "latest" tag and it’s definitely worth checking the image maintainer policy for upgrades.
The other thing worth noticing here is the "port forwarding" - I love MySQL workbench to manage my databases, recently also configured most of them in PhpStorm, but having the port for MySQL open, especially when using the default 3306 is asking for trouble (and the log with failed attempts growing soooo quickly). In this case considering a different, unusual port for connecting from outside could be some option - in my case it drastically reduced the number of attempts.
"Mapping" the host dirs to container dirs.
Mail server
Pretty straight forward configuration. SA prefixed ones are Spam Assassin directives.
Memcached
If you need/want to save size of your images, always look for those based on alpine linux.
Nginx and php
And finally some linking! This web container will use links to percona, mail server and memcached!
SSL certificates
Why let’s encrypt? Because it’s a free, trusted CA. It issues certificates for 3 months only, but with the above image you could have them renewed.
Load balancing/routing
The running part
So let’s spin things up with docker compose. Use -f to specify the setup file and remember about using -d flag to run as deamon (that will let you continue working on the host or terminating the connection).
Checking if all are properly created could be done with docker ps command:
And voilà, all services are up and running. Noticed all the services prefixed with kuba_ ? It’s because the path I’ve run the command was /home/kuba but it would change depending on your path. Also, worth to be noticed is that if you want to scale in the future, do not "hardcode" the container name, allow adding the unique identifiers in the end, like at the above example all are suffixed with _1. In the next part I will try to dig into the details, show how we could scale, but also show how and why to build one’s own image.
References:
- https://hub.docker.com/r/million12/nginx-php/
- https://hub.docker.com/r/tvial/docker-mailserver/
- https://hub.docker.com/_/percona/
- https://hub.docker.com/_/memcached/
- https://hub.docker.com/r/tutum/haproxy/
- https://github.com/Levino/letsencrypt-cert-service
- https://docs.docker.com/compose/