others-How to install kong api gateway on linux using docker?

1. Purpose

In this post, I would demo how to solve the following error when installing kong api gateway using docker:

2021/11/11 11:12:27 [error] 1#0: init_by_lua error: /usr/local/share/lua/5.1/kong/init.lua:524: error parsing declarative config file /usr/local/kong/declarative/kong.yml:
/usr/local/kong/declarative/kong.yml: No such file or directory
stack traceback:
	[C]: in function 'error'
	/usr/local/share/lua/5.1/kong/init.lua:524: in function 'init'
	init_by_lua:3: in main chunk
nginx: [error] init_by_lua error: /usr/local/share/lua/5.1/kong/init.lua:524: error parsing declarative config file /usr/local/kong/declarative/kong.yml:
/usr/local/kong/declarative/kong.yml: No such file or directory
stack traceback:
	[C]: in function 'error'
	/usr/local/share/lua/5.1/kong/init.lua:524: in function 'init'
	init_by_lua:3: in main chunk

Or this error:

2021/11/11 11:18:37 [error] 1#0: init_by_lua error: /usr/local/share/lua/5.1/kong/init.lua:524: error parsing declarative config file /usr/local/kong/declarative/kong.yml:
failed parsing declarative configuration: expected an object
stack traceback:
	[C]: in function 'error'
	/usr/local/share/lua/5.1/kong/init.lua:524: in function 'init'
	init_by_lua:3: in main chunk
nginx: [error] init_by_lua error: /usr/local/share/lua/5.1/kong/init.lua:524: error parsing declarative config file /usr/local/kong/declarative/kong.yml:
failed parsing declarative configuration: expected an object
stack traceback:
	[C]: in function 'error'
	/usr/local/share/lua/5.1/kong/init.lua:524: in function 'init'
	init_by_lua:3: in main chunk

The core error message is:

config file /usr/local/kong/declarative/kong.yml:

/usr/local/kong/declarative/kong.yml: No such file or directory

failed parsing declarative configuration: expected an object

2. The environment

  • Centos 7:CentOS Linux release 7.6.1810 (Core)
  • Docker: Docker version 20.10.8, build 3967b7d

3. The solution

3.1 Step #1: Create a docker network for kong

We should create a dedicated network for kong to use when using docker. This is for test purpose, if you use kong in production, you should use kubernetes instead.

$ docker network create kong-net

then list the networks:

$# docker network ls
NETWORK ID     NAME       DRIVER    SCOPE
9b2830010cfc   bridge     bridge    local
0751e5dbb152   host       host      local
31eb84b3ecba   kong-net   bridge    local
6e2153d1dee3   none       null      local
$#

What is a docker network?

Docker networking is primarily used to establish communication between Docker containers and the outside world via the host machine where the Docker daemon is running. Docker supports different types of networks, each fit for certain use cases.

3.2 Step #2: Create a docker volume for kong

Kong need some configuration files , so we should provide a docker volume for it to store those files and map from the container to host.

$ docker volume create kong-vol

Check the result:

$ docker volume ls
DRIVER    VOLUME NAME
local     kong-vol

Inspect the volume:

$ docker volume inspect kong-vol
[
    {
        "CreatedAt": "2021-11-11T20:00:21+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/data/docker/data/volumes/kong-vol/_data",
        "Name": "kong-vol",
        "Options": {},
        "Scope": "local"
    }
]

Notice the Mountpoint , this is the host path that would be mapped to container.

What is a docker volume:

Docker volumes are file systems mounted on Docker containers to preserve data generated by the running container. The volumes are stored on the host, independent of the container life cycle. This allows users to back up data and share file systems between containers easily.

3.3 Step #3: Start kong container

Now everything is ready, we can start the kong api gateway now:

$ docker run -d --name kong \
>      --network=kong-net \
>      -v "kong-vol:/usr/local/kong/declarative" \
>      -e "KONG_DATABASE=off" \
>      -e "KONG_DECLARATIVE_CONFIG=/usr/local/kong/declarative/kong.yml" \
>      -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
>      -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
>      -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
>      -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
>      -e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" \
>      -p 8000:8000 \
>      -p 8443:8443 \
>      -p 127.0.0.1:8001:8001 \
>      -p 127.0.0.1:8444:8444 \
>      kong:latest

d67f55dbf1957f80819f38039ed613041d07d6dafaf0061533407a950353743e

$#

We are using the docker image kong:latest to start kong container, and notice the docker volume that is mapped to the kong container’s path.

But we get this error:

$# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED         STATUS                            PORTS                                                                                                                                      NAMES
d67f55dbf195   kong:latest   "/docker-entrypoint.…"   5 seconds ago   Up 3 seconds (health: starting)   0.0.0.0:8000->8000/tcp, :::8000->8000/tcp, 127.0.0.1:8001->8001/tcp, 0.0.0.0:8443->8443/tcp, :::8443->8443/tcp, 127.0.0.1:8444->8444/tcp   kong

$# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

$# docker logs d67f55dbf195
2021/11/11 11:12:25 [warn] 1#0: the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /usr/local/kong/nginx.conf:6
nginx: [warn] the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /usr/local/kong/nginx.conf:6
2021/11/11 11:12:27 [error] 1#0: init_by_lua error: /usr/local/share/lua/5.1/kong/init.lua:524: error parsing declarative config file /usr/local/kong/declarative/kong.yml:
/usr/local/kong/declarative/kong.yml: No such file or directory
stack traceback:
	[C]: in function 'error'
	/usr/local/share/lua/5.1/kong/init.lua:524: in function 'init'
	init_by_lua:3: in main chunk
nginx: [error] init_by_lua error: /usr/local/share/lua/5.1/kong/init.lua:524: error parsing declarative config file /usr/local/kong/declarative/kong.yml:
/usr/local/kong/declarative/kong.yml: No such file or directory
stack traceback:
	[C]: in function 'error'
	/usr/local/share/lua/5.1/kong/init.lua:524: in function 'init'
	init_by_lua:3: in main chunk

The core message is:

/usr/local/kong/declarative/kong.yml: No such file or directory

Oh , we have forgotten the kong.yml, which is the key configuration file that kong uses.

Ok, create one,but wait, before that, we should know that we should create the file under the MountPoint directory of the docker volume:

image-20211111202406645

Now create the file:

$# touch /data/docker/data/volumes/kong-vol/_data/kong.yml
$#

Start docker container of kong api gateway again:

$ docker run -d --name kong \
>      --network=kong-net \
>      -v "kong-vol:/usr/local/kong/declarative" \
>      -e "KONG_DATABASE=off" \
>      -e "KONG_DECLARATIVE_CONFIG=/usr/local/kong/declarative/kong.yml" \
>      -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
>      -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
>      -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
>      -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
>      -e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" \
>      -p 8000:8000 \
>      -p 8443:8443 \
>      -p 127.0.0.1:8001:8001 \
>      -p 127.0.0.1:8444:8444 \
>      kong:latest
4587ab9b1e807ee09269cbcae4814cddea4f1df5b9e79657aec53904bab3b171
$#

But we get error again:

$# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

$# docker ps -a
CONTAINER ID   IMAGE         COMMAND                  CREATED          STATUS                     PORTS     NAMES
4587ab9b1e80   kong:latest   "/docker-entrypoint.…"   12 seconds ago   Exited (1) 6 seconds ago             kong

$# docker logs 4587ab9b1e80
2021/11/11 11:18:35 [warn] 1#0: the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /usr/local/kong/nginx.conf:6
nginx: [warn] the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /usr/local/kong/nginx.conf:6
2021/11/11 11:18:37 [error] 1#0: init_by_lua error: /usr/local/share/lua/5.1/kong/init.lua:524: error parsing declarative config file /usr/local/kong/declarative/kong.yml:
failed parsing declarative configuration: expected an object
stack traceback:
	[C]: in function 'error'
	/usr/local/share/lua/5.1/kong/init.lua:524: in function 'init'
	init_by_lua:3: in main chunk
nginx: [error] init_by_lua error: /usr/local/share/lua/5.1/kong/init.lua:524: error parsing declarative config file /usr/local/kong/declarative/kong.yml:
failed parsing declarative configuration: expected an object
stack traceback:
	[C]: in function 'error'
	/usr/local/share/lua/5.1/kong/init.lua:524: in function 'init'
	init_by_lua:3: in main chunk
$#

Core error message is:

nginx: [error] init_by_lua error: /usr/local/share/lua/5.1/kong/init.lua:524: error parsing declarative config file /usr/local/kong/declarative/kong.yml:
failed parsing declarative configuration: expected an object

It means that our kong.yml is not in correct format.

We can refer to the official documents of kong configuration file to get a example kong.yaml:

_format_version: "2.1"
_transform: true

services:
- name: my-service
  url: https://bswen.com
  plugins:
  - name: key-auth
  routes:
  - name: my-route
    paths:
    - /

consumers:
- username: my-user
  keyauth_credentials:
  - key: my-key

Now , verify the installation:

[$ _data]# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED          STATUS                    PORTS                                                                                                                                      NAMES
85883fde85bc   kong:latest   "/docker-entrypoint.…"   17 seconds ago   Up 15 seconds (healthy)   0.0.0.0:8000->8000/tcp, :::8000->8000/tcp, 127.0.0.1:8001->8001/tcp, 0.0.0.0:8443->8443/tcp, :::8443->8443/tcp, 127.0.0.1:8444->8444/tcp   kong
[$ _data]#

It’s running!!!

Check the port that exposed to host:

ot@kube-bswen _data]# curl -i http://localhost:8001/
HTTP/1.1 200 OK
Date: Thu, 11 Nov 2021 11:52:35 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
Content-Length: 11014
X-Kong-Admin-Latency: 389
Server: kong/2.6.0

Kong in docker is working fine!

Check the services behind kong api gateway:

➜[$ _data]# curl -i http://localhost:8001/services
HTTP/1.1 200 OK
Date: Thu, 11 Nov 2021 12:00:06 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
Content-Length: 379
X-Kong-Admin-Latency: 0
Server: kong/2.6.0
{
  "data": [
    {
      "write_timeout": 60000,
      "host": "bswen.com",
      "tls_verify": null,
      "tls_verify_depth": null,
      "retries": 5,
      "tags": null,
      "protocol": "https",
      "created_at": 1636631354,
      "updated_at": 1636631354,
      "client_certificate": null,
      "path": null,
      "name": "my-service",
      "port": 443,
      "ca_certificates": null,
      "connect_timeout": 60000,
      "id": "0855b320-0dd2-547d-891d-601e9b38647f",
      "read_timeout": 60000
    }
  ],
  "next": null
}

It’s working!

4. Summary

In this post, I demonstrated how to solve many errors when install dbless kong using docker. We should pay attention to the docker volume mapping and kong configuration file format. That’s it, thanks for your reading.