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"]
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
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
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
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
Now we can try run both container
docker network create kong-net
docker-compose up -d --build
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
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
Now let's run the whole compose (Postgres + Kong migrations + Kong)
docker-compose up -d --build
Let's check our kong
curl -i http://localhost:8001/
You should get some JSON response.
Konga
- Add Konga to Compose
- Setup Kong LoopBack
- Enable Key Auth Plugin
- Add Konga as Consumer
- Create API Key for Konga
- Setup Connection
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
And also don't forget to add more variable to .env
KONGA_TOKEN_SECRET=some-secret-token
KONGA_ENV=development
KONGA_PORT=9000
After everything configured now let's run our docker-compose again
docker-compose up -d --build
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
}'
- 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"]
}'
Now our Kong Admin API is running behind Kong Proxy, so in order to access it you need to :
curl localhost:8000/admin-api/
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"
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'
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'
Setup Connection
Now we're already have all required component to setup 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
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!
- Modify .env and look for KONGA_ENV
KONGA_ENV=development
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.
Support
If you find my articles or project is useful please support me through:
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)
Hi cool& perfect
if this helps please support me so i can produce more quality content to help other developers
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.
@vousmeevoyez : Unfortunately, running the same exact script giving below error
'FATAL: database "konguser" does not exist'
Hi could you share more details? do you run it using start.sh? or just docker-compose?
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.
yes, I forgot to mention that in article. thanks man
I've tried from both and I have the same error,
hi could you share your error?
database "konguser" does not exist. This is also after running a docker system prune:
pastebin.com/yJkp7BYK
Hi giesberge can you try with this following sequence
to
if this helps please support me so i can produce more quality content to help other developers
Already done, I even tried changing the db_names but that didn't work. pastebin.com/wmcHb9Tw
I've notice you're using windows. Did you use wsl? And what terminal are you running? Command prompt?
I ran with start.sh script
db_1 | FATAL: database "konguser" does not exist
Hi Tikam, sorry for slow response. Been very busy this couple months. try stop and clearing all volumes
also use this setting as .env
Thank you so much @kelvin for the help.
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!
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.
Can We add all the env vars from .env file to docker-compose.yml file?
yes you can
But, I tried it and it was failed. ENV not detected
can you tried edit
to
localhost:9000/ doesn't show anything
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/
Hey, I keep getting this error..
Hi can you run the repo by executing the shell script?
Hey, sorry for the late response got that error while executing with ./start.sh
where do I get docker-entrypoint.sh?
Hi amirhs, terribly sorry for slow response. You can find the docker-entrypoint for the postgres container here github.com/vousmeevoyez/kong-konga...
Some comments have been hidden by the post's author - find out more