I'm using docker-compose.yml for a couple services behind an nginx proxy on a Ubuntu VPS.
I'm having the issue where my Docker containers cannot reach each other using their publicly available proxy URLs. They can only reach each other using their Docker service names.
The easiest way to demonstrate is as follows. I can connect to my PostgreSQL instance from anywhere with the following:
psql -Atx postgres://username:pw@postgres.mysite.com/database
But if I enter one of my running containers:
docker compose exec backend sh
Then try to connect using the same connection string, it just hangs... There aren't any logs, even on the proxy side. But, I can make it work by using the Docker service name instead:
psql -Atx postgres://username:pw@postgres:5432/database
I should be able to use postgres.mysite.com
from anywhere, outside or inside the container. But for some reason, I can only use it outside the container. Here's the nginx configuration section for this:
upstream docker-postgres {
server postgres:5432;
}
server {
listen 443 ssl;
server_name postgres.mysite.com;
location / {
proxy_pass http://docker-postgres;
}
}
But this is not related to PostgreSQL. This appears to be happening regardless of the service. Whenever container A (the app code) tries to connect to container B (the service) by using the publicly available URL of the proxy running in container C.
For example, for my MinIO service, uploads hang when uploading to https://assets.mysite.com
, but not when uploading to http://minio:9001
.
Partial docker-compose.yml file:
proxy:
image: nginx:alpine
ports:
- '80:80'
- '443:443'
networks:
- myNetwork
backend:
ports:
- '3000:3000'
volumes:
- ./:/app
- /app/node_modules
networks:
- myNetwork
postgres:
image: postgres:10.4
ports:
- "5432:5432"
networks:
- myNetwork
minio:
image: minio/minio
command: server --console-address ":9090" --address ":9001" ./minio_data
ports:
- '9090:9090'
- '9001:9001'
networks:
- myNetwork
networks:
myNetwork:
external: true
Additional Information
I set up a /test endpoint in the proxy under the assets.mysite.com
server_name.
location /test { return 200 'success!!'; }
I can hit this endpoint from the server (outside a Docker container):
curl https://assets.mysite.com/test
→ Success
However, I can't hit it from inside any container:
docker compose exec backend curl https://assets.mysite.com/test
→ Hangs!
Despite that, I can ping assets.mysite.com
successfully, even from the containers:
docker compose exec backend ping assets.mysite.com
Here's nearly my whole nginx configuration as requested (just SSL certificates omitted)
http {
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
location / {
return 301 https://$host$request_uri;
}
}
upstream docker-backend {
server backend:9000;
keepalive 100;
}
upstream docker-postgres {
server postgres:5432;
}
upstream docker-redis {
server redis:6379;
}
upstream docker-minio-assets {
server minio:9001;
}
server {
listen 443 ssl;
server_name mysite.com;
root /var/www/frontend;
index index.html;
location /test {
return 200 'success!!';
}
location /backend {
rewrite ^/backend(/.*)$ $1 break;
proxy_pass http://docker-backend;
proxy_set_header Host $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 $scheme;
proxy_pass_request_headers on;
client_max_body_size 3m;
}
location / {
include /etc/nginx/mime.types;
try_files $uri $uri/ /index.html =404;
}
}
server {
listen 443 ssl;
server_name shopadmin.mysite.com;
root /var/www/admin;
index index.html;
location /a/ {
try_files $uri /index.html;
}
location / {
include /etc/nginx/mime.types;
try_files $uri /index.html =404;
}
}
server {
listen 443 ssl;
server_name assets.mysite.com;
client_max_body_size 20m; # Allow bigger file uploads.
location /test {
return 200 'success!!';
}
location / {
proxy_pass http://docker-minio-assets;
}
}
server {
listen 443 ssl;
server_name redis.mysite.com;
location / {
proxy_pass http://docker-redis;
}
}
server {
listen 443 ssl;
server_name postgres.mysite.com;
location / {
proxy_pass http://docker-postgres;
}
}
}