Docker Explained for PHP Developers in 2018

Containers

This post assumes you have a basic understanding of Docker. But what is a basic knowledge? If you aren’t sure, I suggest you read the Get Started docs, and then you will have a basic understanding of Docker.

I’ve read a few posts on Docker for PHP developers. However, it was the same tutorial on different sites, so I’m not going to copy what they did. I’ll explain the concepts that I struggled with learning.

My objective with Docker is to develop locally and deploy to a Swarm. I hope to have a fast site with high-availability that can be updated and deployed quickly.

Developing Locally

I was recently working on a project that uses SOAP hosted on a slow connection. Instead of hitting that API each page load, I decided to store the results in Redis, and load them from there. This helped speed up the pages that needed to access the data from the remote API. Installing Redis on my local system wasn’t what I wanted to do, so I simply added a Redis service to my “docker-compose.yml” file, and it worked great. You can easily add new services to your stack while developing locally with Docker.

Being able to edit your code, with all the services running, and see the changes immediately is very valuable. I like to develop on Windows, OSX, and Linux, so my environment is drastically different on each machine. It would be very time consuming if I had to have Redis running on each of my dev environments. Having Docker running the same services locally on my dev machines as what is running in production is priceless.

Priceless

The Docker Compose file

You will need two use two “docker-compose” files, one for local development, and one for deploying to your swarm. The main file, “docker-compose.yml,” will be used when deploying to your production environment. And “docker-compose.override.yml” will be used when developing locally. You want to copy your PHP code into the container when you are deploying to production. When you’re developing locally, you want your code outside of the container, so we mount it with volumes in the override file.

Docker Swarm explained in a drawing

You can use Volumes in production, but you will need to copy the files to the node where the container will live. That can be complicated and in my opinion, isn’t ideal. It does work well when developing locally and your computer is the node since the files are already on it.

Docker Services and etc

All of these terms can become confusing, at least they were to me, but I hope to explain them shortly. We used to refer to a “web server” as a server that ran everything a website needed. Even though it was a server running daemons like Apache’s httpd.

Now we have stacks, containers, node, swarms, services, and a lot more words to describe things. Communication is important when speaking with others about the approach you wish to use when solving problems. Understanding what you’re saying is even more important. I’m going to try and define these terms myself.

A service is a piece of software written that we will use to help us accomplish our goals. MySQL, nginx, Apache, PHP, node, and etc are all services we can use with Docker.

Your stack is essentially a list of the services being used for the app. For this example, I’m using haproxy, nginx, and PHP-FPM.

A container is a way to virtualize the service(s) on the computer. FreeBSD has had this ability for a long time with Jails, but Docker has made it much easier. Containers can’t access other resources running on the server.

A node is a single instance of an Operating System. Your computer could be a node, as well as a Virtual Private Server or a Virtual Machine or an entire bare metal server. Node’s run an Operating System that runs the containers.

Swarms are really awesome! They are a collection of nodes and can distribute the containers across them as needed. They can have their own private network and do load balancing.

Swarm

Conclusion

This app is using haproxy, nginx, and PHP-FPM. I’m passing SSL through haproxy so nginx can handle SSL termination because I’m not sure how to do it with haproxy. The load balancer, haproxy, passes the request off to one of the web services. One of the web services, nginx, then connects to a PHP-FPM service to process the PHP.

Be sure to check out the levilol/php-docker repo on Github.

Docker is an excellent tool that I hope to learn more about this year. Other’s have predicted it will get much more attention in 2018 and I agree. I’m going to end this post with my simplified description of Docker.

Imagine if you could compile your app with all the required services and end up with one binary file that contains everything – that is Docker.

Please leave any feedback below in the comments section.