Docker+Nginx反向代理出现502 Bad Gateway问题求助
Hey there! Let's work through your Docker + HTTPS multi-site issues step by step—these are super common pitfalls for folks getting started, so we’ll get you sorted.
First: Fixing the SSL Certificate Issue (localhost isn’t a valid domain)
You’re right that localhost can’t get a trusted public SSL certificate. Here are two solid solutions depending on whether you’re testing locally or deploying to a live server:
For Local Testing
Use mkcert to generate locally trusted SSL certificates (no browser warnings, works just like real certs):
- Install mkcert: On Ubuntu run
sudo apt install mkcert, on Mac usebrew install mkcert, or grab binaries from its repo. - Set up the local root CA: Run
mkcert -install(this adds a trusted root to your system/browsers). - Generate certs for your test domain (e.g.,
example.test):mkcert example.test *.example.test - Mount these certs into your Nginx proxy container. Your docker-compose should include a volume like:
Make sure the cert filenames match your domain (e.g.,volumes: - ./path/to/your/certs:/etc/nginx/certsexample.test.pemandexample.test-key.pem—mkcert uses this naming by default).
For Live Production (Real Domain)
Use the jrcs/letsencrypt-nginx-proxy-companion alongside jwilder/nginx-proxy to auto-generate Let’s Encrypt certs:
- Add both services to your docker-compose:
services: nginx-proxy: image: jwilder/nginx-proxy ports: - "80:80" - "443:443" volumes: - /var/run/docker.sock:/tmp/docker.sock:ro - ./certs:/etc/nginx/certs - ./vhost:/etc/nginx/vhost.d - ./html:/usr/share/nginx/html letsencrypt-companion: image: jrcs/letsencrypt-nginx-proxy-companion volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./certs:/etc/nginx/certs - ./vhost:/etc/nginx/vhost.d - ./html:/usr/share/nginx/html environment: - NGINX_PROXY_CONTAINER=nginx-proxy - For each of your website containers, add these environment variables:
This tells the companion to request and renew certs automatically.environment: - VIRTUAL_HOST=your-real-domain.com - LETSENCRYPT_HOST=your-real-domain.com - LETSENCRYPT_EMAIL=your-email@domain.com
Next: Fixing the 502 Bad Gateway Error
502s almost always mean Nginx can’t reach your backend container. Let’s check the most likely culprits:
1. Ensure All Services Share the Same Docker Network
Docker’s default bridge network has DNS limitations. Create a custom network and add every service (including the Nginx proxy) to it:
- First, create the network:
docker network create web-network - In your docker-compose.yml, add this to every service (proxy + website containers):
networks: - web-network - At the bottom of your docker-compose, define the network:
This lets Nginx resolve container names directly (e.g.,networks: web-network: external: truehttp://php-container:80will work).
2. Verify Your Backend Container’s Listening Port
If you tried VIRTUAL_PORT=80 and it didn’t work, double-check what port your container is actually listening on:
- Run
docker inspect <your-container-name>and look forNetworkSettings -> Ports—this shows published ports, but to check internal listening: - Exec into the container and run:
docker exec -it <your-container-name> netstat -tulpn- If you’re running a PHP-FPM-only container, it’ll listen on port 9000, not 80. In this case, your Nginx config needs to use
fastcgi_passinstead ofproxy_pass(proxy_pass is for HTTP services like Nginx in a container). - Example fastcgi config block for PHP-FPM:
location ~ \.php$ { fastcgi_pass php-container:9000; fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name; include fastcgi_params; }
- If you’re running a PHP-FPM-only container, it’ll listen on port 9000, not 80. In this case, your Nginx config needs to use
3. Check Nginx Proxy’s Generated Config
Look at the auto-generated Nginx config file (usually in /etc/nginx/vhost.d/your-domain.com inside the proxy container) and confirm:
- The
upstreamblock points to your container’s name/IP and correct port. - For HTTP backends,
proxy_pass http://container-name:portis present. - For PHP-FPM backends,
fastcgi_pass container-name:9000is used instead.
4. Check Proxy Logs for Clues
Run this to tail the Nginx proxy’s error logs—they’ll tell you exactly why the connection failed:
docker logs -f nginx-proxy
Common errors to look for:
connect() failed (111: Connection refused): Backend container isn’t listening on the port you specified.no resolver defined to resolve container-name: Containers aren’t on the same network.
Quick Recap of Steps to Test
- Confirm all containers are on the same custom Docker network.
- Verify your backend container is listening on the correct port (80 for HTTP, 9000 for PHP-FPM).
- Match Nginx’s proxy config to the backend type (proxy_pass vs fastcgi_pass).
- Use appropriate SSL certs (mkcert for local, Let’s Encrypt for live).
内容的提问来源于stack exchange,提问作者Bigbenny

