Add Kong as Gateway

Now we want to protect our API with Kong as an API Gateway. To do this we will have to extend our docker-compose.yaml with three additional services.

Network

We want all our services to be part of one network. So we add a networks section to our docker-compose.yaml and attach our rove-api service to it.

Additionally we aim to access the API only through our API gateway, so we will have to remove the port-mapping from the service description of the rover-api service. The docker-compose.yaml should then look like this:

version: '3'

networks:
  kong-rover-demo:
    driver: bridge

services:
  rover-api:
    container_name: rover-api
    image: registry.gitlab.com/ngstmnn/go-rover:0.1.1-debug
    networks:
      - kong-rover-demo

Kong database

Kong stores its configuration about services, routes, plugins, etc. in a database. In this tutorial we use PostgreSQL. Kong would also work with cassandra or without any database. If you choose not to use a database Kong could not be configured using the Admin API (what we will do soon).

# ...
services:
  # ...
  kong-database:
    container_name: kong-database
    image: postgres:9.6
    restart: always
    networks:
      - kong-rover-demo
    environment:
      - POSTGRES_USER=kong
      - POSTGRES_DB=kong
      - PGDATA=/var/lib/postgresql/data/kong
    volumes:
      - ./data:/var/lib/postgresql/data/kong
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "kong", "-d", "kong"]
      interval: 10s
      timeout: 5s
      retries: 5

Kong database migration

The API gateway requires an existing schema in the database. When starting Kong with the parameter migrations bootstrap it will initialize this schema in an empty database. So this service will only check the database and migrate it if required and stop afterwards.

# ...
services:
  # ...
  kong-migration:
    container_name: kong-migration
    image: kong:1.3
    depends_on:
      - "kong-database"
    restart: on-failure
    networks:
      - kong-rover-demo
    environment:
      - KONG_DATABASE=postgres
      - KONG_PG_HOST=kong-database
      - KONG_PG_DATABASE=kong
    command: kong migrations bootstrap

Kong

The third service is the API gateway itself.

  kong:
    container_name: kong
    image: kong:1.3
    depends_on:
      - "kong-migration"
      - "kong-database"
    restart: always
    networks:
      - kong-rover-demo
    environment:
      - KONG_DATABASE=postgres
      - KONG_PG_HOST=kong-database
      - KONG_PG_DATABASE=kong
      - KONG_PROXY_LISTEN=0.0.0.0:8000
      - KONG_ADMIN_LISTEN=0.0.0.0:8001
    ports:
      - 80:8000
      - 8001:8001
    healthcheck:
      test: ["CMD-SHELL","curl -I -s -L http://localhost:8000 || exit 1"]
      interval: 5s
      retries: 10

Start the services

Once we have updated the docker-compose.yaml (this is how it should look now) we can start the services again with:

docker-compose up -d

If we now send a request as we did when we only had the API deployed we will receive the following answer from Kong:

{
  "message":"no Route matched with those values"
}

So we can’t access our API any more. To change this, we will have to add a service and a route to our API gateway.