Search code examples
nginxdockerdnsvirtualhostconsul

How could I connect to nginx vhost in Docker container from linked php Docker container?


I want to isolate my new project infrastructure using Docker containers and I'm newbie in Docker. I'm stuck with a problem. First of all I will show example of my config and then I will address 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 have dropped details for *_loc services. So, I have two local domains for development, like site1.loc and site2.loc. I'm use micro-service architecture and site2.loc is a micro-service for site1.loc.

I have common php container for all micro-services code and I have common nginx container for all micro-services which configured with *.loc.conf config files. Nginx listen to 80 port inside Docker network. This hosts are available through 8181 port on host machine. On local (host) machine I have front nginx with the same *.loc configs configured as proxy to 8181 analogues. Also I have in my /etc/hosts records

127.0.0.1 site1.loc
127.0.0.1 site2.loc

So, I can open in browser both local sites and work with them separately.

The problem

The problem is, that site2.loc is a micro-service, so it should be accessible from site1.loc php code. And now, when I'm trying to send request to site2.loc from site1.loc php code I'm getting the error:

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

Php can't find the way to site2.loc.

I have tried docker-compose feature extra_hosts on nginx and php containers, but it's doesn't helped me.

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

I have tried to configure custom network, but then I'm realized, that this is wrong way.

Also I have tried jwilder/nginx-proxy, but it's make vhosts available just for local machine, not inside php container.

I clearly understand that source of problem is that environment inside php container doesn't know anything about site2.loc host. And I guess I need some kind of hosts mapping or dns to be configured.

But I don't know how to implement such configuration and can't find any example (I had googled through half day yesterday).

How could I make site2.loc accessible to site1.loc php code?

UPD

I just have figured out that I need use Consul. Are there another ways without Consul?

UPD

Helped way of indicating the hosts with reference to 172.17.0.1 in extra_hosts. Prompt, how it is better to select a method for Productions - extra_hosts, dns, Consul? Given that I have on the server several projects nearby, in containers or without.


Solution

  • Do you need external access to your microservice site2.loc ? If not you can split site1 and site2 in two nginx containers, then you can do like this with user-defined networks:

    1. Create a network named "app-net"
    2. When you create each service connect them to the network and give them an alias (--network-alias), let's say you put the alias site2 on your microservice
    3. There is an internal DNS server in Docker that will resolve the domain names for the container. So when you want to access site2 from the PHP code simply use "site2" wich will be resolved into a IP adress accessible by the PHP container (if they are all connected to the same user-defined network)

    Just make sure the PHP process can access the PHP files with the same path as nginx.

    EDIT : In docker compose I think the net alias is set automaticaly with the service name
    EDIT2 : in fact docker compose is setting up a network automaticaly https://docs.docker.com/compose/networking/#/networking-in-compose