Good day.

I want to isolate the infrastructure of my new project using Docker containers and I am new to Docker. I am stuck with a problem. First of all, I will show an example of my config, and then I will describe the problem.

Config example

nginx: restart: always image: nginx:latest expose: - 80 ports: - 8181:80 # - 80:80 volumes: - ../.:/code - ./docker/nginx/hosts:/etc/nginx/conf.d/ - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf links: - php php: restart: always build: docker/php5.6-fpm # image: php:5.6-fpm # ports: # - 9000:9000 volumes: - ../.:/code links: - redis_loc - postgres_loc - memcached_loc - rabbitmq_loc 

This is an example. I omitted details for * _loc services. So, I have 2 local development domains, such as site1.loc and site2.loc. I use microservice architecture, and site2.loc is microservice for site1.loc.

I have a common php container for all microservice code and I have the same generic nginx for microservices, which is configured using *.loc.conf configs. Nginx listens to port 80 inside the Docker network. Hosts are available through port 8181 on the local machine. On the local machine, I have a Nginx front that proxies 80 to the appropriate 8181 hosts. Of course, in / etc / hosts on the local machine I have entries

 127.0.0.1 site1.loc 127.0.0.1 site2.loc 

This way I can open these loc hosts in the browser and work with them independently.

Problem

The problem is that site2.loc is a microservice, and it should be accessible from the php code in site1.loc. Now, when I try to send a request from site1.loc php code to site2.loc, I get this error

 'stream_socket_client(): unable to connect to site2.loc:80 (php_network_getaddresses: getaddrinfo failed: Name or service not known)' 

Php can not find a way to connect.

I have already tried to use a docker-compose chip, such as extra_hosts on the nginx and php container, but this did not help me.

 # extra_hosts: # - "site1.loc:nginx" # - "site2.loc:nginx" 

I have already tried to configure a custom network, but this is not the direction.

I also tried jwilder/nginx-proxy , but this makes hosts available on the local machine, and not inside the php container.

I clearly understand that the source of the problem is that the php container environment does not know anything about the site2.loc host. I suppose I need something like hosts map or dns.

But I don’t know how to configure it and I can’t find an example (I used to go Google for half a day).

How can I make site2.loc sufficient for site1.loc php code?

UPD

I just realized that Consul can be used. Or are there other ways without Consul?

UPD

The method with the indication of hosts on 172.17.0.1 in extra_hosts helped. Tell me, which is still better to choose a method for production - extra_hosts, dns, Consul? Provided that on my server there will be more projects nearby in containers and without.

  • request on the internal network to - Naumov
  • Is site2.loc also inside your docker? - ilyapt
  • one
    But after all nginx and php are different containers? Then, first, where does php inside the container need to be aware that site2.loc is 127.0.0.1, if the record is in the / etc / hosts file of the local machine, and not the container? And secondly, your code inside the php-container addressing 127.0.0.1 will refer to itself, and not to the container from nginx. Is there something inside the php container that is listening to port 80? - ilyapt
  • one
    as an option, you can try to use the address 172.17.0.1, the mapping of the nginx port should also be performed on it - ilyapt
  • one
    If you have two microservices in different containers, then they should be smashed. Taking into account near-zero overhead costs, you can add additional nginx before each microservice and link them as you like. - etki

1 answer 1

When you use the value of nginx in Extra Hosts, php doesn't know anything about it, because the containers are isolated, so it is simply recorded in the nginx format1.tite1.loc and everything, but you cannot link 2 containers directly, so that they cannot see each other, a binding error will occur, therefore they used the ambassador pattern before.

The easiest solution to your problem.

We execute in the command line:

 ifconfig docker0 

We take from inet addr output

 inet addr:172.17.0.1 

Usually it is 172.17.0.1, this is the address of the host machine in Docker. Next, open docker-compose.yml, find a container with PHP and paste it there.

 extra_hosts: - "site1.loc:172.17.0.1" - "site2.loc:172.17.0.1" 

172.17.0.1 - the address of your machine from ifconfig. Recreating containers, docker-compose up -d

There are also solutions through networking, external dns. These solutions are in the article on Bi-directional Linking Problem

  • But after all, these ip addresses are dynamic and constantly changing. I need to fix them somehow so that the docker-compose is always with the correct addresses. Or is 172.17.0.1 always the same as the entry point? - Oleg Abrazhayev
  • 2
    172.17.0.1 - the permanent address of your host machine. Containers will contact the host machine and request an address for the required addresses. - Firepro
  • one
    The user who put a minus and wrote that I was wrong, and then deleted my comment, it would be possible to remove the minus too :) - Firepro
  • Firepro, helped with the method of 172.17.0.1. Tell me, which is still better to choose a method for production - extra_hosts, dns, Consul? Provided that on my server there will be more projects nearby in containers and without. - Oleg Abrazhayev