Creating a PHP and Nginx Dockerfile

As discussed in the previous article, I'm in the middle of a major project to build out a scalable hosting platform based on Docker.

As discussed in the previous article, I'm in the middle of a major project to build out a scalable hosting platform based on Docker.

Here's a quick discussion of the stack and build process.

The Dockerfile

Every container uses a base Dockerfile to create the machine in a predictable state. The main challenge is to make sure that the data written to the database during an application's various rebuilds is persistent across deploys.

Apart from that the philosophy of working on Docker is that everything can be quickly rebuilt from scratch on every deploy.

Here's a link to our dockerbase repo on github.

The setup is fairly straightforward, here's a brief walkthrough:

FROM ubuntu:12.04
VOLUME ["/data/mysql"]

RUN echo "deb precise universe" >> /etc/apt/sources.list
RUN apt-get update

RUN apt-get install -y curl wget git

This prepares the container with a base install of Ubuntu, updates the packages via apt-get update and then installs curl, wget and git on the machine which we need to download some extras.

The Volume command tells docker that we are going to keep this path reserved for persistent data.

Adding custom Repos

RUN apt-get install -y python-software-properties
RUN apt-key adv --recv-keys --keyserver 0xcbcb082a1bb943db
RUN add-apt-repository 'deb precise main'
RUN add-apt-repository -y ppa:nginx/stable
RUN add-apt-repository -y ppa:ondrej/php5
RUN apt-get update

Here we add some custom PPA repos which make sure we can be on more cutting edge PHP / Nginx and Mysql versions the default ones on Ubuntu 12.04 are pretty much obsolete, most of our sites require at least PHP5.4 and many now PHP5.5 so this allows us to override the defaults.

Installing Mysql and Nginx

RUN apt-get -y install mariadb-server
RUN sed -i 's/^innodb_flush_method/#innodb_flush_method/' /etc/mysql/my.cnf
RUN sed -i "/^datadir*/ s|=.*|=/data/mysql|" /etc/mysql/my.cnf
RUN chown -R mysql:mysql /data/mysql

RUN apt-get -y install nginx

RUN echo "daemon off;" >> /etc/nginx/nginx.conf

This is fairly straightforward, we install the latest version of MariaDB and repoint the data dir to our newly created volume (see above)

The data dir also needs to be owned by the database user, in this case mysql.

Installing PHP and Composer

RUN apt-get -y install php5-fpm php5-mysql php-apc php5-mcrypt php5-curl php5-gd php5-json php5-cli
RUN sed -i -e "s/short_open_tag = Off/short_open_tag = On/g" /etc/php5/fpm/php.ini
RUN curl -sS | php
RUN mv composer.phar /usr/local/bin/composer

RUN echo "cgi.fix_pathinfo = 0;" >> /etc/php5/fpm/php.ini
RUN mkdir -p /var/www
RUN chown -R www-data:www-data /var/www

Composer is a vital part of our deploy stack, so after configuring php and some necessary modules we install a global version of composer.

mkdir -p /var/www is going to be our web root directory so this gets setup and owned by the web server user in this case www-data.

Let's Go

CMD service mysql start; php5-fpm; nginx -c /etc/nginx/nginx.conf

Once everything is setup, then all we do is start all the services. This is a very easy way to get going, the final version will be rewritten to use the supervisord daemon.

Read more

This repo is currently a work in progress which you can have a look at over on github. If you want to use it in your own Docker builds then search for dockerbase on the Docker index.