How to develop a LAMP web application using Docker, Puppet and Vagrant?

Robert picture Robert · Oct 1, 2014 · Viewed 17.8k times · Source

In the dark ages, my usual set up for development of LAMP web applications was to test locally on my machine. PHP (in my case), the database and the web server were all installed natively.

The server was set up with standard installs of Apache and MySQL, and I had multiple virtual hosts for different parts of the web app. When I was happy with the results I had on my local machine, I'd log in to the server and git pull in the staging environment. Assuming everything was working as well on the server as it was on my machine, I'd do the same thing for production.

New beginnings…

So now I'm starting a brand new web application from scratch, and I want to do it "the proper way". I've read up about Docker, Vagrant and Puppet (and Chef, although I personally prefer Puppet's system of dependencies rather than Chef's iterative process). Despite all the research I've done, there still seem to be several questions I can't seem to find answers for:

Should there be separate Docker containers for the web server (such as Apache), the database server (such as MySQL) and each part of the web application?

When I talk about parts of the web application, I mean things like mysite.com, controlpanel.mysite.com, etc. These "parts" will share the same database.

Since Docker seems to provide ready-made containers for things like the web and database servers, it seems like those things at least should be in separate containers. Should the different parts of my web app be in separate containers, too?

Docker containers seem to be designed to be replaceable rather than me having to update the software inside them. What about the data they write that I don't want to loose?

The database server will manage files related to the content of my database (that I'll want to be backing up). The web server will be creating logs, and my web applications will be managing various files and caches, etc. All these files need to be written outside of the application's containers (because I might replace them when updating?), so where do they go? Straight into the host machines's file system? Or into a separate "Docker Volume"? If they go into Docker volumes, should I use a separate volume for the database, web server, application, etc? Can I still easily access the contents using SFTP from my local machine like I do now? I don't want to loose any convenience here!

Is it a good idea to use Puppet to create and manage the Docker containers, both for the development server and production server?

It seems Puppet has support for managing Docker containers directly, so this seems like a reasonably good way of easily setting up a server or the production environment (using Vagrant) from scratch.

Hopefully I've asked some relevant questions; it would be great to get some proper "best practices" for development and production of LAMP-like web apps, it's just there doesn't seem to be much that I've found!

Answer

Thomasleveil picture Thomasleveil · Oct 5, 2014

Should there be separate Docker containers for the web server (such as Apache), the database server (such as MySQL) and each part of the web application?

There is no correct answer to that question. If you will be using docker in production, then try to run your docker containers in your dev environment as they will be in production. Else just use the docker containers the easiest way you can.

The docker hub provides ready to go containers for php, databases, etc and it is easy to use them. On the other hand you have to link them together to allow them to interact. For a dev environment and if you use multiple containers, I would advise to use docker-compose.

Another path is to build a docker image that is the closest to your production machine (assuming you have only one machine) which would run the database, the web server and php. A container from such an image would have to run multiple processes. This can be achieved in different ways. Take a look at supervisor or phusion/baseimage.

When I talk about parts of the web application, I mean things like mysite.com, controlpanel.mysite.com, etc.

You could have them separated. If those apps need to share sessions make sure sessions are stored in database or on a docker volume that is accessible to all.

Docker containers seem to be designed to be replaceable rather than me having to update the software inside them. What about the data they write that I don't want to loose?

Docker has a thing called volume to allow data to be written on a filesystem out of the container. There are different ways to work with volumes: you can mount a directory from the docker host to a container volume, or you can have data volume containers, or named volumes.

Docker volumes is an important concept and it is worthwhile to take the time to master them.

If you want to easily access the data used by your containers from your docker host, mounting a directory on the docker host is the way to go. Although it may be tricky regarding permissions and ownership of the files

Regarding backups, take a look at the docker user guide where everything you need to know in regards with volumes is detailed.

Is it a good idea to use Puppet to create and manage the Docker containers, both for the development server and production server?

The best practice is to operate on your dev environment the same way you will operate on your production environment. There is no point going through setting up puppet correctly for your dev environment if all that work won't be used for the production environment. Having a Vagrantfile that provision a VM with docker is really easy with just shell provisioning ; IMHO puppet/chef/... are overkill.


You are asking the right questions but there is no answer that fit all situations. In my view there are two ways to do things:

  • make your dev environment replicate exactly your production environment
  • make your dev environment different from production keeping it as simple and straight forward as you can so developers won't feel the friction induced by using new tools