Docker容器无法使用外部地址在同一主机上调用其他容器

时间:2018-09-30 21:13:45

标签: docker nginx docker-compose

设置如下:

我在同一主机上有3个容器

  • 一个在端口3000上部署了VueJs Web应用程序的Docker容器
  • 在5,000端口上部署了一个node.js应用程序(API)的docker容器
  • 一个带有nginx的docker容器

由于nginx,Web应用程序从外部对myproject.com做出响应,API对api.myproject.com做出响应。

问题在于,当VueJs应用程序使用地址(在服务器端执行代码的代码)nginx超时调用API并给出504响应时。如果我使用内部网络名称,则可以正常工作(例如,http://myproject-api),但很显然,此后该Web应用程序无法在客户端运行。

这是nginx日志给出的错误

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_alignParentBottom="true">

        <Button
            android:id="@+id/button3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="BUTTON3"/>

        <Button
            android:id="@+id/button4"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="BUTTON4"/>

    </LinearLayout>

    <LinearLayout
        android:id="@+id/linearLayout2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_above="@id/linearLayout1">

        <Button
            android:id="@+id/button1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="BUTTON1"/>

        <Button
            android:id="@+id/button2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="BUTTON2" />

    </LinearLayout>

    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@id/linearLayout2">

    </ListView>

</RelativeLayout>

如果我从浏览器中调用API,它也可以正常工作。 如果我在Web应用程序docker shell中执行wget,则无法正常工作。 例如,在浏览器中,大张旗鼓显示端点,但此调用在docker shell中超时

2018/09/29 09:12:00 [error] 13#13: *5 upstream timed out (110: Connection timed out) while reading response header from upstream, client: XXX.XXX.XXX.XXX, server: staging.myproject.com, request: "GET / HTTP/1.1", upstream: "http://172.18.0.3:3000/", host: "staging.myproject.com"

这是nginx conf

docker exec -it myproject-client wget http://api.myproject.com/documentation

这是docker-compose.yml

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
error_log  logs/error.log  debug;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    gzip  on;

    server {
        listen       80;
        server_name  api.staging.myproject.com;

        location /  {
                proxy_pass http://myproject-api:5000;
                proxy_http_version 1.1;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header Host $http_host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header Connection keep-alive;
                proxy_read_timeout 90;
        }
    }

    server {
        listen       80;
        server_name  staging.myproject.com;

        location /  {
                proxy_pass http://myproject-client:3000;
                proxy_http_version 1.1;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header Host $http_host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header Connection keep-alive;
                proxy_read_timeout 90;
        }
    }
}

这是网络检查

version: "3"

services:
  myproject-api:
    build: ./myproject/packages/server
    container_name: myproject-api
    networks:
      - myproject-network
    ports:
      - "5000:5000"
  myproject-client:
    build: ./myproject/packages/client
    container_name: myproject-client
    networks:
      - myproject-network
    ports:
      - "3000:3000"
    depends_on:
     - myproject-api
  nginx:
    image: "nginx"
    container_name: nginx
    networks:
      - myproject-network
    ports:
      - "80:80"
    depends_on:
      - myproject-client
    volumes:
      - /opt/myproject/nginx/conf:/etc/nginx

networks:
  myproject-network:

客户端的dockerfile

[
    {
        "Name": "myproject-network",
        "Id": "54955ca5c8fdd12185216afa155f71c1828cf745ca9943485f1f2f17ed77d6ac",
        "Created": "2018-09-27T21:23:19.516715853Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "10265fd53f07e01bc4625ca10e2015d8ecc309cad35b6fa35b32e03b5d26e170": {
                "Name": "nginx",
                "EndpointID": "2d4441f3e763fda797edfaeb30aa145f0d0e5ec744b8089a3ac0e0ce24658942",
                "MacAddress": "02:42:ac:12:00:04",
                "IPv4Address": "172.18.0.4/16",
                "IPv6Address": ""
            },
            "20c2f183cd8f8df72389aedaac71ffb722be88859973637d56d83193af0bdc3f": {
                "Name": "myproject-client",
                "EndpointID": "33165f9d2d1393c0afc1338e30dd5c6afd4c4f0ecd622818b8d74481ace60918",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            },
            "beaa5461033c8e4d1d704560e6b2b12e0b640346e9f13bac60958acecf8d7144": {
                "Name": "myproject-api",
                "EndpointID": "c25f6b5cd468a2d06b7ae0e74e5933131b975ed64a9cc402928272fbc5d5cc34",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "myproject",
            "com.docker.compose.project": "myproject",
            "com.docker.compose.version": "1.22.0"
        }
    }
]

API的dockerfile

FROM node:8.12-alpine
ADD . /opt/myproject
WORKDIR /opt/myproject
RUN yarn
RUN yarn run build
RUN npm install pm2 -g
EXPOSE 3000
CMD ["pm2-runtime","./dist/ssr-mat/index.js", "-i", "max"]

docker容器正常工作,客户端以及API和nginx我唯一不了解的问题是,为什么客户端容器不能使用网址调用API,而是可以使用其网络名称来调用它。

欢迎所有想法!

谢谢

0 个答案:

没有答案