I want to run my Symfony3 app out of Docker container. As I understand I can install/create multiple images with docker and spin them up into a container that will hold my app.
I been going through some docks on Docker on how I may do this, I seen that I can have a docker images such as:
But I still find it hard to understand the concept of spinning multiple images into one container.
Also I have seen something called DockerFile which apparently can can build a my dev environment into one container that I can also work with.
Question 1: Can someone please clarify the whole process I still find it hard to wrap my head around it.
Question 2: How can I build DockerFile and what is it?
You don't want to spin multiple images into one container. It's possible that you don't even need a docker file (but for PHP, you probably do).
The usual mantra concerning docker is "one process per container", and after working with it for several months, I find this to be great advice, even if it's not always achievable. For a PHP app, whether it's symphony, Cake, Laravel, Wordpress, whatever, this is how I do it. I use apache, and it sounds like you might be more familiar with apache as well. You can easily substitute the official nginx container with minor changes to my example if desired.
I typically use the official httpd container, the official mysql container, and I extent the offical php fpm container as described to include the mods that I need. Here is an example of a PHP-FPM dockerfile that adds in some external libs that might be needed for your app:
FROM php:5.5-fpm
RUN apt-get update && apt-get install -y \
php5-mysql \
php5-curl \
php5-common \
php5-gd \
php5-imagick \
php5-intl \
php5-dev \
php5-sqlite \
php5-xdebug \
php5-memcached \
\
libmemcached-dev \
libmcrypt-dev \
libfreetype6-dev \
libxml2-dev \
libmagickwand-dev \
libjpeg62-turbo-dev \
libpng-dev && \
\
docker-php-ext-install pdo pdo_mysql && \
docker-php-ext-install soap && \
docker-php-ext-configure gd --with-jpeg-dir=/usr/include/ && \
docker-php-ext-install gd && \
docker-php-ext-install iconv mcrypt && \
\
pecl install imagick && \
docker-php-ext-enable imagick && \
pecl install memcached && \
docker-php-ext-enable memcached && \
\
pecl install xdebug && \
docker-php-ext-enable xdebug && \
\
mkdir -p /app/content && \
mkdir -p /app/usr/local/apache2 && \
cd /app/usr/local/apache2 && \
ln -s ../../../content htdocs
COPY copy/xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini
This builds an image that I actually use for development. In addition to installing dependencies, it copies a config for xdebug, and sets up the folder structure to hold my app.
You would build this container like this:
docker build -f nameoffile.Dockerfile -t myhubaccount/myphpcontainer \ ./path/to/folder/where/dockerfile/is
This builds an image on your machine tagged as myhubaccount/myphpcontainer
and you can refer to it in your compose file.
A basic compose file that tells these containers how to talk to each other might look something like this:
docker-compose.yml
version: '2'
services:
httpd:
image: httpd:latest
volumes:
- ./docker_conf/httpd.conf:/usr/local/apache2/conf/httpd.conf
- ./webroot:/usr/local/apache2/htdocs
ports:
- "80:80"
links:
- fpm
logging:
options:
max-size: "0"
database:
image: mysql
ports:
- "3306:3306"
volumes:
- ./schema.sql:/docker-entrypoint-initdb.d/schema.sql
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
MYSQL_DATABASE: development
logging:
options:
max-size: "5k"
fpm:
image: myhubaccount/myphpcontainer
volumes:
- ./webroot:/app/content
links:
- database
logging:
options:
max-size: "50k"
I think it's beneficial to highlight several parts of this file. First, for php-fpm you need to set up apache to talk to the fpm server. The links
object under httpd tells the container that there is another container with a domain name of "fpm", and docker knows how to resolve that name, so any communication with the fpm server can use that name. We have to mount (under volumes) the apache config in the httpd container. It looks like the default config, but has this part added to accommodate php-fpm:
ProxyTimeout 30
<FilesMatch ".*\.php$">
SetHandler "proxy:fcgi://fpm:9000"
</FilesMatch>
This tells apache to forward requests for php files to the fpm server and serve the result.
The ports
entry causes port 80 of the container to be forwarded to port 80 of the docker machine. This is localhost on linux, or the docker-machine ip on Mac and Windows. You can find this ip with the console command docker-machine ip
.
We do the same thing on the mysql container so that we access mysql directly with a tool like Mysql Workbench. You can read about the environment variables that the official mysql container allows and what they do.
We have links
for fpm, if it needs to talk to the database. The hostname for your database in this case is just "database".
The logging
items are not necessary, just personal preference to keep the log output from becoming excessive.
Once you have all this in place, you bring up the environment with docker-compose up
. If you want to take a look at what a container looks like you can get a shell on a running container with docker-compose exec fpm bash
, substituting "fpm" with the name of the container you want to look at. The caveat here is that the container must actually include the bash
binary. All of these here do, but some containers do not.
I hope that this gives enough php-specific example to help you wrap your head around how docker sort of works. I would suggest re-reading the docs for bother Docker and Docker Compose. And I would also suggest reading the Dockerfiles for the official images if you are interested in building your own containers. The docs have links to Dockerfiles that the Docker team considers to be exemplary.