PHP Platform on Docker
A PHP-Platform Docker tutorial to make PHP runnable in Docker
First of all: I LOVE PHP! I am PHP-Developer for more then 12 years now and still love it like on the first day ;)
But a new “Darling” shown up 4 years ago. DOCKER! I don’t want to loos my PHP but I was also interested using Docker for my App-Servers and my Dev-Machine.
Because of this I decided to use PHP and Docker at the same time and what can I say: IT IS JUST AWESOME!
In this Tutorial i will show you the Setup on my Dev-Machine to develop PHP-Apps with PHP-FPM and NGINX.
#Prerequirements You have Docker installed already and know how Dockerfiles work.
WARNING: This setup is just for your Dev-Machine! Do not use it 1 to 1 on your production servers! I will post a second tutorial how to build this on production!
#Lets go!
Basically, we need two Docker-Images:
- PHP-FPM
- Nginx
I build my own PHP-FPM5 and 7 images based on Alpine. You should create two directories phpfpm5 and phpfpm7 and create the Dockerfiles in it.
Configfiles for php-fpm.
php-fpm.conf
[www]
user = nobody
group = nobody
listen = [::]:9000
chdir = /application
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
catch_workers_output = Yes
php.ini
date.timezone = "UTC"
short_open_tag = Off
session.auto_start = Off
Dockerfile PHP-FPM5
FROM alpine:3.5
RUN apk --update add \
php5 \
php5-bcmath \
php5-dom \
php5-ctype \
php5-curl \
php5-fpm \
php5-gd \
php5-iconv \
php5-intl \
php5-json \
php5-mcrypt \
php5-opcache \
php5-openssl \
php5-pdo \
php5-pdo_mysql \
php5-pdo_pgsql \
php5-pdo_sqlite \
php5-phar \
php5-posix \
php5-soap \
php5-xml \
&& rm -rf /var/cache/apk/*
COPY php.ini /etc/php5/conf.d/50-setting.ini
COPY php-fpm.conf /etc/php5/php-fpm.conf
EXPOSE 9000
CMD ["php-fpm", "-F"]
Dockerfile PHP-FPM7
FROM alpine:edge
RUN echo 'http://dl-cdn.alpinelinux.org/alpine/edge/testing' >> /etc/apk/repositories && \
apk --update add \
php7 \
php7-bcmath \
php7-dom \
php7-ctype \
php7-curl \
php7-fileinfo \
php7-fpm \
php7-gd \
php7-iconv \
php7-intl \
php7-json \
php7-mbstring \
php7-mcrypt \
php7-mysqlnd \
php7-opcache \
php7-openssl \
php7-pdo \
php7-pdo_mysql \
php7-pdo_pgsql \
php7-pdo_sqlite \
php7-phar \
php7-posix \
php7-session \
php7-soap \
php7-xml \
php7-xmlreader \
php7-xmlwriter \
php7-zip \
&& rm -rf /var/cache/apk/*
COPY php.ini /etc/php7/conf.d/50-setting.ini
COPY php-fpm.conf /etc/php7/php-fpm.conf
EXPOSE 9000
CMD ["php-fpm7", "-F"]
Based on these Dockerfiles run a docker build command to build your images. Navigate into your directories and run
docker build -t tippexs/phpfpm7:1.0 .
docker build -t tippexs/phpfpm5:1.0 .
After this you should have two Docker images on your machine. You can see the new generated images by typing
docker images
Your output should look like this:
tippexe/phpfpm5 1.0 818a198d3c00 6 days ago 82 MB
tippexe/phpfpm7 1.0 21ccb78f50bb 6 days ago 67.7 MB
Before we run the PHP-Containers we should setup the NGINX-Webserver and link it to the PHP-FPM Container.
Build your NGINX Container
nginx configuration file
server {
listen 80;
server_name localhost;
location / {
root /var/www;
index index.php index.html index.htm;
}
error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ \.(php)$ {
fastcgi_pass php:9000;
fastcgi_param DOCUMENT_ROOT /application;
fastcgi_param SCRIPT_FILENAME /application$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
}
Dockerfile nginx
FROM nginx:latest
COPY conf/nginx.conf /etc/nginx/conf.d/app.conf
You can build your Docker Image in the same way you built your PHP-FPM Images. Navigate into the directory and run docker build. Don’t forget to label your build ;).
Run your Containers
Make sure you have at least 2 images. NGINX and PHP-FPM.
Now we can run our containers. Very important at this point is the fact we need to link the containers against each other and allow them to talk.
First, start your PHP-FPM container. In my case PHP-FPM7.
docker run --name php -d -v /var/www/myapphome:/application tippexe/phpfpm7:1.0
The –name is important to link our containers. I case this is completely new to you read the docs.
There was or still is a CLI-command –link. This i depracted and should not be used anymore. Therefore you should create a User-defined bridged network for your containers.
[Docker User-defined networks] (https://docs.docker.com/engine/userguide/networking/#user-defined-networks)
I did this by typing:
docker network create --driver bridge dev
Now you should have a User-defined bridged dev network (Isn’t that a perfect word for hangman: “userdefinedbridgeddevnetwork” :D)
List your networks by typing docker network ls.
Now, finally!, let’s start our containers.
Important: Start your PHP-FPM first.
docker run --name=php --network=dev -itd -v /var/docker/audi_nginx/apphome:/application tippexs/phpfpm7:1.0
Now, start your NGINX webserver
docker run --network=dev -itd -p 80:80 --name=web -v /var/www/mywebapps/apphome:/var/www tippexs/nginx:1.0
Let’s have a look if it works:
Type docker ps to list your running container instances. You should have two containers up & running.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
072945924b22 tippexs/phpfpm5:1.0 "php-fpm -F" 55 seconds ago Up 55 seconds 9000/tcp php
b4bc295200e7 tippexs/nginx:1.0 "nginx -g 'daemon ..." 5 minutes ago Up 5 minutes 0.0.0.0:80->80/tcp web
Awesome! That looks good. Now lets see what webapp we are running, currently.
To change the PHP-FPM for example just kill and remove the running PHP-FPM container instance and run the other PHP-FPM container.
How to do this?
simply run docker ps to list your running containers (As we did it a lately to check our running containers). Each running container has an unique container-id. To kill and remove the container you can run
docker kill 072945924b22 && docker rm 072945924b22
What’s next
- A PHP and Docker production Tutorial i a new Post.
- Use Pear and Pecl with PHP-FPM on alpine-linux Base-Images
If you have any questions or commands feel free to leave a comment.