Kong API Gateway Installation
Kong is a widely-deployed open-source API gateway built on Nginx, providing a scalable platform for managing APIs, microservices, and applications. Kong's plugin-based architecture enables authentication, rate limiting, CORS, request/response transformation, and more. This guide covers Docker-based and package-based installation, service and route configuration, essential plugins, admin API usage, and the deck declarative configuration tool.
Table of Contents
- What is Kong
- System Requirements
- Docker Installation
- Package Manager Installation
- Database Setup
- Configuration Overview
- Services Configuration
- Routes Configuration
- Plugin Management
- Authentication Plugins
- Rate Limiting Plugin
- Admin API
- Deck Declarative Configuration
- Troubleshooting
What is Kong
Kong is an API gateway and microservices management layer that simplifies application architecture by:
- Routing requests to appropriate microservices
- Enforcing authentication and authorization
- Rate limiting and traffic shaping
- API versioning and transformations
- Monitoring and logging
Kong operates as a reverse proxy layer, sitting between clients and backend services.
System Requirements
Ensure your system meets:
- Linux kernel 3.10 or newer
- 512 MB RAM minimum (2 GB recommended)
- PostgreSQL 9.5+ or Cassandra 3.11+ for data storage
- 100 MB disk space for Kong binary
- Network access to database and backend services
Docker Installation
The simplest deployment method for Kong uses Docker and Docker Compose. Create a docker-compose.yml:
version: '3.8'
services:
postgres:
image: postgres:15-alpine
restart: always
environment:
POSTGRES_DB: kong
POSTGRES_USER: kong
POSTGRES_PASSWORD: kong_secure_password_123
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "kong"]
interval: 10s
timeout: 5s
retries: 5
kong-migration:
image: kong:3.4-alpine
command: kong migrations bootstrap
depends_on:
postgres:
condition: service_healthy
environment:
KONG_DATABASE: postgres
KONG_PG_HOST: postgres
KONG_PG_USER: kong
KONG_PG_PASSWORD: kong_secure_password_123
KONG_PG_DATABASE: kong
kong:
image: kong:3.4-alpine
restart: always
depends_on:
- kong-migration
ports:
- "8000:8000" # Proxy
- "8443:8443" # Proxy SSL
- "8001:8001" # Admin API
- "8444:8444" # Admin API SSL
environment:
KONG_DATABASE: postgres
KONG_PG_HOST: postgres
KONG_PG_USER: kong
KONG_PG_PASSWORD: kong_secure_password_123
KONG_PG_DATABASE: kong
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_LOG_LEVEL: info
konga:
image: pantsel/konga:latest
restart: always
depends_on:
- kong
ports:
- "1337:1337"
environment:
NODE_ENV: production
DB_ADAPTER: postgres
DB_HOST: postgres
DB_USER: kong
DB_PASSWORD: kong_secure_password_123
DB_DATABASE: konga
volumes:
postgres_data:
networks:
default:
name: kong_network
Deploy Kong:
docker-compose up -d
Verify Kong is running:
curl http://localhost:8001
Access Konga dashboard at http://localhost:1337
Package Manager Installation
For Ubuntu/Debian:
curl https://repo.konghq.com/gpg.key | sudo apt-key add -
echo "deb https://repo.konghq.com/ubuntu/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/kong.list
sudo apt update
sudo apt install kong
For RHEL/CentOS:
curl https://repo.konghq.com/rpm/el7/[email protected] | sudo yum install -
sudo yum install kong
Create Kong configuration file /etc/kong/kong.conf:
database = postgres
pg_host = localhost
pg_port = 5432
pg_user = kong
pg_password = kong_secure_password_123
pg_database = kong
proxy_listen = 0.0.0.0:8000, 0.0.0.0:8443 ssl
admin_listen = 127.0.0.1:8001
ssl_cert = /etc/kong/ssl/kong.crt
ssl_cert_key = /etc/kong/ssl/kong.key
log_level = notice
Run migrations:
kong migrations bootstrap -c /etc/kong/kong.conf
Start Kong:
kong start -c /etc/kong/kong.conf
Database Setup
Create PostgreSQL database and user:
sudo -u postgres psql <<EOF
CREATE USER kong WITH PASSWORD 'kong_secure_password_123';
CREATE DATABASE kong OWNER kong;
GRANT ALL PRIVILEGES ON DATABASE kong TO kong;
EOF
Or using the Kong migrations:
kong migrations bootstrap -c /etc/kong/kong.conf
Configuration Overview
Kong's core concepts:
- Services: Backend services or microservices
- Routes: Paths or hosts that map to services
- Plugins: Add functionality like authentication, rate limiting
- Consumers: API consumers or users
- Credentials: API keys or authentication credentials
Services Configuration
Create a service via Kong Admin API:
curl -X POST http://localhost:8001/services \
-H "Content-Type: application/json" \
-d '{
"name": "web-service",
"url": "http://192.168.1.100:8000"
}'
Update service:
curl -X PATCH http://localhost:8001/services/web-service \
-H "Content-Type: application/json" \
-d '{
"url": "http://192.168.1.100:8001"
}'
List services:
curl http://localhost:8001/services
Create multiple services:
curl -X POST http://localhost:8001/services \
-H "Content-Type: application/json" \
-d '{"name": "api-service", "url": "http://192.168.1.110:8080"}'
curl -X POST http://localhost:8001/services \
-H "Content-Type: application/json" \
-d '{"name": "blog-service", "url": "http://192.168.1.120:3000"}'
Routes Configuration
Create a route pointing to a service:
curl -X POST http://localhost:8001/services/web-service/routes \
-H "Content-Type: application/json" \
-d '{
"name": "web-route",
"paths": ["/"],
"methods": ["GET", "POST", "PUT", "DELETE"]
}'
Create routes with host matching:
curl -X POST http://localhost:8001/services/api-service/routes \
-H "Content-Type: application/json" \
-d '{
"name": "api-route",
"hosts": ["api.example.com"],
"paths": ["/api"]
}'
curl -X POST http://localhost:8001/services/blog-service/routes \
-H "Content-Type: application/json" \
-d '{
"name": "blog-route",
"hosts": ["blog.example.com"],
"paths": ["/"]
}'
Update route:
curl -X PATCH http://localhost:8001/services/web-service/routes/web-route \
-H "Content-Type: application/json" \
-d '{
"strip_path": true,
"preserve_host": true
}'
Plugin Management
List available plugins:
curl http://localhost:8001/plugins/enabled
Enable a plugin globally:
curl -X POST http://localhost:8001/plugins \
-H "Content-Type: application/json" \
-d '{
"name": "cors",
"config": {
"origins": ["*"],
"methods": ["GET", "POST", "PUT", "DELETE"],
"headers": ["Content-Type", "Authorization"],
"exposed_headers": ["X-Total-Count"]
}
}'
Enable plugin on a service:
curl -X POST http://localhost:8001/services/api-service/plugins \
-H "Content-Type: application/json" \
-d '{
"name": "cors",
"config": {
"origins": ["https://example.com"]
}
}'
Enable plugin on a route:
curl -X POST http://localhost:8001/services/web-service/routes/web-route/plugins \
-H "Content-Type: application/json" \
-d '{
"name": "request-transformer",
"config": {
"add": {
"headers": ["X-Custom-Header:custom-value"]
}
}
}'
Authentication Plugins
Create a consumer:
curl -X POST http://localhost:8001/consumers \
-H "Content-Type: application/json" \
-d '{"username": "app-client", "custom_id": "app-123"}'
Enable basic auth plugin:
curl -X POST http://localhost:8001/services/api-service/plugins \
-H "Content-Type: application/json" \
-d '{"name": "basic-auth"}'
Add basic auth credentials:
curl -X POST http://localhost:8001/consumers/app-client/basic-auth \
-H "Content-Type: application/json" \
-d '{"username": "api_user", "password": "secure_password"}'
Enable key-auth plugin:
curl -X POST http://localhost:8001/services/api-service/plugins \
-H "Content-Type: application/json" \
-d '{"name": "key-auth", "config": {"key_names": ["apikey"]}}'
Add API key:
curl -X POST http://localhost:8001/consumers/app-client/key-auth \
-H "Content-Type: application/json" \
-d '{"key": "super-secret-apikey-12345"}'
Test API key authentication:
curl -H "apikey: super-secret-apikey-12345" http://localhost:8000/api/
Enable OAuth 2.0:
curl -X POST http://localhost:8001/services/api-service/plugins \
-H "Content-Type: application/json" \
-d '{"name": "oauth2", "config": {"mandatory_scope": true, "enable_implicit_grant": true}}'
Rate Limiting Plugin
Enable rate limiting plugin:
curl -X POST http://localhost:8001/services/api-service/plugins \
-H "Content-Type: application/json" \
-d '{
"name": "rate-limiting",
"config": {
"minute": 100,
"hour": 10000,
"policy": "local",
"fault_tolerant": true,
"hide_client_headers": false
}
}'
Apply different limits per consumer:
curl -X POST http://localhost:8001/consumers/app-client/plugins \
-H "Content-Type: application/json" \
-d '{
"name": "rate-limiting",
"config": {
"minute": 500,
"hour": 50000
}
}'
Enable response rate limiting:
curl -X POST http://localhost:8001/services/api-service/plugins \
-H "Content-Type: application/json" \
-d '{
"name": "response-ratelimiting",
"config": {
"limits": {
"default": {"minute": 1000}
}
}
}'
Admin API
List all routes:
curl http://localhost:8001/routes
Get specific route details:
curl http://localhost:8001/routes/web-route
Delete a route:
curl -X DELETE http://localhost:8001/routes/web-route
Delete a service:
curl -X DELETE http://localhost:8001/services/web-service
Get health status:
curl http://localhost:8001/status
Deck Declarative Configuration
Install deck:
curl -sL https://github.com/kong/deck/releases/download/v1.28.0/deck_1.28.0_linux_amd64.tar.gz | tar xz -C /usr/local/bin
Create a Kong configuration file kong.yaml:
_format_version: "3.0"
_info:
title: My API Gateway
description: Production API Gateway Configuration
version: 1.0.0
services:
- name: web-service
url: http://192.168.1.100:8000
routes:
- name: web-route
paths:
- /
strip_path: false
- name: api-service
url: http://192.168.1.110:8080
routes:
- name: api-route
hosts:
- api.example.com
paths:
- /api
plugins:
- name: rate-limiting
config:
minute: 100
hour: 10000
- name: basic-auth
- name: blog-service
url: http://192.168.1.120:3000
routes:
- name: blog-route
hosts:
- blog.example.com
plugins:
- name: cors
config:
origins:
- "*"
methods:
- GET
- POST
headers:
- Content-Type
- Authorization
consumers:
- username: app-client
basic_auth:
- username: api_user
password: secure_password
key_auth:
- key: super-secret-apikey
Sync configuration to Kong:
deck sync -s kong.yaml
Validate configuration without applying:
deck validate -s kong.yaml
Dump current Kong configuration:
deck dump > current-kong.yaml
Troubleshooting
Check Kong service status:
systemctl status kong
journalctl -u kong -f
Verify Kong is responding:
curl -v http://localhost:8001
curl -v http://localhost:8000
Check database connectivity:
curl http://localhost:8001/status
Review Kong logs:
tail -f /var/log/kong/error.log
tail -f /var/log/kong/access.log
Test service routing:
curl -H "Host: api.example.com" http://localhost:8000/api/test
Debug plugins:
curl http://localhost:8001/plugins
curl http://localhost:8001/services/api-service/plugins
Conclusion
Kong provides a flexible, scalable API gateway platform with powerful plugin architecture for authentication, rate limiting, transformation, and monitoring. Whether deploying via Docker Compose or package managers, Kong simplifies API management and microservices orchestration. The combination of the Admin API for programmatic configuration and Deck for declarative management ensures flexible operations at scale.


