docker compose:重建一个链接容器会破坏nginx的上游

时间:2016-10-20 12:33:00

标签: nginx docker docker-compose

我正在使用docker-compose和“Docker for Mac”,我有两个容器:一个NGINX,一个容器,用于端口3000上的node-app。

docker-compose.yml看起来像这样:

version: "2"

services:
  nginx:
    build: ./nginx
    ports:
      - "80:80"
    links:
      - api
  api:
    build: ./api
    volumes:
      - "./api:/opt/app"

在NGINX的配置中,我说:

upstream api {
  server api:3000;
}

server {
  # ....
  location ~ ^/api/?(.*) {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;

    proxy_pass http://api;
    proxy_redirect off;
  }
}

现在,当我更改节点代码中的某些内容并重建容器

$ docker-compose stop api && docker-compose up -d --build --no-deps api

容器正在重建并启动。问题是,有时容器的内部IP会发生变化,NGINX也不会知道。有趣的是,当我进入NGINX容器并ping api我得到新的IP地址

$ ping api
PING api (172.19.0.3): 56 data bytes
64 bytes from 172.19.0.3: icmp_seq=0 ttl=64 time=0.236 ms

但NGINX日志仍然说

2016/10/20 14:20:53 [error] 9#9: *9 connect() failed (113: No route to host) while connecting to upstream, client: 172.19.0.1, server: localhost, request: "GET /api/test HTTP/1.1", upstream: "http://172.19.0.7:3000/api/test", host: "localhost"

其中上游的172.19.0.7仍然是旧的IP地址。

PS:每次重建容器时都不会发生这种情况。

1 个答案:

答案 0 :(得分:2)

This is because Nginx caches the DNS response for upstream servers - in your workflow you're only restarting the app container, so Nginx doesn't reload and always uses its cached IP address for the api container.

When you run a new api container, as you've seen, it can have a different IP address so the cache in Nginx is not valid. The ping works because it doesn't cache Docker's DNS response.

Assuming this is just for dev and downtime isn't an issue, docker-compose restart nginx after you rebuild the app container will restart Nginx and clear the DNS cache.