DEV Community

Kelvin
Kelvin

Posted on • Updated on

Setup (Kong + Konga) as API Gateway

Welcome! You are about to start on a journey about and how to setup kong as an API Gateway for your infrastructure. In this second chapter, We are going to learn how to setup Kong and Konga. By the end of this series you are going to have your Kong and Konga running.

Table of Content

In this articles, i won't talk to much about why choose kong compare to another product. Tl;dr is because kong is open-source, has good community thanks to Kong Hub and it can be easily run using Docker because they have prebuilt image.

Prerequisites

Before jumping to how, you need to make sure you have this installed:

Kong

To run kong via docker-compose we need to prepare docker-compose (Kong + DB) because we want to run kong using database. There's 2 database that currently supported by kong (PostgreSQL + Cassandra). In this articles i'm going to configure it using PostgreSQL. First let's configure Postgres services.

Dockerfile

FROM postgres:9.6

COPY docker-entrypoint.sh /usr/local/bin/

ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["postgres"]
Enter fullscreen mode Exit fullscreen mode

If you're wondering why would we create our own postgres dockerfile instead directly using prebuilt images is because we need to load custom docker-entrypoint.sh which support create multiple initial user + database that later going to be used by (Kong + Konga), compare to prebuilt images where you can only create one user + one database. With this now our postgres can set environment like this:

environment:
 POSTGRES_USERS: username:password | username2:password 
 POSTGRES_DATABASES: dbname:username | dbname2:username2
Enter fullscreen mode Exit fullscreen mode

Now let's continue wrote our docker-compose.yml, let's create services called db and kong-migrations. In db we build from context instead of images, to make all of our container portable and prevent hardcoded config we make environment to refer our own defined variable called KONG_DB_USERNAME, KONG_DB_PASSWORD, KONGA_DB_USERNAME and KONGA_DB_PASSWORD.

docker-compose.yml

version: '3.7'
services:
    db:
        build:
          context: postgres
        environment:
          POSTGRES_USERS: ${KONG_DB_USERNAME}:${KONG_DB_PASSWORD}|${KONGA_DB_USERNAME}:${KONGA_DB_PASSWORD}
          POSTGRES_DATABASES: ${KONG_DB_NAME}:${KONG_DB_USERNAME}|${KONGA_DB_NAME}:${KONGA_DB_USERNAME}
        volumes:
        - persist_volume:/var/lib/postgresql/data
        networks:
        - kong-net

    kong-migrations:
      image: kong:latest
      entrypoint: sh -c "sleep 10 && kong migrations bootstrap -v"
      environment:
        KONG_DATABASE: ${KONG_DATABASE}
        KONG_PG_HOST: ${KONG_DB_HOST}
        KONG_PG_DATABASE: ${KONG_DB_NAME}
        KONG_PG_USER: ${KONG_DB_USERNAME}
        KONG_PG_PASSWORD: ${KONG_DB_PASSWORD}
      depends_on:
      - db
      networks:
      - kong-net
      restart: on-failure
Enter fullscreen mode Exit fullscreen mode

Before we run the actual kong we need to run kong migrations command first. Also if you're wondering why we add sleep on entrypoint it's because i encounter some issue before when i tried to follow tutorial from kong. Apparently this is because we tried to run migrations command but postgres container is not ready yet, to make it works i just add delay before executing migrations.

Don't forget to define network and volume at bottom or top part of docker-compose

volumes:
  persist_volume:

networks:
  kong-net:
    external: true
Enter fullscreen mode Exit fullscreen mode

Before run we need to set required environment by postgres and kong

.env

# KONG SETTING
KONG_DB_NAME=db_kong
KONG_DB_USERNAME=konguser
KONG_DB_PASSWORD=kongpassword
KONG_DB_HOST=db
KONG_DB_PORT=5432

# KONGA SETTING
KONGA_DB_NAME=db_konga
KONGA_DB_USERNAME=kongauser
KONGA_DB_PASSWORD=kongapassword
KONGA_DB_HOST=db
KONGA_DB_PORT=5432
Enter fullscreen mode Exit fullscreen mode

Now we can try run both container

docker network create kong-net
docker-compose up -d --build
Enter fullscreen mode Exit fullscreen mode

Let's add more stuff, this time we add services called kong.
docker-compose.yml

    kong:
      image: kong:latest
      environment:
        KONG_DATABASE: ${KONG_DATABASE}
        KONG_PG_HOST: ${KONG_DB_HOST}
        KONG_PG_DATABASE: ${KONG_DB_NAME}
        KONG_PG_USER: ${KONG_DB_USERNAME}
        KONG_PG_PASSWORD: ${KONG_DB_PASSWORD}
        KONG_PROXY_ACCESS_LOG: ${KONG_PROXY_ACCESS_LOG}
        KONG_ADMIN_ACCESS_LOG: ${KONG_ADMIN_ACCESS_LOG}
        KONG_PROXY_ERROR_LOG: ${KONG_PROXY_ERROR_LOG}
        KONG_ADMIN_ERROR_LOG: ${KONG_ADMIN_ERROR_LOG}
        #KONG_ADMIN_LISTEN: ${KONG_ADMIN_LISTEN}
      restart: on-failure
      ports:
      - $KONG_PROXY_PORT:8000
      - $KONG_PROXY_SSL_PORT:8443
        #- $KONG_PROXY_ADMIN_API_PORT:8001
        #- $KONG_PROXY_ADMIN_SSL_API_PORT:8444
      networks:
      - kong-net
Enter fullscreen mode Exit fullscreen mode

Don't forget to add more variable to our environment variable
.env

KONG_DATABASE=postgres
KONG_PROXY_ACCESS_LOG=/dev/stdout
KONG_ADMIN_ACCESS_LOG=/dev/stdout
KONG_PROXY_ERROR_LOG=/dev/stderr
KONG_ADMIN_ERROR_LOG=/dev/stderr
KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl

KONG_PROXY_PORT=8000
KONG_PROXY_SSL_PORT=8443
KONG_PROXY_ADMIN_API_PORT=8001
KONG_PROXY_ADMIN_SSL_API_PORT=8444
Enter fullscreen mode Exit fullscreen mode

Now let's run the whole compose (Postgres + Kong migrations + Kong)

docker-compose up -d --build
Enter fullscreen mode Exit fullscreen mode

Let's check our kong

curl -i http://localhost:8001/
Enter fullscreen mode Exit fullscreen mode

You should get some JSON response.

Konga

Some people might prefer interact with Kong Admin API through curl or Postman. But i'm more comfortable interacting through UI. Konga basically done this, they provide GUI for interacting with Kong Admin API.

Add Konga to Docker Compose

To setup Konga with Kong we need few more step, first we need to add Konga in our docker-compose and later we need to configure Kong Admin LoopBack.

Let's do the first step, add konga to our docker-compose.yml

    konga:
      image: pantsel/konga
      environment:
        TOKEN_SECRET: ${KONGA_TOKEN_SECRET}
        DB_ADAPTER: ${KONG_DATABASE}
        DB_HOST: ${KONGA_DB_HOST}
        DB_PORT: ${KONGA_DB_PORT}
        DB_DATABASE: ${KONGA_DB_NAME}
        DB_USER: ${KONGA_DB_USERNAME}
        DB_PASSWORD: ${KONGA_DB_PASSWORD}
        NODE_ENV: ${KONGA_ENV}
        KONGA_HOOK_TIMEOUT: 10000
      restart: on-failure
      ports:
      - $KONGA_PORT:1337
      depends_on:
      - db
      networks:
      - kong-net
Enter fullscreen mode Exit fullscreen mode

And also don't forget to add more variable to .env

KONGA_TOKEN_SECRET=some-secret-token
KONGA_ENV=development
KONGA_PORT=9000
Enter fullscreen mode Exit fullscreen mode

After everything configured now let's run our docker-compose again

docker-compose up -d --build
Enter fullscreen mode Exit fullscreen mode

Now you can go to your browser and open http://localhost:9000/

Konga would ask you to configure some credentials (Username + Password) that required to access Konga Web. After that they going to prompt how we want to communicate with Kong there's 3 available option:

  • Default (Not Recommended): Konga would access the Kong Admin API directly
  • Key Auth (Recommended): Konga would access Kong Admin API that run behind Kong (Loop-Back API) using configured Api Key.
  • JWT (Recommended): Konga would access Kong Admin API that run behind Kong (Loop-Back API) using JWT by using shared key and secrets.

In this article i would use the second method using Key Auth. Before we setup connection let's go back to access our Kong Admin API. Currently Kong Admin API is publicly accessible for those anyone who has access to the url which is dangerous for production environment. Now we need to protect Kong Admin API by running it behind Kong using LoopBack.

Setup Kong LoopBack

Thanks to Kong's routing design it's possible to serve Admin API itself behind Kong proxy.

To configure this we need to following steps:

  • Add Kong Admin API as services: You can import postman collection that i already create before or simply copy-paste following commands:
curl --location --request POST 'http://localhost:8001/services/' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "admin-api",
    "host": "localhost",
    "port": 8001
}'
Enter fullscreen mode Exit fullscreen mode
  • Add Admin API route: To register route on Admin API Services we need either service name or service id, you can replace the following command below:
curl --location --request POST 'http://localhost:8001/services/{service_id|service_name}/routes' \
--header 'Content-Type: application/json' \
--data-raw '{
    "paths": ["/admin-api"]
}'
Enter fullscreen mode Exit fullscreen mode

Now our Kong Admin API is running behind Kong Proxy, so in order to access it you need to :

curl localhost:8000/admin-api/
Enter fullscreen mode Exit fullscreen mode

Enable Key Auth Plugin

Our Admin API already run behind kong, but is not secured yet. In order to protect Kong Admin API we need to enable key auth plugin at service level by doing this commands.

curl -X POST http://localhost:8001/services/{service_id|service_name}/plugins \
    --data "name=key-auth" 
Enter fullscreen mode Exit fullscreen mode

Add Konga as Consumer

Our Admin API already run behind kong, but is not secured yet. In order to protect Kong Admin API we need to enable key auth plugin at service level by doing this commands.

curl --location --request POST 'http://localhost:8001/consumers/' \
--form 'username=konga' \
--form 'custom_id=cebd360d-3de6-4f8f-81b2-31575fe9846a'
Enter fullscreen mode Exit fullscreen mode

Create API Key for Konga

Using Consumer ID that generated when we're adding consumer, we will use that Consumer ID and generate API Key.

curl --location --request POST 'http://localhost:8001/consumers/e7b420e2-f200-40d0-9d1a-a0df359da56e/key-auth'
Enter fullscreen mode Exit fullscreen mode

Setup Connection

Now we're already have all required component to setup Konga connection
Konga Connection
Remember in picture above, because Kong and Konga are in the same network they can simply reach each other by using container name.

Repository

For those whose want simply clone it you can access this repository

FAQ

For those who encounter error below

Failed to seed User Error (E_UNKNOWN) :: Encountered an unexpected error
error: relation "public.konga_users" does not exist
Enter fullscreen mode Exit fullscreen mode

this is due to failed migration of konga container, to fix this, run following instruction below:

  • Stop all containers
docker-compose down
docker system prune --volumes ## optional!
Enter fullscreen mode Exit fullscreen mode
  • Modify .env and look for KONGA_ENV
KONGA_ENV=development
Enter fullscreen mode Exit fullscreen mode

If it's configured using production, Konga will not perform db migrations which the cause of the error above. So development should work and will trigger user migration for Konga. Now you should able to access it on localhost:9000 if you still use the default configuration.
konga-login

Support

If you find my articles or project is useful please support me through:

Buy Me A Coffee

Thank you very much

Api Gateway series

if you like to know other series please check out below:
*Introduction
*Setup Kong (This Articles)

Top comments (29)

Collapse
 
jamallmahmoudi profile image
jamallmahmoudi

Hi cool& perfect

Collapse
 
vousmeevoyez profile image
Kelvin

if this helps please support me so i can produce more quality content to help other developers
Buy Me A Coffee

Collapse
 
netanyahuisgay profile image
TechDebtDevin

Do not give this guy money for this guide until he improves it. I'd happily give him money to delete this fucking thing tbh.

Collapse
 
ayyappa99 profile image
Ayyappa

@vousmeevoyez : Unfortunately, running the same exact script giving below error
'FATAL: database "konguser" does not exist'

Collapse
 
vousmeevoyez profile image
Kelvin

Hi could you share more details? do you run it using start.sh? or just docker-compose?

Collapse
 
giesberge profile image
giesberge

I've tried from both and I have the same error,

Thread Thread
 
vousmeevoyez profile image
Kelvin

hi could you share your error?

Thread Thread
 
giesberge profile image
giesberge

database "konguser" does not exist. This is also after running a docker system prune:
pastebin.com/yJkp7BYK

Thread Thread
 
vousmeevoyez profile image
Kelvin

Hi giesberge can you try with this following sequence

  • docker system prune --volumes
  • mv .env.sample .env
  • update .env from
KONGA_ENV=production
Enter fullscreen mode Exit fullscreen mode

to

KONGA_ENV=development
Enter fullscreen mode Exit fullscreen mode
  • ./start.sh
  • go to localhost:9000

if this helps please support me so i can produce more quality content to help other developers
Buy Me A Coffee

Thread Thread
 
giesberge profile image
giesberge

Already done, I even tried changing the db_names but that didn't work. pastebin.com/wmcHb9Tw

Thread Thread
 
vousmeevoyez profile image
Kelvin

I've notice you're using windows. Did you use wsl? And what terminal are you running? Command prompt?

Collapse
 
ayyappa99 profile image
Ayyappa

I ran with start.sh script
Also what i noticed was the db name needs to be kong always else kong is throwing kong database doesn't exist.

Thread Thread
 
vousmeevoyez profile image
Kelvin

yes, I forgot to mention that in article. thanks man

Collapse
 
tiagosmx profile image
Tiago Stapenhorst Martins

Brilliant post dude! Your guide is valuable and well written.
I have been trying with no success to setup Kong and Konga with docker a while ago by following their git and official pages. Their documentation aren't very friendly indeed.
Thanks!

Collapse
 
tikam02 profile image
Tikam Singh Alma

I ran with start.sh script
db_1 | FATAL: database "konguser" does not exist

Collapse
 
vousmeevoyez profile image
Kelvin

Hi Tikam, sorry for slow response. Been very busy this couple months. try stop and clearing all volumes

docker-compose down
docker system prune --volumes
Enter fullscreen mode Exit fullscreen mode

also use this setting as .env

# KONG SETTING
KONG_DB_NAME=db_kong
KONG_DB_USERNAME=konguser
KONG_DB_PASSWORD=kongpassword
KONG_DB_HOST=db
KONG_DB_PORT=5432

KONG_DATABASE=postgres
KONG_PROXY_ACCESS_LOG=/dev/stdout
KONG_ADMIN_ACCESS_LOG=/dev/stdout
KONG_PROXY_ERROR_LOG=/dev/stderr
KONG_ADMIN_ERROR_LOG=/dev/stderr
KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl

KONG_PROXY_PORT=8000
KONG_PROXY_SSL_PORT=8443

# KONGA SETTING
KONGA_DB_NAME=db_konga
KONGA_DB_USERNAME=kongauser
KONGA_DB_PASSWORD=kongapassword
KONGA_DB_HOST=db
KONGA_DB_PORT=5432

KONGA_TOKEN_SECRET=some-secret-token
KONGA_ENV=production
KONGA_PORT=9000
Enter fullscreen mode Exit fullscreen mode
Collapse
 
tikam02 profile image
Tikam Singh Alma

Thank you so much @kelvin for the help.

Collapse
 
hendisantika profile image
Hendi Santika

Can We add all the env vars from .env file to docker-compose.yml file?

Collapse
 
vousmeevoyez profile image
Kelvin

yes you can

Collapse
 
hendisantika profile image
Hendi Santika

But, I tried it and it was failed. ENV not detected

Thread Thread
 
vousmeevoyez profile image
Kelvin

can you tried edit

    kong-migrations:
      image: kong:latest
      entrypoint: sh -c "sleep 10 && kong migrations bootstrap -v"
      environment:
        KONG_DATABASE: ${KONG_DATABASE}
        KONG_PG_HOST: ${KONG_DB_HOST}
        KONG_PG_DATABASE: ${KONG_DB_NAME}
        KONG_PG_USER: ${KONG_DB_USERNAME}
        KONG_PG_PASSWORD: ${KONG_DB_PASSWORD}
Enter fullscreen mode Exit fullscreen mode

to

    kong-migrations:
      image: kong:latest
      entrypoint: sh -c "sleep 10 && kong migrations bootstrap -v"
      env_file:
        - .env
      depends_on:
      - db
      networks:
      - kong-net
      restart: on-failure

    kong:
      image: kong:latest
      restart: on-failure
      env_file:
        - .env
      ports:
      - $KONG_PROXY_PORT:8000
      - $KONG_PROXY_SSL_PORT:8443
        #- $KONG_PROXY_ADMIN_API_PORT:8001
        #- $KONG_PROXY_ADMIN_SSL_API_PORT:8444
      networks:
      - kong-net

    konga:
      image: pantsel/konga
      env_file:
        - .env
      restart: on-failure
      ports:
      - $KONGA_PORT:1337
      depends_on:
      - db
      networks:
      - kong-net

Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
hendisantika profile image
Hendi Santika

localhost:9000/ doesn't show anything

Thread Thread
 
vousmeevoyez profile image
Kelvin

I'm helping software engineer around the world solving the hard problem so they can focus on the actual problem.

Please support me through link below so i can help other developers
buymeacoffee.com/kelvindsmn/

Collapse
 
netanyahuisgay profile image
TechDebtDevin

This is my third time writing this comment, the first two were too mean and somewhat stupid on my part. However, I do want to emphasize that this is not a great guide and you are far better off setting up Kong and Konga on your own via their docs. I really wish authors would delete these guides or improve them, its clear 90% of people hit very confusing errors following this process and wasted a ton of time in the process. Just read kong docs. Crazy this guy asks for people to give him money, please improve your guide or delete it @vousmeevoyez. Yes I'm getting the same error 50x that everyone else has described here, your recommended fixes are not fixes and only cause us to waste more time. Please please delete or fix. I really don't want to be mean or rude here but its hard to be nice when this guide caused me such a massive headache.

Collapse
 
fruitninja156 profile image
firew

Hey, I keep getting this error..

Image description

Collapse
 
vousmeevoyez profile image
Kelvin

Hi can you run the repo by executing the shell script?

./start.sh
Enter fullscreen mode Exit fullscreen mode
Collapse
 
fruitninja156 profile image
firew

Hey, sorry for the late response got that error while executing with ./start.sh

Collapse
 
amirhs712 profile image
amirhs712

where do I get docker-entrypoint.sh?

Collapse
 
vousmeevoyez profile image
Kelvin

Hi amirhs, terribly sorry for slow response. You can find the docker-entrypoint for the postgres container here github.com/vousmeevoyez/kong-konga...