I have two different services:
- account-generator: FastAPI app
- money-tracker: split into a golang backend and a react frontend.
Additionally I have a set up also an NGINX proxy in order to manage all the requests.
My docker-compose.yml
version: '3.9'
services:
backend:
container_name: myexample-backend
build:
context: backend
command: ["air", "migrate", "&&", "air", "serve"]
env_file:
- backend/.env
ports:
- "18001:18001"
volumes:
- ./certbot/conf/:/etc/nginx/ssl/
networks:
myexample-webserver-network: {}
frontend:
container_name: myexample-frontend
build:
context: frontend
dockerfile: Dockerfile
env_file:
- frontend/.env-prod
command: ["npm", "run", "start:prod"]
ports:
- "13001:3000"
networks:
myexample-webserver-network: {}
stdin_open: true
account-generator:
build:
context: myexample-account-generator
command: [ "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "18010" ]
env_file:
- .env
ports:
- "18010:18010"
networks:
myexample-webserver-network: { }
webserver:
container_name: myexample-nginx-production
image: nginx
volumes:
- ./nginx/conf/production.conf:/etc/nginx/conf.d/default.conf
ports:
- "80:80"
- "443:443"
depends_on:
- backend
- frontend
- myexampleapp
networks:
myexample-webserver-network: {}
networks:
myexample-webserver-network:
external: true
And my nginx.conf
server {
listen 80;
listen [::]:80;
root /var/www/html;
server_name myexampledomain.com www.myexampledomain.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://myexampledomain.com$request_uri;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
root /var/www/html;
server_name myexampledomain.com www.myexampledomain.com;
keepalive_timeout 65;
proxy_connect_timeout 600;
proxy_read_timeout 600;
proxy_send_timeout 600;
ssl_certificate /etc/nginx/ssl/live/myexampledomain.com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/myexampledomain.com/privkey.pem;
location / {
proxy_pass http://money-tracker:18010;
}
}
server {
listen 80;
listen [::]:80;
root /var/www/html;
server_name money-tracker.myexampledomain.com www.money-tracker.myexampledomain.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://money-tracker.myexampledomain.com$request_uri;
}
location /api {
return 301 https://money-tracker.myexampledomain.com/api$request_uri;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
root /var/www/html;
server_name localhost money-tracker.myexampledomain.com www.money-tracker.myexampledomain.com;
keepalive_timeout 65;
proxy_connect_timeout 600;
proxy_read_timeout 600;
proxy_send_timeout 600;
ssl_certificate /etc/nginx/ssl/live/money-tracker.myexampledomain.com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/money-tracker.myexampledomain.com/privkey.pem;
location / {
proxy_pass http://frontend:3000;
}
location /api {
chunked_transfer_encoding off;
proxy_pass http://backend:18001;
}
}`
I am running these services in an EC2 instance, purchased a domain and have all the required DNS records configured both in my domain provider and in Route 53.
I want to run the account-generator service on the domain (myexampledomain.com) and the money-tracker service on the subdomain (money-tracker.myexampledomain.com).
So far this works flawlessly but, whenever I try to call from money-tracker frontend money-tracker.myexampledomain.com) the money-tracker backend (money-tracker.myexampledomain.com/api), I am getting a 502 error. Also, if I try to reach from the outside (Postman or Imnsomnia) I am also getting a 502 error.
Interestingly the containers are healthy since if I ssh to the EC2 instance, I can curl the backend and it is receiving the requests.
I have tried editing the compose file, the NGINX conf file, /etc/hosts file, etc. But nothing seems to work.
Hopefully someone can help me. Thanks in advance.
2
Answers
Tried lots of stuff for days and in the end the solution I came up with was to use the private IP alongside the port rather than the container name.
Hope it helps.
Verify that the backend container is running and listening on port 18001. You can do this by logging into the container and running netstat -tln.
Is accessing the backend service directly by ip address working? if yes, there might be the issue with dns resolution.
You also might check nginx logs, you might find errors related to timeouts. try increasing the timeout values for proxy_connect_timeout, proxy_read_timeout or proxy_send_timeout
Also check if aws firewal is not blocking the traffic. the ports should be open for backend and frontend.
May be try the simple configuration first without ssl , proxy and then enable one by one as you get success.
Its difficult to come up to the exact issue. but I think if you check these you might find the root cause.