Secure API Gateway with rate limits, JWT auth, IP blocking, logging, and analytics for safety.
951
A lightweight API Gateway (Spring Boot) with JWT validation, per-user/IP rate limiting, IP blocking, dynamic routing, analytics, recent logs, and health endpoints. Redis is used for rate limits, analytics, IP blocks, recent logs, and the dynamic route table.
Image: shivammm21/apigateway:latest
8767 (map any host port you prefer)docker pull shivammm21/apigateway:latest
The gateway needs Redis for core features. Start Redis on your host (or in Docker) before running the gateway:
docker run -d --name redis -p 6379:6379 redis:alpine
What uses Redis:
Tip: If 6379 is already in use on your host, use another host port, e.g.
-p 6380:6379.
Map any host port (example: 7678) to the container's internal port 8767. Point the gateway to your host Redis using host.docker.internal.
docker run -d --name api-gateway \
-p 7678:8767 \
-e REDIS_HOST=host.docker.internal \
shivammm21/apigateway:latest
Why this works:
host.docker.internal.Linux note:
host.docker.internalis supported on recent Docker versions. If it does not resolve, add--add-host=host.docker.internal:host-gatewayto thedocker runcommand.
The gateway forwards requests based on the route table stored in Redis.
Assume your backend service runs at http://localhost:8081 on the host. Add a route:
curl -X POST http://localhost:7678/admin/routes/add \
-H "Content-Type: application/json" \
-d '{"path":"/users/**","serviceUrl":"http://host.docker.internal:8081"}'
This tells the gateway: any request matching /users/** should be forwarded to the backend on 8081.
Before (direct to backend):
GET http://localhost:8081/users/1
After (via gateway):
GET http://localhost:7678/users/1
Authorization: Bearer <jwt>
The gateway will:
curl -H "Authorization: Bearer sometokenvalue12345" \
http://localhost:7678/auth/validate
# Check usage
curl 'http://localhost:7678/admin/rate-limit/status?userId=123'
# Update global limit
curl -X POST http://localhost:7678/admin/rate-limit/update \
-H 'Content-Type: application/json' \
-d '{"limitPerMinute": 200}'
# Block an IP
curl -X POST http://localhost:7678/admin/ip-block/block \
-H 'Content-Type: application/json' \
-d '{"ip":"1.2.3.4","reason":"Suspicious"}'
curl http://localhost:7678/admin/analytics/traffic
curl http://localhost:7678/admin/analytics/errors
curl http://localhost:7678/admin/logs/recent
curl http://localhost:7678/health
Expected response:
{"status":"UP"}
If you prefer everything inside containers and isolated from host ports, use Compose:
version: "3.8"
services:
redis:
image: redis:alpine
container_name: apigateway-redis
command: ["redis-server", "--appendonly", "yes"]
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 5
restart: unless-stopped
gateway:
image: shivammm21/apigateway:latest
ports:
- "7678:8767" # host:container
environment:
- REDIS_HOST=redis
depends_on:
redis:
condition: service_healthy
restart: unless-stopped
volumes:
redis-data:
docker compose up -d
curl http://localhost:7678/health
REDIS_HOST (required): Hostname of Redis. Examples:
host.docker.internal (Redis on host)redis (Redis service name in the same Docker network/Compose project)JAVA_OPTS (optional): JVM flags, e.g. -Xms256m -Xmx512m.-p 8088:8767.ECONNREFUSED or Connection refused to Redis:
--add-host=host.docker.internal:host-gateway to docker run./health:
/health endpoint should respond even when routing is disabled.docker logs --tail=200 api-gateway
docker rm -f api-gateway redis 2>/dev/null || true
REDIS_HOST)Content type
Image
Digest
sha256:ac46ff5b5…
Size
121.7 MB
Last updated
11 months ago
docker pull shivammm21/apigateway