Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker swarm not exposing port

I'm trying to run docker swarm on a single node and having trouble getting a docker app port exposed to the host.

This is similar Docker swarm service port not exposed but I'm running in a single node, and provide more detail on my question and research.

For example, given the following myapp.yml file:

version: "3"
services:
  app:
    image: myapp
    ports: 
      - "8123:8123"

The stack is started via

docker stack deploy -c myapp.yml myapp

After the stack is started, when I try to access the port (via curl) it fails. For example,

curl -v http://localhost:8123/myapp

shows the connection was refused (nothing was listening on that port).

Code works when using docker run

The following command starts the image and shows how to verify the port is exposed.

docker run -p 8123:8123 --name myapp myapp

Curl then works.

curl -v http://localhost:8123/myapp

Gives output from the app running in docker.

When I run docker ps the output in the PORTS section shows: 0.0.0.0:8123:8123/tcp.

docker network inspect bridge - Show that the docker container is assigned to the bridge network. The docker bridge network is used by default with the docker run command.

The command docker port myapp shows:

8123/tcp -> 0.0.0.0:8123

which matches the output from docker ps PORT field.

docker stack deploy doesn't expose port

After starting using docker stack deploy -c myapp.yml myapp, I run the docker ps command and only see 8123/tcp in the PORTS field of the output.

The command docker port myapp has no output (indicating no ports are available from the docker host.

When I run docker network ls, I see:

NETWORK ID       NAME            DRIVER     SCOPE
1234567890      bridge           bridge     local
9999999999      myapp_default   overlay    swarm

So I noticed that the network myapp_default is in a different mode than bridge, local. I tried using existing bridge network but when I refereed to the bridge network in my stack/compose file I observed that the network myapp_bridge was created.

So I read up on docker networking https://blog.alexellis.io/docker-stacks-attachable-networks/ was a good writeup.

So far I haven't gotten it to work so I drafted this to ask for suggestions/help.

NOTE: This aricle (dated Feb 2017) says it should work but doesn't address my question.

I think I'm close.

Resources and other related questions

https://docs.docker.com/v17.12/get-started/part5/ - is the docker primary documentation for the docker stack technology. But searches on that page for networks shows nothing useful.

https://blog.alexellis.io/docker-stacks-attachable-networks/ - Good write up.

Docker swarm service port not exposed - similar to the question I'm asking.

https://runnable.com/docker/basic-docker-networking - Write up on docker networking. It says the following when creating an overlay network (which is the default when docker stack deploy is used).

These networks require a valid key-value store service, such as Consul, Etcd, or ZooKeeper. You must install and configure your key-value store service before creating your network.

Can not use user-defined bridge in swarm compose yaml file.

like image 752
PatS Avatar asked Jan 29 '19 00:01

PatS


2 Answers

In swarm

ports:
  - "8123:8123"

will expose port on all swarm nodes and in case of use of the port on some of the nodes by another service you can have problems

you can expose port only on host with container with next docker-compose.yml config

services:
  app:
    ports:
      - target: 8123
        published: 8123
        mode: host
like image 109
Ryabchenko Alexander Avatar answered Nov 12 '22 20:11

Ryabchenko Alexander


You should define a network for your services. In Docker Swarm mode, the docker container becomes 'Service', to access its port, you call to the Service's name I provide you an example of docker-compose file how to connect nginx and php-fpm

version: '3.2'
  services:
    nginx:
      image: nginx
      links:
      - php
      - mariadb:mysql
      ports:
      - "8880:80"
      networks:
      - frontend
      deploy:
        #mode: replicated
        replicas: 1
        placement:
          constraints: [node.role == manager]
    php:
       image: php
       deploy:
         #mode: replicated
         replicas: 1
         placement:
           constraints: [node.role == manager]
           #endpoint_mode: dnsrr
       links:
         - mariadb:mysql
    mariadb:
       image: mariadb:10.4.1
       #restart: always
       deploy:
         mode: replicated
         replicas: 1
         #placement:
         #constraints: [node.role == manage]
         environment:
           MYSQL_ROOT_PASSWORD: SECRET          
         volumes:
           - type: volume
              source: mydatabase
              target: /var/lib/mysql/data
              volume:
                nocopy: true # do not copy data from container when a volume is created?
    networks:
      frontend  
    volumes:
      mydatabase:

After you deployed (docker stack deploy -c docker-compose.yaml) , to see list of Services:

docker service ls 

To guild nginx how to access your php-fpm backend, edit your nginx configuration file :

location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass **NAME_OF_PHP_SERVICE_IN SWARM**:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

Instead of putting your container's IP address ( IP:9000 ) , you put the name of the php Service in your Swarm cluster

like image 30
Dylan B Avatar answered Nov 12 '22 19:11

Dylan B