Install Kong Gateway in read-only mode using Docker Compose

Uses: Kong Gateway
Related Documentation
Incompatible with
konnect
Minimum Version
Kong Gateway - 3.2
TL;DR

Run a Kong Gateway Docker container in DB-less mode using the provided Docker Compose file with read_only set to true.

Prerequisites

This guide requires Docker installed on your system.

Create a kong.yml configuration file

For read-only mode, you need to run Kong Gateway as a DB-less deployment - that is, without a database. This means that you can’t use the Admin API or decK to configure the Gateway instance. Instead, you have to pass a declarative configuration file to Kong Gateway while starting the instance.

Create a directory for your Kong configuration:

mkdir declarative

Then, create a kong.yml file with your entire Gateway configuration. For example, the following file creates a Service and a Route:

cat <<EOF > ./declarative/kong.yml
_format_version: "3.0"
services:
- name: example-service
  url: http://httpbin.org
  routes:
  - name: example-route
    paths:
    - /anything
EOF

Set up the Docker Compose file for read-only mode

Now we need to configure our Kong Gateway Docker Compose stack.

In this configuration file, we’re going to mount a Docker volume to the locations where Kong Gateway needs to write data, which includes the /declarative directory. This default configuration requires write access to /tmp and to the prefix path.

Run the following command to create a Docker Compose file at docker-compose.yml with read_only set to true:

cat <<EOF > docker-compose.yml

services:
  kong-dbless:
    image: '${GW_IMAGE:-kong/kong-gateway:3.11.0.1}' # Kong Gateway image (default to latest version)
    container_name: kong-dbless-readonly
    read_only: true
    restart: unless-stopped
    networks:
      - kong-net
    volumes:
      - ./declarative:/kong/declarative/
      - ./tmp_volume:/tmp
      - ./prefix_volume:/var/run/kong
    environment:
      KONG_PREFIX: /var/run/kong
      KONG_DATABASE: off
      KONG_DECLARATIVE_CONFIG: /kong/declarative/kong.yml
      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
      KONG_ADMIN_GUI_URL: http://localhost:8002
      KONG_LICENSE_DATA: "\${KONG_LICENSE_DATA}" # Kong Enterprise license passed via environment variable
    ports:
      - "8000:8000"
      - "8443:8443"
      - "8001:8001"
      - "8444:8444"
      - "8002:8002"
      - "8445:8445"
      - "8003:8003"
      - "8004:8004"

networks:
  kong-net:
    external: true
EOF

This Docker Compose file will create a read-only Kong Gateway instance without a datastore.

Start Kong Gateway

Start Kong Gateway with the Docker Compose file:

docker compose up -d

Validate

Let’s make sure that Kong Gateway is running in read-only mode by checking that we can’t write to the API.

First, check that Kong Gateway is running:

 curl -X GET "http://localhost:8001/services"

This will return an HTTP/1.1 200 OK response with the example-service Service configured through kong.yml.

Now, try writing to the Kong Admin API:

 curl -X POST "http://localhost:8001/consumers" \
     -H "Accept: application/json" \
     --json '{
       "username": "consumer"
     }'

This time, you’ll get a 405 Not Allowed response, with the following message:

{"code":12,"message":"cannot create 'consumers' entities when not using a database","name":"operation unsupported"}%
Something wrong?

Help us make these docs great!

Kong Developer docs are open source. If you find these useful and want to make them better, contribute today!