Install Kong Gateway in read-only mode using Docker Compose
Run a Kong Gateway Docker container in DB-less mode using the provided Docker Compose file with read_only set to true.
Prerequisites
Docker Compose
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 declarativeThen, 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
protocols:
- http
- https
EOFSet 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, replacing 3.15.0.5 with your own version of Kong Gateway:
cat <<EOF > docker-compose.yml
services:
kong-dbless:
image: '${GW_IMAGE:-kong/kong-gateway:3.15.0.5}' # 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
EOFThis Docker Compose file will create a read-only Kong Gateway instance without a datastore.
Running in a hardened container
Kong Gateway needs writable volumes mounted at
/tmpand at theprefix(KONG_PREFIX) directory, even in a read-only root filesystem. The prefix directory holds the PID file, Unix sockets, the LMDB cache, and the generated NGINX configuration. You can redirect logs, such asproxy_error_log, to a separate writable path or to stderr.To run as a non-root user, set
nginx_user(or theKONG_NGINX_USERenvironment variable). A non-root user can’t bind to privileged ports (1024 or lower), so configure the proxy and Admin API listeners on ports above 1024.
Start Kong Gateway
Start Kong Gateway with the Docker Compose file:
docker compose up -dValidate
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" \
--no-progress-meter --fail-with-body 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" \
--no-progress-meter --fail-with-body \
-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"}%Cleanup
Destroy the Kong Gateway container
docker compose down