I’m using docker-compose.yml for a couple services behind an nginx proxy.
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 Postgres instance from anyhere with the following:
psql -Atx postgres://username:[email protected]/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… No 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 config 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 postgres. 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:
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
2
Answers
Update the DNS configuration of your Docker containers to use a DNS resolver which should resolve the domain names correctly. Then specify the DNS resolver in the
docker-compose.yml
file for each service by adding the dns option under the service definition.Now this could be completely wrong for your scenario, but I have run into such issues on both Windows and macOS host computers. In both cases they caused me days of pain.
WINDOWS
I had a flaky Kubernetes connectivity problem using KIND and a docker network. I had to use an external URL for a cloud authorization server. Eventually the fix was to add DNS entries to the computer’s intenet connection:
macOS
I had a similarly annoying Android problem in this answer, which also took days to overcome.
SUMMARY
You may be running into the same kind of developer specific issue I did, with cryptic results that probably will not apply to your deployed systems. Otherwise just discard my answer. You should update your question with the host OS you are using though.