How to Fix Docker 502 Bad Gateway on AWS EC2
The Root Cause On AWS EC2, a Docker 502 Bad Gateway primarily indicates that the upstream Docker container is either not running, has crashed, or is not listening on the port that the reverse proxy (e.g., Nginx, ALB/NLB) expects. Additionally, AWS Security Groups might be preventing the proxy or external traffic from reaching the EC2 instance’s exposed Docker port, leading to a connection refused error on the proxy side.
Quick Fix (CLI)
# 1. List all Docker containers to identify the problematic one and its status
sudo docker ps -a
# 2. Inspect logs of the stopped or unhealthy container for crash details or errors
# Replace <container_id_or_name> with the actual ID or name from `docker ps -a`
sudo docker logs <container_id_or_name>
# 3. If the container is stopped or recently crashed, attempt to restart it
sudo docker restart <container_id_or_name>
# 4. If restarting doesn't resolve the issue, verify resource usage (e.g., OOM kills)
sudo dmesg | grep -i "killed process"
Configuration Check
-
File to edit: Typically
/etc/nginx/sites-available/default(or a custom Nginx service configuration file) on your EC2 instance, and yourdocker-compose.ymlor thedocker runcommand used to start the container. -
Lines to change:
-
Nginx Reverse Proxy Configuration: Verify the
proxy_passdirective targets the correct host port exposed by your Docker container.# Example: /etc/nginx/sites-available/default server { listen 80; server_name your_domain.com your_ec2_ip; location / { # Ensure '8080' (or your designated port) matches the *host port* # where Docker exposes your container on the EC2 instance. proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # ... other proxy directives ... } } -
Docker Port Mapping: Ensure the Docker container is exposing its internal application port to the correct host port that Nginx (or your ALB/NLB) is configured to connect to.
- If using
docker run: Verify the-p host_port:container_portflag.sudo docker run -d -p 8080:3000 --name my-app my-image:latest(Here,8080is the host port Nginx should connect to, and3000is the port your application inside the container listens on.) - If using
docker-compose.yml: Verify theportssection for your service.
Ensure theservices: web: image: your_app_image ports: - "8080:3000" # host_port:container_porthost_port(e.g.,8080in these examples) in Docker’s mapping exactly matches the port specified in Nginx’sproxy_passdirective.
- If using
-
AWS Security Groups: In the AWS EC2 console, navigate to Security Groups. Select the Security Group associated with your EC2 instance. In the “Inbound rules” tab, confirm that the
host_port(e.g., 8080) is open to traffic from either0.0.0.0/0(for public access) or from your Load Balancer’s security group.
-
Verification
# 1. If Nginx configuration was changed, test its syntax and reload it
sudo nginx -t && sudo systemctl reload nginx
# 2. Verify the Docker container is now running and healthy
sudo docker ps
# 3. Attempt to access the application directly from the EC2 instance using curl
# Replace <docker_exposed_host_port> (e.g., 8080) with the actual host port
curl http://localhost:<docker_exposed_host_port>/
# Expected: Your application's HTTP response (e.g., HTML, JSON). If this works,
# but external access still fails, review AWS Security Groups and Load Balancer health checks.