Guides
Kong Custom Plugin Setup Guide
Kong Custom Plugin Setup Guide
This guide explains how to set up and use custom Kong plugins in the jan-server project.
Directory Structure
kong/
+-- kong.yml # Main Kong declarative config
+-- kong-dev-full.yml # Dev-Full/Hybrid mode config (host routing)
+-- plugins/ # Custom plugins directory
+-- keycloak-apikey/ # API key validation plugin
+-- handler.lua # Plugin logic
+-- schema.lua # Configuration schema
+-- README.md # Plugin documentationPlugin Loading
Docker Configuration
Kong is configured to load custom plugins via environment variables:
environment:
KONG_PLUGINS: bundled,keycloak-apikey # Load bundled + custom plugins
KONG_LUA_PACKAGE_PATH: /usr/local/kong/plugins/?.lua;; # Plugin search path
volumes:
-../kong/plugins:/usr/local/kong/plugins:ro # Mount plugins directoryVerification
After starting Kong, verify plugins are loaded:
# List all enabled plugins
curl http://localhost:8001/plugins/enabled
# Should include:
# - bundled plugins (jwt, rate-limiting, cors, etc.)
# - keycloak-apikey (custom)Creating New Plugins
1. Create Plugin Directory
mkdir -p kong/plugins/my-plugin2. Create handler.lua
local MyPluginHandler = {
PRIORITY = 1000, -- Plugin execution priority
VERSION = "1.0.0",
}
function MyPluginHandler:access(conf)
-- Your plugin logic here
kong.log.info("My plugin executed!")
end
return MyPluginHandler3. Create schema.lua
return {
name = "my-plugin",
fields = {
{ config = {
type = "record",
fields = {
{ my_setting = {
type = "string",
required = true,
default = "default_value",
}},
}
}},
},
}4. Register Plugin
Update docker/infrastructure.yml:
environment:
KONG_PLUGINS: bundled,keycloak-apikey,my-plugin # Add your plugin5. Use in kong.yml
plugins:
- name: my-plugin
tags: [custom]
config:
my_setting: "value"Plugin Development Tips
Debugging
- Enable debug logging:
environment:
KONG_LOG_LEVEL: debug- Watch logs in real-time:
docker logs kong -f- Add debug statements:
kong.log.debug("Variable value: ", some_variable)
kong.log.err("Error occurred: ", error_message)Testing Locally
- Reload Kong after changes:
docker restart kong- Test plugin behavior:
# Make test request
curl -v http://localhost:8000/your-endpoint \
-H "X-Custom-Header: value"
# Check response headers
curl -I http://localhost:8000/your-endpointPlugin Priority
Kong executes plugins in priority order (higher = earlier):
2000+ - Pre-processing (e.g., request transformation)
1000+ - Authentication (e.g., jwt: 1005, keycloak-apikey: 1002)
500+ - Authorization
100+ - Post-processingSet priority in handler.lua:
local MyPluginHandler = {
PRIORITY = 1002, -- Your priority
}Common Patterns
HTTP Requests
local http = require "resty.http"
local httpc = http.new()
local res, err = httpc:request_uri("http://service:8080/endpoint", {
method = "POST",
body = "data",
headers = {
["Content-Type"] = "application/json",
},
})
if res.status == 200 then
kong.log.info("Request successful")
endHeader Manipulation
-- Read headers
local api_key = kong.request.get_header("X-API-Key")
-- Set request headers (to upstream)
kong.service.request.set_header("X-User-ID", "123")
-- Set response headers (to client)
kong.response.set_header("X-Custom", "value")
-- Remove headers
kong.service.request.clear_header("Authorization")Authentication
-- Authenticate consumer for rate limiting
kong.client.authenticate({
id = user_id,
custom_id = user_subject,
})Error Responses
-- Return error to client
return kong.response.exit(401, {
message = "Unauthorized"
})Best Practices
- Error Handling: Always handle HTTP errors gracefully
- Logging: Use appropriate log levels (debug, info, warn, err)
- Performance: Cache expensive operations, reuse HTTP connections
- Security: Validate all inputs, sanitize data
- Configuration: Use schema.lua for type-safe config
- Testing: Test with both valid and invalid inputs
Resources
Troubleshooting
Plugin Not Loaded
Symptom: Plugin not in /plugins/enabled
Solutions:
- Check
KONG_PLUGINSincludes your plugin name - Verify plugin files are mounted correctly
- Check file permissions (must be readable)
- Restart Kong container
Syntax Errors
Symptom: Kong fails to start
Solutions:
- Check Kong logs:
docker logs kong - Validate Lua syntax:
luac -p handler.lua - Check schema format matches Kong requirements
Plugin Not Executing
Symptom: Plugin loaded but not running
Solutions:
- Verify plugin is configured in
kong.yml - Check route/service matches request
- Ensure priority doesn't conflict with other plugins
- Add debug logging to verify execution
Performance Issues
Symptom: Slow response times
Solutions:
- Profile plugin execution time
- Add caching for expensive operations
- Use connection pooling for HTTP requests
- Consider async operations if possible