26

(I know others have asked this question before, but I'm not able to solve the problem using the solutions proposed in other posts, so i figured i would try to post my configuration files and see if someone could help.)

I want to create a container for nginx, and use proxy_pass to pass requests to the container with the running web application. I can't figure out how to communicate between the two containers. When i try to run docker stack deploy -c docker-compose.yml somename, only the web container starts. The nginx container fails to start, and is stuck in a loop of trying to restart. This is the log messages I get:

2017/08/16 14:56:10 [emerg] 1#1: host not found in upstream "web:8000" in /etc/nginx/conf.d/nginx.conf:2 nginx: [emerg] host not found in upstream "web:8000" in /etc/nginx/conf.d/nginx.conf:2

I found an answer that as long as you use the same name as under services in the docker-compose.yml file, nginx would find the variable. However that doesn't seem to help in my case.

How does communication like this between different containers work? Where is the 'web' variable

Most examples I've seen use version: "2" in the docker-compose.yml file, should this make a difference?

My docker-compose.yml:

version: "3"
services:
  web:
    image: user/repo:web
    deploy:
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
      restart_policy:
        condition: on-failure
    ports:
      - "8000:80"
    networks:
      - webnet

  nginx:
    image: user/repo:nginx
    ports:
      - 80:80
    links:
      - web:web
    depends_on:
      - web

networks:
  webnet:

Nginx config:

upstream docker-web {
    server web:8000;
}


server {
    listen 80;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location / {
         proxy_pass http://docker-web;

         proxy_set_header   Host $host;
         proxy_set_header   X-Real-IP $remote_addr;
         proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header   X-Forwarded-Host $server_name;
    }
}
landigio
  • 543
  • 1
  • 5
  • 10

4 Answers4

14

I figured out how to fix the problem. Got some help to fix the docker-compose.yml, so it looks like this:

docker-compose-yml:

version: "3"
services:
  web:
    image: user/repo:web
    deploy:
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
      restart_policy:
        condition: on-failure
    ports:
      - "8000:80"
    networks:
        main:
            aliases:
                - web


  nginx:
    image: user/repo:nginx
    ports:
      - 80:80
    links:
      - web:web
    depends_on:
      - web
    networks:
        main:
            aliases:
                - nginx
networks:
  main:

After this the nginx container actually ran, but it was still not capable of connecting to the web-container. Found out I was able to use both curl web and curl web -p 8000 to get the page from web, from inside the nginx container. Then I changed the upstream in my nginx.conf from this

upstream docker-web {
    server web:8000;
}

to this:

upstream docker-web {
    server web;
}
landigio
  • 543
  • 1
  • 5
  • 10
  • In my case I was running the web service on port `8000` and I have had to specify the port in the upstream `upstream docker-api { server api:8000;}` and the proxy_pass line of the server nginx server config y left it like this `proxy_pass https://docker-web;` – Imanol Apr 18 '23 at 07:11
  • I also recommend creating a folder _nginx/conf.d_ in the project rootdir and save there all the nginx .conf file. Then you can add this into your _docker-compose.yml_ file to load them automatically `volumes: - ./nginx/conf.d:/etc/nginx/conf.d/` – Imanol Apr 18 '23 at 07:13
7

It's simple. Just change the old configuration:

upstream docker-web {
    server web:8000;
}

To this new one:

upstream docker-web {
    server web:80;
}

The reason is, between containers can't communicate with published port. It just can communicate with the target port. 8000:80 (8000 is published port and 80 is target port).

Let say you have 8000:443, you must create the configuration with "server web:443" inside Nginx listen to 443 port number. May this help.

Game Terserah
  • 309
  • 3
  • 5
  • Been banging my head for 2 days on this. On Docker Desktop on Windows, this is not how it works. I would map to web:8000. However, on my Linux/Ubuntu box this IS how it works, u map to web:80. – brando Nov 13 '21 at 18:08
  • Is there any documentation for this anywhere?!?!?! – David Owens Oct 27 '22 at 22:50
4

Hello your problem is with the port when you linked web:web you need to specify the port in which the container runs the service for exemple

    ports:
  - "8000:80"

means inside the container i can access on port 80 but in the host machine i can acess via 8000. here's the doc about linking two services in docker-compose

so if you want to access web in proxy nginx don't use 8000 but use :

upstream docker-web {
server web:80;
  }

instead, this should work :)

or (those are both the same)

 upstream docker-web {
    server web;
      }
Montassar Bouajina
  • 1,482
  • 1
  • 8
  • 20
0

Well you could achieve that by editing your /etc/hosts file and add the proper entry for your web host

1.1.1.1 web

Obviouslly you'll have to replace 1.1.1.1 with the web server's real ip address (a private one I suppose). Save the file and try again. Another workaround would be to replace in the config:

upstream docker-web {
    server web:8000;
}

with

upstream docker-web {
    server web-ip-address:8000;
}

If you'll go for the 2nd, don't forget to restart/reload nginx!

Bogdan Stoica
  • 4,349
  • 2
  • 23
  • 38