I am trying to link 2 separate containers:
The problem is that php scripts do not work. Perhaps the php-fpm configuration is incorrect.
Here is the source code, which is in my repository. Here is the file docker-compose.yml
:
nginx:
build: .
ports:
- "80:80"
- "443:443"
volumes:
- ./:/var/www/test/
links:
- fpm
fpm:
image: php:fpm
ports:
- "9000:9000"
and Dockerfile
which I used to build a custom image based on the nginx one:
FROM nginx
# Change Nginx config here...
RUN rm /etc/nginx/conf.d/default.conf
ADD ./default.conf /etc/nginx/conf.d/
Lastly, here is my custom Nginx virtual host config:
server {
listen 80;
server_name localhost;
root /var/www/test;
error_log /var/log/nginx/localhost.error.log;
access_log /var/log/nginx/localhost.access.log;
location / {
# try to serve file directly, fallback to app.php
try_files $uri /index.php$is_args$args;
}
location ~ ^/.+\.php(/|$) {
fastcgi_pass 192.168.59.103:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
}
}
Could anybody help me configure these containers correctly to execute php scripts?
P.S. I run containers via docker-composer like this:
docker-compose up
from the project root directory.
Don't hardcode ip of containers in nginx config, docker link adds the hostname of the linked machine to the hosts file of the container and you should be able to ping by hostname.
EDIT: Docker 1.9 Networking no longer requires you to link containers, when multiple containers are connected to the same network, their hosts file will be updated so they can reach each other by hostname.
Every time a docker container spins up from an image (even stop/start-ing an existing container) the containers get new ip's assigned by the docker host. These ip's are not in the same subnet as your actual machines.
see docker linking docs (this is what compose uses in the background)
but more clearly explained in the
docker-compose
docs on links & exposeand if you set up your project to get the ports + other credentials through environment variables, links automatically set a bunch of system variables:
I know it is kind an old post, but I've had the same problem and couldn't understand why your code didn't work. After a LOT of tests I've found out why.
docker-compose.yml
/etc/nginx/conf.d/default.conf
Dockerfile
New Answer
Docker Compose has been updated. They now have a version 2 file format.
They now support the networking feature of Docker which when run sets up a default network called myapp_default
From their documentation your file would look something like the below:
As these containers are automatically added to the default myapp_default network they would be able to talk to each other. You would then have in the Nginx config:
fastcgi_pass fpm:9000;
Also as mentioned by @treeface in the comments remember to ensure PHP-FPM is listening on port 9000, this can be done by editing
/etc/php5/fpm/pool.d/www.conf
where you will needlisten = 9000
.Old Answer
I have kept the below here for those using older version of Docker/Docker compose and would like the information.
I kept stumbling upon this question on google when trying to find an answer to this question but it was not quite what I was looking for due to the Q/A emphasis on docker-compose (which at the time of writing only has experimental support for docker networking features). So here is my take on what I have learnt.
Docker has recently deprecated its link feature in favour of its networks feature
Therefore using the Docker Networks feature you can link containers by following these steps. For full explanations on options read up on the docs linked previously.
First create your network
Next run your PHP-FPM container ensuring you open up port 9000 and assign to your new network (
mynetwork
).The important bit here is the
--name php-fpm
at the end of the command which is the name, we will need this later.Next run your Nginx container again assign to the network you created.
For the PHP and Nginx containers you can also add in
--volumes-from
commands etc as required.Now comes the Nginx configuration. Which should look something similar to this:
Notice the
fastcgi_pass php-fpm:9000;
in the location block. Thats saying contact containerphp-fpm
on port9000
. When you add containers to a Docker bridge network they all automatically get a hosts file update which puts in their container name against their IP address. So when Nginx sees that it will know to contact the PHP-FPM container you namedphp-fpm
earlier and assigned to yourmynetwork
Docker network.You can add that Nginx config either during the build process of your Docker container or afterwards its up to you.
As pointed out before, the problem was that the files were not visible by the fpm container. However to share data among containers the recommended pattern is using data-only containers (as explained in this article).
Long story short: create a container that just holds your data, share it with a volume, and link this volume in your apps with
volumes_from
.Using compose (1.6.2 in my machine), the
docker-compose.yml
file would read:Note that
data
publishes a volume that is linked to thenginx
andfpm
services. Then theDockerfile
for the data service, that contains your source code:And the
Dockerfile
for nginx, that just replaces the default config:For the sake of completion, here's the config file required for the example to work:
which just tells nginx to use the shared volume as document root, and sets the right config for nginx to be able to communicate with the fpm container (i.e.: the right
HOST:PORT
, which isfpm:9000
thanks to the hostnames defined by compose, and theSCRIPT_FILENAME
).For anyone else getting
when using
index.php
whileindex.html
works perfectly and having includedindex.php
in the index in the server block of their site config insites-enabled
Make sure your nginx.conf file at
/etc/nginx/nginx.conf
actually loads your site config in thehttp
block...I think we also need to give the fpm container the volume, dont we? So =>
If i dont do this, i run into this exception when firing a request, as fpm cannot find requested file: