skip to Main Content

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: "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;
    }
}
  • 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.containers

I also send my requests from swagger and postman

2

Answers


  1. Chosen as BEST ANSWER

    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!


  2. 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
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search