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.
I also send my requests from swagger and postman
2
Answers
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!
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