Two-way link with Docker Compose
Update: See the comment by Tristan Claverie for a much simple solution: https://medium.com/@tristan.claverie/well-there-is-in-fact-a-simpler-solution-than-creating-a-network-do-nothing-at-all-docker-f38e93326134#.f1g146wi4
$ docker-compose up
ERROR: Circular dependency between nginx and php5-fpm
This article will talk about how I resolved the Circular dependency between two or more Docker containers using Docker Compose. The solution is generic and can be applied to any number of tools used to create and link Docker containers. If you are in a hurry, the solution is provided at the end of the article.
I had an odd use case:
My nginx container depended on php-fpm to serve PHP scripts while my PHP scripts were making calls to the nginx container.
I started with this simple Docker Compose file:
version: ‘2’services:
php-fpm:
image: yani/php-fpmnginx:
image: yani/nginx
links:
- php-fpm
This worked great for making php-fpm available on the nginx container via upstream:
upstream php {
server php-fpm:9000;
}
However, my php-fpm container didn’t know the ip address of the nginx.
Without much thinking, I’ve added a link to nginx in my php-fpm container with:
version: ‘2’services:
php-fpm:
image: yani/php-fpm
links:
- nginxnginx:
image: yani/nginx
links:
- php-fpm
Then I tried to build this compose file:
$ docker-compose up
ERROR: Circular dependency between nginx and php-fpm
Why linking the containers is not the answer?
To link a container, Docker needs to know the name of the container it is linking in. That means that the container needs to be started first before it can be linked to another container.
I couldn’t find a straightforward solution on the web. I’ve tried irc.freenode.org #docker and #docker-dev but didn’t get any replies. I finally found a GitHub issue that was describing my problem but the solution was rather complex. It, however, helped me shift my focus away from using links.
The solution was to put both containers on the same network and assign them aliases. Then, I could communicate between them using these aliases. I had to change my docker-compose.yml a bit:
version: ‘2’services:
php-fpm:
image: yani/php-fpm
networks:
main:
aliases:
- php-fpmnginx:
image: yani/nginx
networks:
main:
aliases:
- webnetworks:
main:
My nginx config stayed the same. PHP scripts had a direct access to nginx using web hostname (http://web).