How can I make curl http://barfoo:8002
work from the foobar-container, without making changes to the docker file?
I have the following compose file:
version: '3'
services:
foobar:
build:
context: ./foobar
ports:
- 8001:80
depends_on:
- barfoo
barfoo:
build:
context: ./barfoo
ports:
- 8002:80
And I added the following to my hosts file on my computer
127.0.0.1 foobar
127.0.0.1 barfoo
Now I start this project with docker-compose up
.
When I execute the following on my terminal, this logically works without any problem: curl http://barfoo:8002
When I do the same from a Bash in the foobar container (docker-compose exec foobar /bin/bash
) I get Failed to connect to barfoo port 8002: Connection refused
, If I use curl http://barfoo:80
it works.
The reason why is that I want to simulate a production like situation, where in production there is no port needed since they use a different hostname and both can use port 80 directly
How can I make curl http://barfoo:8002 work from the foobar-container, without making changes to the docker file?
Simple solution is to map host port 8002 to barfoo
port 8002. But that's probably not what you want.
barfoo
is service name registered in internal docker dns accessible only by the services (foobar
) within the same docker network created when you run docker-compose up
8002 is port mapped to the docker host.
So when you run curl http://barfoo:8002
from foobar
container you try to connect to service barfoo
to port 8002. However barfoo
listens on port 80 inside the container and not on 8002.
Another solution:
You can add network_mode: host
to barfoo
and foobar
.
foobar:
build:
context: ./foobar
network_mode: host
ports:
- 8001:80
depends_on:
- barfoo
barfoo:
build:
context: ./barfoo
network_mode: host
ports:
- 8002:80
But then foobar
would need to connect using localhost:8002
The reason why is that I want to simulate a production like situation, where in production there is no port needed since they use a different hostname and both can use port 80 directly
If that's really what you want, a better alternative would be to use docker stack.
And your services would be docker swarm services:
You can deploy them using:
docker deploy --compose-file path_to_compose_file
Then foobar
would connect to barfoo
using service name and port barfoo:80
For now, a possible workaround is to overwrite the command
in the docker-compose.yml so that it the process in it listens to port 8002 instead of 80.
version: '3'
services:
foobar:
build:
context: ./foobar
ports:
- 8001:80
depends_on:
- barfoo
barfoo:
build:
context: ./barfoo
ports:
- 8002:8002
command: 'some-service --port 8002'
But I would be more than happy to accept a better solution/answer for this one.
When you execute curl http://barfoo:8002
from your terminal, you are hitting the local port 8002 of your computer, which is forwarding port 80 of your container.
The foobar container, however, is hitting the container port directly, which is listening on port 80 alone.
You can achieve what you are trying to do by adding another container to the docker-compose.yaml, which will act as a reverse proxy in front of the barfoo container.
The new docker-compose will look something like this -
version: '3'
services:
foobar:
build:
context: ./foobar
ports:
- 8001:80
depends_on:
- barfoo
barfoo-host:
build:
context: ./barfoo
ports:
- 8002:80
barfoo:
image: custom-nginx:latest
And the custom-nginx image should be built like so -
FROM nginx:1.17-alpine
COPY nginx.conf /etc/nginx/
EXPOSE 8002
CMD ["nginx", "-g", "daemon off;"]
Using this as the nginx.conf
file -
user root;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile off;
access_log off;
keepalive_timeout 3000;
server {
listen 8002;
root /usr/share/nginx/html;
server_name barfoo;
location / {
proxy_pass http://barfoo-host;
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With