Reputation: 1337
I've been following this tutorial on docker services and swarms. But I'm having some trouble with networking between different docker containers.
The following is my docker-compose.yml
file, it basically contains two services. One is just a redis image connected to two networks (although the second is useless for now). And the other is my application which needs to connect to redis. For that reason I opted to give the redis service a static IP.
version: "3"
services:
my_redis:
image: redis
ports:
- "6379:6379"
networks:
first_network:
ipv4_address: 172.20.1.1
second_network:
ipv4_address: 172.30.1.1
my_app:
build:
context: .
dockerfile: Dockerfile_my_app
image: my_app_image
depends_on:
- my_redis
deploy:
replicas: 1 # 4
networks:
- first_network
networks:
first_network:
ipam:
config:
- subnet: 172.20.1.0/24
second_network:
ipam:
config:
- subnet: 172.30.1.0/24
And the following is my Dockerfile for my_app
:
FROM python:3.7
WORKDIR /app
COPY . /app
RUN pip3 install --trusted-host pypi.python.org -r requirements.txt
CMD ip a && wait-for-it.sh 172.20.1.1:6379 && PYTHONPATH=. python3 my_app.py
Now the problem I'm having is that for some reason, my app cannot connect to the redis service. So I tried the following:
sudo docker run -p 6379:6379 redis
and then I used wait-for-it to make sure that localhost:6379
was up and running and it was.docker stack deploy
is creating the app service before the redis service, So I added the depends_on
part in the docker-compose
file.depends_on
only guarantees order of starting (not being ready, i.e. not running all commands before proceeding to next image) and that I have to find a different solution. Based on that I also changed the Dockerfile_my_app
to run wait-for-it
before it actually runs my app. Didn't work.Lastly, I didn't know what else to do, I ran ip a
to see if my_app
service is getting the right IP. and it is getting an IP in the right range:
my_test_my_app.1.jydyydckzyfh@snode-01 | 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
my_test_my_app.1.jydyydckzyfh@snode-01 | link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
my_test_my_app.1.jydyydckzyfh@snode-01 | inet 127.0.0.1/8 scope host lo
my_test_my_app.1.jydyydckzyfh@snode-01 | valid_lft forever preferred_lft forever
my_test_my_app.1.jydyydckzyfh@snode-01 | 1010: eth0@if1011: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default
my_test_my_app.1.jydyydckzyfh@snode-01 | link/ether 02:42:ac:14:01:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
my_test_my_app.1.jydyydckzyfh@snode-01 | inet 172.20.1.3/24 brd 172.20.1.255 scope global eth0
my_test_my_app.1.jydyydckzyfh@snode-01 | valid_lft forever preferred_lft forever
my_test_my_app.1.jydyydckzyfh@snode-01 | 1012: eth1@if1013: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
my_test_my_app.1.jydyydckzyfh@snode-01 | link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 1
my_test_my_app.1.jydyydckzyfh@snode-01 | inet 172.18.0.3/16 brd 172.18.255.255 scope global eth1
my_test_my_app.1.jydyydckzyfh@snode-01 | valid_lft forever preferred_lft forever
my_test_my_app.1.jydyydckzyfh@snode-01 | wait-for-it.sh: waiting 15 seconds for 172.20.1.1:6379
my_test_my_app.1.jydyydckzyfh@snode-01 | wait-for-it.sh: timeout occurred after waiting 15 seconds for 172.20.1.1:6379
So in short, IPs are getting assigned correctly. However, the my_app
service cannot connect to the redis
service. Is there any reason why? Am I missing something in the compose file?
Any help would be appreciated.
Upvotes: 4
Views: 3915
Reputation: 303
Try changing wait-for-it.sh 172.20.1.1:6379
in Dockerfile_my_app to:
wait-for-it.sh my_redis:6379
and see if that works.
Explanation: If i'm not wrong, once containers are part of the same network, they are able to communicate with each other via the service names declared in the docker-compose file.
See https://docs.docker.com/compose/compose-file/ under 'Networks' and https://docs.docker.com/compose/networking/ for detailed information
Upvotes: 8