1

I have a few simple REST api services implemented in Express.These services run in docker containers in a swarm mode.Also,I am trying to use express-api gateway with these services.The express api gateway also runs in a container as part of the docker swarm.Following is the Dockercompose file

 version: "3"
services:
  firstService:
    image: chaitanyaw/firstrepository:first
    deploy:
      replicas: 3
      restart_policy:
        condition: on-failure
    ports:
        - '3000:3000'
    networks:
      - webnet
  apiGateway:
    image: firstgateway:latest
    deploy:
      restart_policy:
        condition: on-failure
    ports:
      - '80:80'
    networks: 
      - webnet
  visualizer:
    image: dockersamples/visualizer:latest
    ports:
     - 8080:8080
    volumes: 
      - /var/run/docker.sock:/var/run/docker.sock
    deploy:
      placement:
         constraints: [node.role == manager]
    networks:
      - webnet
networks:
  webnet:

also, following is the gateway.config file

http:
  port: 80
admin:
  port: 9876
  hostname: localhost
apiEndpoints:
  api:
    host: 192.168.99.100
    paths: '/ip'
  localApi:
    host: 192.168.99.100
    paths: '/'
serviceEndpoints:
  httpbin:
    url: 'https://httpbin.org'
  services:
    urls:
      - 'http://192.168.99.100:3000/serviceonerequest'
      - 'http://192.168.99.100:3000/servicetwo'
policies:
  - basic-auth
  - cors
  - expression
  - key-auth
  - log
  - oauth2
  - proxy
  - rate-limit
pipelines:
  default:
    apiEndpoints:
      - api
    policies:
    # Uncomment `key-auth:` when instructed to in the Getting Started guide.
    # - key-auth:
      - proxy:
          - action:
              serviceEndpoint: httpbin 
              changeOrigin: true
  customPipeline:
    apiEndpoints:
      - localApi
    policies:
      - proxy:
        - action:
            serviceEndpoint: services
            changeOrigin: true

The ip '192.168.99.100' is the docker-machine ip. If I run the stack using the above gateway.config file, everything works fine. However,IF I replace

services:
    urls:
      - 'http://192.168.99.100:3000/serviceonerequest'
      - 'http://192.168.99.100:3000/servicetwo'

with

services:
    urls:
      - 'http://services_firstService:3000/serviceonerequest'
      - 'http://services_firstService:3000/servicetwo'

I get a bad gateway! This docker swarm runs an overlay network "webnet".So,I must be able to use the service name as the hostname in the gateway.config file according to this link. In the above working case with the use of IP the services become available 'outside' of the gateway which I do not desire. What is wrong?

user1261913
  • 325
  • 4
  • 18

2 Answers2

2

SO I have found where I was going wrong!Look at the compose file above!The service names are firstService (a capital S!). Now, if I used

urls:
      - 'http://services_firstService:3000/serviceonerequest'
      - 'http://services_firstService:3000/servicetwo'

the API gateway would keep looking for services_firstservice (Note the small 's' in firstService) which obviously is not present in the overlay network! Now,I changed the names to small case and it works just as expected! Here is the new Docker-compose file

version: "3"
services:
  firstservice:
    image: chaitanyaw/firstrepository:first
    deploy:
      replicas: 3
      restart_policy:
        condition: on-failure
    networks:
      - webnet
  apigateway:
    image: firstgateway:latest
    deploy:
      restart_policy:
        condition: on-failure
    ports:
      - '80:80'
    networks: 
      - webnet
  visualizer:
    image: dockersamples/visualizer:latest
    ports:
     - 8080:8080
    volumes: 
      - /var/run/docker.sock:/var/run/docker.sock
    deploy:
      placement:
         constraints: [node.role == manager]
    networks:
      - webnet
networks:
  webnet:

Also,here is the gateway.config file

http:
  port: 80
admin:
  port: 9876
  hostname: localhost
apiEndpoints:
  api:
    host: 192.168.99.100
    paths: '/ip'
  localApi:
    host: 192.168.99.100
    paths: '/'
serviceEndpoints:
  httpbin:
    url: 'https://httpbin.org'
  services:
    urls:
      - 'http://services_firstservice:3000/serviceonerequest'
      - 'http://services_firstservice:3000/servicetwo'
policies:
  - basic-auth
  - cors
  - expression
  - key-auth
  - log
  - oauth2
  - proxy
  - rate-limit
pipelines:
  default:
    apiEndpoints:
      - api
    policies:
    # Uncomment `key-auth:` when instructed to in the Getting Started guide.
    # - key-auth:
      - proxy:
          - action:
              serviceEndpoint: httpbin 
              changeOrigin: true
  customPipeline:
    apiEndpoints:
      - localApi
    policies:
      - proxy:
        - action:
            serviceEndpoint: services
            changeOrigin: true
user1261913
  • 325
  • 4
  • 18
0

From a Gateway perspective, there's nothing wrong in the configuration. As long the DNS name can be resolved correctly, the request should go through with no problem.

What I would try to do is to log in the Gateway container and try to ping the two services. If something goes wrong, then most likely the docker-compose.yml file has some problem.

I'd try to remove the network key, for example. The network is implicitly created so you do not really need that part.

Also — I do not think that the DNS name for the service is services_firstService; I'd try with firstService directly.

Cheers,

V.

Vincenzo
  • 1,549
  • 1
  • 9
  • 17