前端无法在单独的 docker 容器中到达后端端口

Posted

技术标签:

【中文标题】前端无法在单独的 docker 容器中到达后端端口【英文标题】:Frontend cannot reach backend port in separate docker containers 【发布时间】:2020-05-28 06:32:51 【问题描述】:

我的前端应用程序在 nginx 后面,它在 docker 容器中提供静态前端文件(用 Angular 编写),通信端口是 80:80。

我的后端应用是 NestJS,它在另一个 docker 容器中的 localhost:3000 端口上提供数据。

使用 docker-compose up 启动应用程序,但我的前端无法访问后端 - 得到 502,错误 GW。

问题是由 nginx 或 docker-compose.yml 或两者的设置引起的吗?

Dockerfile 前端:

FROM node:latest AS builder

WORKDIR /app
COPY . .
ARG configuration=production
RUN npm install && npm run build.prod

FROM nginx:latest
LABEL version="1.0"

COPY nginx.conf /etc/nginx/nginx.conf

WORKDIR /usr/share/nginx/html
COPY --from=builder /app/dist/frontend/ .

Dockerfile 后端:

FROM node:10 AS builder
WORKDIR /app
COPY ./package.json ./
RUN npm install
COPY . .
RUN npm run build
ADD . /app
EXPOSE 3000
CMD ["npm", "run", "start:prod"]

NGINX.conf

worker_processes  1;

events 
    worker_connections  1024;


http 
    server 
        listen 80;
        server_name  localhost;

        root   /usr/share/nginx/html;
        index  index.html index.htm;
        include /etc/nginx/mime.types;

        gzip on;
        gzip_min_length 1000;
        gzip_proxied expired no-cache no-store private auth;
        gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;

        location / 
            try_files $uri $uri/ /index.html;
        

        location /api 
            proxy_pass http://127.0.0.1:3000;
        

        location ~ \.html$ 
          add_header Cache-Control "private, no-cache, no-store, must-revalidate";
          add_header Expires "Sat, 01 Jan 2000 00:00:00 GMT";
          add_header Pragma no-cache;
        
    

docker-compose.yml

version: '3'

services:
  angular:
    image: "docker-frontend:v3"
    container_name: "frontend"
    ports:
      - "80:80"
    links:
      - restapi

  restapi:
    image: "docker-backend:v1"
    container_name: "backend"
    expose: 
      - 3000
    ports:
      - "3000:3000"

【问题讨论】:

你能在你的 Angular 应用中显示一个带有 url 的 http 请求吗? 另一个问题,您是否尝试从邮递员等外部软件调用您的端点? 请求是到 localhost/api/books [GET],响应是 502 bad gateway。我可以从主机(MacOS)访问 localhost:3000/api/books 没有任何问题。我认为问题是,在 nginx 后面我要去 localhost:3000 但它与运行后端容器的主机不是同一个 localhost。 你的意思是 localhost:3000/api/books 吗?请复制粘贴: const url = "localhost:3000/api/books"; const httpOptions = headers: new HttpHeaders( 'Content-Type': 'application/json' ) ;返回 this.httpClient.get(url, httpOptions); 我会尝试,但我不想在我的角度(前端)服务中指定端口,我只想使用 /api/books 之类的相对路径,然后在 nginx 上重定向每个请求到 /api/* 到 localhost:3000。 【参考方案1】:

你不能使用容器内的 localhost 连接到另一个容器,以实现你可以使用你的容器的名称

例如

http://localhost:3000/api/

http://backend:3000/api/

【讨论】:

明白,但是我必须在nginx conf文件中使用代理传递?因为我不想在我的角度服务中指定端口。 好的,所以我将位置更改为后端:3000 而不是本地主机,它可以工作。

以上是关于前端无法在单独的 docker 容器中到达后端端口的主要内容,如果未能解决你的问题,请参考以下文章

docker容器中的前端和后端[关闭]

怎么将更改elasticsearch服务端端口

无法访问本地主机上的 Docker 容器 [重复]

在单独的 docker 容器 (AWS ECS) 中连接到 MongoDB

UDP的协议格式及特性

UDP的协议格式及特性