For me the benefits of having two containers are:
- Separation of concerns.
- PHP processes are way more resource consuming than NGinx and will have to be scaled up more often (maybe also interesting read);
- Running multiple versions of PHP becomes easier as they are decoupled;
Last week I’ve been trying to get a good setup working, but until now I haven’t found any good solutions for separate NGinx and PHP containers. I’ll list the things I’ve tried below. I hope you find it useful.
A. Building two separate images
PHP:
FROM php:7-fpm
ADD ./php/php.ini /usr/local/etc/php/php.ini
ADD ./src /var/www/html
NGinx:
FROM nginx
ADD ./nginx/default.conf /etc/nginx/conf.d/default.conf
ADD ./src /var/www/html
docker-compose.yml:
php:
image : <your_php_image>
links:
- memcached
- mysql
nginx:
image: <your_nginx_image>
links:
- php
ports:
- "80:80"
Every time you want to deploy something to production both an PHP image and an NGinx image need to be build which will contain your source code. This solutions just makes me feel uncomfortable and doesn’t seem to be DRY.
B. Volumes-From
php:
image : <your_php_image>
links:
- memcached
- mysql
nginx:
image: nginx
links:
- php
volumes_from:
- php
ports:
- "80:80"
In this example only one container needs to be build which will contain your application. This image might also contain the configuration files for NGinx if you like. If not, you only need to rebuild the nginx container when some config file needs to be updated. In Rancher we need to use a sidekick if we want to use volumes_from
:
php:
image : <your_php_image>
links:
- memcached
- mysql
nginx:
image: nginx
volumes_from:
- php
ports:
- "80:80"
labels:
io.rancher.sidekicks: php
This seamed like a good solution to me, however the problem is that sidekicks are not to allowed to have any links. Because PHP has links to the memcached
and mysql
service this won’t work. To bad! Maybe someone knows how to bypass this?
C. Volumes
php:
image : php
volumes:
- /volume/src:/var/www/html
links:
- memcached
- mysql
nginx:
image: nginx
links:
- php
volumes:
- /volume/src:/var/www/html
ports:
- "80:80"
A third option could be to use something like convoy fs to share an underlying filesystem which both the PHP and NGinx container could use to mount the source code. I’ve been using this method on AWS Elastic beanstalk and It works great for me there, but I have not tested it yet for rancher. The benefits here are that you can just use public repositories as there is no sensitive information in your containers. The thing I’m uncertain about it is how to do rolling updates if a shared filesystem is used. Maybe someone has an idea about this?
In the end I might just go with a single php-nginx container as it simplifies the whole process .
Like RVN_BR I also would like to see other solutions / ideas