I'm following the docker tutorial and I'm on part 4: swarms that involves setting up a swarm across two vm's. I think swarm is not mapping my container ports correctly. When I launch an app with swarm I cannot connect to my app when I try to visit the IP address provided by my VM. However, if I manually launch the app while SSH'd into the vm then I can access it.
The reason why I think swarm isn't mapping the ports correctly is because when I deployed the app via swarm I tried to view the port mappings of a container by doing something like docker port CONTAINER_NAME
nothing would be shown. After manually deploying and I run that command for a specified container I see something like 80/tcp -> 0.0.0.0:80
For example, here's what happens when I try to use curl
curl 192.168.99.100:80
curl: (7) Failed to connect to 192.168.99.100 port 80: Connection refused
I made this post a while back that goes into more detail, but that went unanswered and I think the new information I have might be more helpful.
What doesn't work
When I try to deploy w/ swarm docker stack deploy -c docker-compose.yml getstartedlab
I cannot connect to the app via a web browser or curl. I believe everything was deployed correctly because I can run docker stack ps getstartedlab
and view all of the services running and distributed between my two vm's.
What does work
I took down the stack with docker stack rm getstartedlab
then I ssh'd into the two vm's I created and manually launched the app specifying the port mapping like so:
docker run -p 80:80 -td myusername/get-started:part2
Then browsing to 192.168.99.100
I was able to see the app and no longer had the connection issues. I'm pretty sure this means it's a Docker issue, not a VM issue.
Other info - maybe useful
Here's my docker-compose.yml file. I tried the ports with both "4000:80" and "80:80"
version: "3"
services:
web:
image: myusername/get-started:part2
deploy:
replicas: 5
resources:
limits:
cpus: "0.1"
memory: 50M
restart_policy:
condition: on-failure
ports:
- "4000:80"
networks:
- webnet
networks:
webnet:
To sum it up I cannot access the app when I try to launch it with swarm. If I manually launch from within the VM and specify the port mapping (not using swarm) I can then access the app from the vm's IP.
Updates
I removed the running stack, restarted the VM's and relaunched with docker stack deploy -c docker-compose.yml getstartedlab
$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
4kn46vue9ka3 getstartedlab_web replicated 5/5 myusername/get-started:part2 *:4000->80/tcp
$ docker service ps 4kn46vue9ka3
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
a34u4jijc5d6 getstartedlab_web.1 myusername/get-started:part2 myvm1 Running Running 20 minutes ago
8fvukpo95ko4 getstartedlab_web.2 myusername/get-started:part2 myvm2 Running Running 20 minutes ago
lywca2zwtjfa getstartedlab_web.3 myusername/get-started:part2 myvm2 Running Running 20 minutes ago
u3cw40tjmujb getstartedlab_web.4 myusername/get-started:part2 myvm1 Running Running 20 minutes ago
c0tiyxu5o5x5 getstartedlab_web.5 myusername/get-started:part2 myvm2 Running Running 20 minutes ago
Here are the logs
$ docker service logs 4kn46vue9ka3
getstartedlab_web.4.u3cw40tjmujb@myvm1 | * Serving Flask app "app" (lazy loading)
getstartedlab_web.4.u3cw40tjmujb@myvm1 | * Environment: production
getstartedlab_web.4.u3cw40tjmujb@myvm1 | WARNING: Do not use the development server in a production environment.
getstartedlab_web.4.u3cw40tjmujb@myvm1 | Use a production WSGI server instead.
getstartedlab_web.4.u3cw40tjmujb@myvm1 | * Debug mode: off
getstartedlab_web.4.u3cw40tjmujb@myvm1 | * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
getstartedlab_web.1.a34u4jijc5d6@myvm1 | * Serving Flask app "app" (lazy loading)
getstartedlab_web.1.a34u4jijc5d6@myvm1 | * Environment: production
getstartedlab_web.1.a34u4jijc5d6@myvm1 | WARNING: Do not use the development server in a production environment.
getstartedlab_web.1.a34u4jijc5d6@myvm1 | Use a production WSGI server instead.
getstartedlab_web.1.a34u4jijc5d6@myvm1 | * Debug mode: off
getstartedlab_web.1.a34u4jijc5d6@myvm1 | * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
getstartedlab_web.3.lywca2zwtjfa@myvm2 | * Serving Flask app "app" (lazy loading)
getstartedlab_web.3.lywca2zwtjfa@myvm2 | * Environment: production
getstartedlab_web.3.lywca2zwtjfa@myvm2 | WARNING: Do not use the development server in a production environment.
getstartedlab_web.3.lywca2zwtjfa@myvm2 | Use a production WSGI server instead.
getstartedlab_web.3.lywca2zwtjfa@myvm2 | * Debug mode: off
getstartedlab_web.3.lywca2zwtjfa@myvm2 | * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
getstartedlab_web.2.8fvukpo95ko4@myvm2 | * Serving Flask app "app" (lazy loading)
getstartedlab_web.2.8fvukpo95ko4@myvm2 | * Environment: production
getstartedlab_web.2.8fvukpo95ko4@myvm2 | WARNING: Do not use the development server in a production environment.
getstartedlab_web.2.8fvukpo95ko4@myvm2 | Use a production WSGI server instead.
getstartedlab_web.2.8fvukpo95ko4@myvm2 | * Debug mode: off
getstartedlab_web.2.8fvukpo95ko4@myvm2 | * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
getstartedlab_web.5.c0tiyxu5o5x5@myvm2 | * Serving Flask app "app" (lazy loading)
getstartedlab_web.5.c0tiyxu5o5x5@myvm2 | * Environment: production
getstartedlab_web.5.c0tiyxu5o5x5@myvm2 | WARNING: Do not use the development server in a production environment.
getstartedlab_web.5.c0tiyxu5o5x5@myvm2 | Use a production WSGI server instead.
getstartedlab_web.5.c0tiyxu5o5x5@myvm2 | * Debug mode: off
getstartedlab_web.5.c0tiyxu5o5x5@myvm2 | * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
I ran this from both my local machine and within the vm, the results were the same
$ docker container exec getstartedlab_web.1.a34u4jijc5d69m7rqry1jpfo9 curl http://127.0.0.1
OCI runtime exec failed: exec failed: container_linux.go:348: starting container process caused "exec: \"curl\": executable file not found in $PATH": unknown
I also ran the swarm with only one node, still no luck connecting to 192.168.99.100/
$ docker-machine ssh myvm2
docker@myvm2:~$ docker swarm leave
Then back on my local machine
$ docker-machine stop myvm2
$ docker stack deploy -c docker-compose.yml getstartedlab
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
gjkde7aw2rznl9y68zti3lqrj * myvm1 Ready Active Leader 18.09.0
qu6qymppl1msxatll9m0sh7tn myvm2 Down Active 18.09.0
$ docker stack ps getstartedlab
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
vr0w3riw1cnz getstartedlab_web.1 myusername/get-started:part2 myvm1 Running Running 22 seconds ago
pvr93rqi64dw getstartedlab_web.2 myusername/get-started:part2 myvm1 Running Running 22 seconds ago
gucfa7asiwvx getstartedlab_web.3 myusername/get-started:part2 myvm1 Running Running 22 seconds ago
qzarr6jc5hzk getstartedlab_web.4 myusername/get-started:part2 myvm1 Running Running 22 seconds ago
p0hszupsl8wj getstartedlab_web.5 myusername/get-started:part2 myvm1 Running Running 22 seconds ago
I also checked the logs and there was no sign of myvm2 anywhere, as expected.
More Updates
I removed all images, containers, vm's, etc... and started the tutorial over from the start. To ensure that no old code/configurations were being used I named the vm myvm3 and the image is now getting-started-again. This time I only launched one vm as a single node cluster. Still no luck, I'm having the same "connection refused" error
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
myvm3 * virtualbox Running tcp://192.168.99.102:2376 v18.09.0
$ docker stack ps getstartedlab
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
hnbqdo9k3val getstartedlab_web.1 myusername/get-started-again:part2 myvm3 Running Running 7 minutes ago
bwc0ga954poo getstartedlab_web.2 myusername/get-started-again:part2 myvm3 Running Running 7 minutes ago
aleioewe4ivx getstartedlab_web.3 myusername/get-started-again:part2 myvm3 Running Running 7 minutes ago
fzys3tihrf0t getstartedlab_web.4 myusername/get-started-again:part2 myvm3 Running Running 7 minutes ago
4jyzzao11z96 getstartedlab_web.5 myusername/get-started-again:part2 myvm3 Running Running 7 minutes ago