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

  1. What is Kong
  2. System Requirements
  3. Docker Installation
  4. Package Manager Installation
  5. Database Setup
  6. Configuration Overview
  7. Services Configuration
  8. Routes Configuration
  9. Plugin Management
  10. Authentication Plugins
  11. Rate Limiting Plugin
  12. Admin API
  13. Deck Declarative Configuration
  14. 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.