在使用docker-compose发送请求时,遇到502连接被拒绝的错误。

huangapple go评论113阅读模式
英文:

502 connection refuse while sending requests from docker-compose

问题

我有一个在本地运行良好的golang应用程序(我发送请求并获得正确的响应)。但是当我尝试在带有nginx代理服务器的容器中运行此应用程序时,所有请求都返回502错误:

> [error] 31#31: *1 connect() failed (111: Connection refused) while
> connecting to upstream, client: 172.20.0.1, server:
> polygon.application.local, request: "GET /v1/credits HTTP/1.1",
> upstream: "http://172.20.0.5:8080/v1/credits", host:
> "polygon.application.local"

我尝试了谷歌上的不同解决方案来解决这个问题,但还没有解决。

这是我的配置:

  • docker-compose.yaml
version: "3.9"

services:
  nginx:
    image: nginx:alpine
    volumes:
      - ${PROJECT_DIR}/deployments/nginx.conf:/etc/nginx/conf.d/default.conf:delegated
      - ${PROJECT_DIR}/configs/ssl:/etc/nginx/ssl/:delegated
    ports:
      - "80:80"
      - "443:443"

  swagger_ui:
    image: swaggerapi/swagger-ui
    environment:
      SWAGGER_JSON: /spec/api.swagger.yaml
    volumes:
      - ${PROJECT_DIR}/api/openapi-spec/api.swagger.yaml:/spec/api.swagger.yaml

  credit_server:
    build:
      context: ..
      dockerfile: ${PROJECT_DIR}/deployments/Dockerfile
      args:
        BUILD_APP_NAME: credit-server
    depends_on:
      credit_service_db:
        condition: service_healthy

  credit_service_db:
    image: mysql:8.0
    container_name: credit_service_db
    restart: always
    environment:
      MYSQL_DATABASE: credit_service
      MYSQL_USER: credit_service
      MYSQL_PASSWORD: credit_service
      MYSQL_ROOT_PASSWORD: credit_service
    ports:
      - '3306:3306'
    expose:
      - '3306'
    healthcheck:
      test: [ 'CMD-SHELL', 'mysqladmin ping -h localhost' ]
      interval: 5s
      timeout: 20s
      retries: 10
  • nginx.conf
map $microservice $upstream {
    credits       credit_server:8080;
    swagger       swagger_ui:8080;
}

server {
    listen 443 http2 ssl;
    server_name polygon.application.local;
    server_tokens   off;
    client_max_body_size 16m;
    root /dev/null;
    resolver 127.0.0.11 valid=30s;

    ssl_certificate     /etc/nginx/ssl/crt.pem;
    ssl_certificate_key /etc/nginx/ssl/private.key.pem;

    location / {
        set $microservice "swagger";
        proxy_pass http://$upstream;
    }

    location ~ ^/v1/(?<microservice>[\w\-]+) {
        proxy_http_version 1.1;
        proxy_set_header    Host                $http_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-Proto   http;
        proxy_set_header    X-Frame-Options     SAMEORIGIN;

        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET,POST,PUT,DELETE,OPTIONS,PATCH';
            add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Access-Control-Allow-Headers,Access-Control-Allow-Origin,Authorization';
            add_header 'Access-Control-Max-Age' 1728000;
            add_header 'Content-Type' 'text/plain; charset=utf-8';
            add_header 'Content-Length' 0;
            return 204;
        }

        add_header 'X-Microservice' '$microservice';
        add_header 'X-Proxy-Pass' '$upstream';
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET,POST,PUT,DELETE,OPTIONS,PATCH';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Access-Control-Allow-Headers,Access-Control-Allow-Origin,Authorization';
        proxy_pass http://$upstream;
    }
}
  • credit_server的Dockerfile
FROM alpine:latest

ARG BUILD_APP_NAME

ENV PROJECT_DIR=/go

RUN apk add tzdata

COPY ./build/${BUILD_APP_NAME} ${PROJECT_DIR}/bin/app
COPY ./configs ${PROJECT_DIR}/configs
COPY ./internal/migrations ${PROJECT_DIR}/migrations

CMD ${PROJECT_DIR}/bin/app -c ${PROJECT_DIR}/configs/config.yml -m container -p ${PROJECT_DIR}/migrations/

所有容器都启动并且没有错误。在使用docker-compose发送请求时,遇到502连接被拒绝的错误。

我还从Swagger和Postman发送了请求。

英文:

I have a golang application that works well locally (I send requests and get the correct responses). But when I try to run this application in containers with nginx proxy server, I get a 502 error for all requests:

> [error] 31#31: *1 connect() failed (111: Connection refused) while
> connecting to upstream, client: 172.20.0.1, server:
> polygon.application.local, request: "GET /v1/credits HTTP/1.1",
> upstream: "http://172.20.0.5:8080/v1/credits", host:
> "polygon.application.local"

I have tried different solutions from Google to fix this problem, but have not fixed it yet.

There are my configs:

  • docker-compose.yaml
version: &quot;3.9&quot;

services:
  nginx:
    image: nginx:alpine
    volumes:
      - ${PROJECT_DIR}/deployments/nginx.conf:/etc/nginx/conf.d/default.conf:delegated
      - ${PROJECT_DIR}/configs/ssl:/etc/nginx/ssl/:delegated
    ports:
      - &quot;80:80&quot;
      - &quot;443:443&quot;

  swagger_ui:
    image: swaggerapi/swagger-ui
    environment:
      SWAGGER_JSON: /spec/api.swagger.yaml
    volumes:
      - ${PROJECT_DIR}/api/openapi-spec/api.swagger.yaml:/spec/api.swagger.yaml

  credit_server:
    build:
      context: ..
      dockerfile: ${PROJECT_DIR}/deployments/Dockerfile
      args:
        BUILD_APP_NAME: credit-server
    depends_on:
      credit_service_db:
        condition: service_healthy

  credit_service_db:
    image: mysql:8.0
    container_name: credit_service_db
    restart: always
    environment:
      MYSQL_DATABASE: credit_service
      MYSQL_USER: credit_service
      MYSQL_PASSWORD: credit_service
      MYSQL_ROOT_PASSWORD: credit_service
    ports:
      - &#39;3306:3306&#39;
    expose:
      - &#39;3306&#39;
    healthcheck:
      test: [ &#39;CMD-SHELL&#39;, &#39;mysqladmin ping -h localhost&#39; ]
      interval: 5s
      timeout: 20s
      retries: 10

  • nginx.conf
map $microservice $upstream {
    credits       credit_server:8080;
    swagger       swagger_ui:8080;
}

server {
    listen 443 http2 ssl;
    server_name polygon.application.local;
    server_tokens   off;
    client_max_body_size 16m;
    root /dev/null;
    resolver 127.0.0.11 valid=30s;

    ssl_certificate     /etc/nginx/ssl/crt.pem;
    ssl_certificate_key /etc/nginx/ssl/private.key.pem;

    location / {
        set $microservice &quot;swagger&quot;;
        proxy_pass http://$upstream;
    }

    location ~ ^/v1/(?&lt;microservice&gt;[\w\-]+) {
        proxy_http_version 1.1;
        proxy_set_header    Host                $http_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-Proto   http;
        proxy_set_header    X-Frame-Options     SAMEORIGIN;

        if ($request_method = &#39;OPTIONS&#39;) {
            add_header &#39;Access-Control-Allow-Origin&#39; &#39;*&#39;;
            add_header &#39;Access-Control-Allow-Methods&#39; &#39;GET,POST,PUT,DELETE,OPTIONS,PATCH&#39;;
            add_header &#39;Access-Control-Allow-Headers&#39; &#39;DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Access-Control-Allow-Headers,Access-Control-Allow-Origin,Authorization&#39;;
            add_header &#39;Access-Control-Max-Age&#39; 1728000;
            add_header &#39;Content-Type&#39; &#39;text/plain; charset=utf-8&#39;;
            add_header &#39;Content-Length&#39; 0;
            return 204;
        }

        add_header &#39;X-Microservice&#39; &#39;$microservice&#39;;
        add_header &#39;X-Proxy-Pass&#39; &#39;$upstream&#39;;
        add_header &#39;Access-Control-Allow-Origin&#39; &#39;*&#39;;
        add_header &#39;Access-Control-Allow-Methods&#39; &#39;GET,POST,PUT,DELETE,OPTIONS,PATCH&#39;;
        add_header &#39;Access-Control-Allow-Headers&#39; &#39;DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Access-Control-Allow-Headers,Access-Control-Allow-Origin,Authorization&#39;;
        proxy_pass http://$upstream;
    }
}
  • Dockerfile for the credit_server
FROM alpine:latest

ARG BUILD_APP_NAME

ENV PROJECT_DIR=/go

RUN apk add tzdata

COPY ./build/${BUILD_APP_NAME} ${PROJECT_DIR}/bin/app
COPY ./configs ${PROJECT_DIR}/configs
COPY ./internal/migrations ${PROJECT_DIR}/migrations

CMD ${PROJECT_DIR}/bin/app -c ${PROJECT_DIR}/configs/config.yml -m container -p ${PROJECT_DIR}/migrations/

All containers start and work without errors.在使用docker-compose发送请求时,遇到502连接被拒绝的错误。

I also send my requests from swagger and postman

答案1

得分: 0

你遇到的错误来自NGINX,看起来它找到了正确的容器进行通信,但是在该容器上的8080端口上没有任何监听。这可能是因为你配置了错误的监听端口,或者是因为应用程序需要一些时间启动,所以在NGINX尝试连接时它不接受连接。

尝试将depends_on声明放入nginx部分中:

depends_on:
  credit_server:
    condition: service_healthy
  swagger:
    condition: service_healthy
英文:

The error you are getting is coming from NGINX, looks like it is finding the correct container to talk to, but nothing is listening on port 8080 in that container. It could be because you have misconfigured the listening port or could be because the application takes some time to start up, so it is not accepting connections at the time NGINX is trying to connect.

Try putting depends_on declarations into nginx section

  depends_on:
    credit_server:
      condition: service_healthy
    swagger:
      condition: service_healthy

答案2

得分: 0

默认情况下,我的golang应用程序的rest-host是127.0.0.1或者只是localhost。但是在nginx中,我们指定了listen 80,这意味着0.0.0.0:80,当我将我的主机重写为0.0.0.0时,它将正常工作!

英文:

By default, my rest-host for the golang application was 127.0.0.1 or just localhost. But in nginx we specify listen 80, it means 0.0.0.0:80, and when I rewrote my host to 0.0.0.0, it will work!

huangapple
  • 本文由 发表于 2022年10月9日 01:26:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/73999118.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定