๐ Configuring API Gateway in Alpine Linux: Simple Guide
Setting up an API gateway makes your services work together smoothly! ๐ป This tutorial shows you how to configure an API gateway easily. Donโt worry - itโs simpler than you think! ๐
๐ค What is an API Gateway?
An API gateway is like a smart doorman for your applications. It manages who can talk to your services and how they communicate!
An API gateway helps you:
- ๐ Control access to your services
- ๐ Monitor and log all requests
- โก Balance load across servers
- ๐ก๏ธ Add security and authentication
๐ฏ What You Need
Before we start, you need:
- โ Alpine Linux system running
- โ Root or sudo access
- โ Basic understanding of web services
- โ Internet connection for installing packages
๐ Step 1: Installing API Gateway Software
๐ง Setting Up NGINX as API Gateway
Letโs start by installing NGINX, which makes an excellent API gateway. Itโs fast and reliable! ๐
What weโre doing: Installing and configuring NGINX to act as our API gateway.
# Update package manager
apk update
# Install NGINX and useful modules
apk add nginx nginx-mod-http-upstream-fair nginx-mod-http-headers-more
# Install additional tools
apk add curl jq openssl
# Create directories for configuration
mkdir -p /etc/nginx/conf.d/gateways
mkdir -p /var/log/nginx/gateway
# Check NGINX version
nginx -v
# Start and enable NGINX
rc-service nginx start
rc-update add nginx default
What this does: ๐ Installs NGINX with modules needed for API gateway functionality.
Expected Output:
nginx version: nginx/1.24.0
* Starting nginx... [ ok ]
* service nginx added to runlevel default
What this means: Your API gateway platform is ready! โ
๐ก Important Tips
Tip: NGINX is perfect for API gateways because itโs lightweight and fast! ๐ก
Warning: Always test configuration changes before applying them to production! โ ๏ธ
๐ ๏ธ Step 2: Basic API Gateway Configuration
๐ก Creating Gateway Configuration
Now letโs configure NGINX to act as an API gateway. This is where the magic happens! ๐
What weโre doing: Setting up basic API gateway rules that route requests to different backend services.
# Create main gateway configuration
cat > /etc/nginx/conf.d/api-gateway.conf << 'EOF'
# API Gateway Configuration
upstream auth_service {
server 127.0.0.1:3001;
server 127.0.0.1:3002 backup;
}
upstream user_service {
server 127.0.0.1:4001;
server 127.0.0.1:4002 backup;
}
upstream order_service {
server 127.0.0.1:5001;
server 127.0.0.1:5002 backup;
}
# Rate limiting zones
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=auth_limit:10m rate=5r/s;
# Main API Gateway Server
server {
listen 80;
server_name api.example.com localhost;
# Global settings
client_max_body_size 10M;
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
# Logging
access_log /var/log/nginx/gateway/access.log;
error_log /var/log/nginx/gateway/error.log;
# Health check endpoint
location /health {
access_log off;
return 200 '{"status":"healthy","timestamp":"$time_iso8601"}';
add_header Content-Type application/json;
}
# Authentication service
location /api/auth/ {
# Apply rate limiting
limit_req zone=auth_limit burst=20 nodelay;
# Add CORS headers
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
# Handle preflight requests
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
# Proxy to auth service
proxy_pass http://auth_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Add gateway headers
proxy_set_header X-Gateway-Version "1.0";
proxy_set_header X-Request-ID $request_id;
}
# User service
location /api/users/ {
# Apply rate limiting
limit_req zone=api_limit burst=50 nodelay;
# Require authentication (placeholder)
# auth_request /auth;
# Proxy to user service
proxy_pass http://user_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Request-ID $request_id;
}
# Order service
location /api/orders/ {
# Apply rate limiting
limit_req zone=api_limit burst=30 nodelay;
# Proxy to order service
proxy_pass http://order_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Request-ID $request_id;
}
# Default response for unmatched routes
location / {
return 404 '{"error":"Endpoint not found","timestamp":"$time_iso8601"}';
add_header Content-Type application/json;
}
}
EOF
# Test NGINX configuration
nginx -t
# Reload NGINX to apply changes
nginx -s reload
Code explanation:
upstream
: Defines backend service groups with load balancinglimit_req_zone
: Sets up rate limiting to prevent abuseproxy_pass
: Forwards requests to backend servicesproxy_set_header
: Adds important headers for backend servicesadd_header
: Adds CORS and custom headers
Expected Output:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
What this means: Your API gateway is configured and ready to route requests! ๐
๐ฎ Letโs Try It!
Time for hands-on practice! This is the fun part! ๐ฏ
What weโre doing: Creating mock backend services to test our API gateway configuration.
# Create directory for test services
mkdir -p /opt/api-test-services
cd /opt/api-test-services
# Install Node.js for mock services
apk add nodejs npm
# Create package.json
cat > package.json << 'EOF'
{
"name": "api-test-services",
"version": "1.0.0",
"description": "Mock services for API gateway testing",
"scripts": {
"start-auth": "node auth-service.js",
"start-users": "node user-service.js",
"start-orders": "node order-service.js"
},
"dependencies": {
"express": "^4.18.0"
}
}
EOF
# Install dependencies
npm install
# Create mock authentication service
cat > auth-service.js << 'EOF'
const express = require('express');
const app = express();
const port = 3001;
app.use(express.json());
// Mock user database
const users = {
'user1': { password: 'pass123', id: 1, role: 'user' },
'admin': { password: 'admin123', id: 2, role: 'admin' }
};
// Login endpoint
app.post('/api/auth/login', (req, res) => {
const { username, password } = req.body;
console.log(`๐ Login attempt for: ${username}`);
if (users[username] && users[username].password === password) {
res.json({
success: true,
token: `token_${username}_${Date.now()}`,
user: { id: users[username].id, username, role: users[username].role }
});
} else {
res.status(401).json({ success: false, error: 'Invalid credentials' });
}
});
// Token validation endpoint
app.get('/api/auth/validate', (req, res) => {
const token = req.headers.authorization;
if (token && token.startsWith('token_')) {
res.json({ valid: true, user: { id: 1, username: 'user1' } });
} else {
res.status(401).json({ valid: false, error: 'Invalid token' });
}
});
app.listen(port, () => {
console.log(`๐ Auth service running on port ${port}`);
});
EOF
# Create mock user service
cat > user-service.js << 'EOF'
const express = require('express');
const app = express();
const port = 4001;
app.use(express.json());
// Mock users database
let users = [
{ id: 1, name: 'John Doe', email: '[email protected]' },
{ id: 2, name: 'Jane Smith', email: '[email protected]' },
{ id: 3, name: 'Bob Wilson', email: '[email protected]' }
];
// Get all users
app.get('/api/users/', (req, res) => {
console.log('๐ฅ Fetching all users');
res.json({ users: users });
});
// Get user by ID
app.get('/api/users/:id', (req, res) => {
const userId = parseInt(req.params.id);
const user = users.find(u => u.id === userId);
console.log(`๐ค Fetching user ${userId}`);
if (user) {
res.json({ user: user });
} else {
res.status(404).json({ error: 'User not found' });
}
});
// Create new user
app.post('/api/users/', (req, res) => {
const { name, email } = req.body;
const newUser = {
id: users.length + 1,
name: name,
email: email
};
users.push(newUser);
console.log(`โ Created user: ${name}`);
res.status(201).json({ user: newUser });
});
app.listen(port, () => {
console.log(`๐ฅ User service running on port ${port}`);
});
EOF
# Create mock order service
cat > order-service.js << 'EOF'
const express = require('express');
const app = express();
const port = 5001;
app.use(express.json());
// Mock orders database
let orders = [
{ id: 1, userId: 1, product: 'Laptop', amount: 999.99, status: 'completed' },
{ id: 2, userId: 2, product: 'Mouse', amount: 29.99, status: 'pending' }
];
// Get all orders
app.get('/api/orders/', (req, res) => {
console.log('๐ฆ Fetching all orders');
res.json({ orders: orders });
});
// Get order by ID
app.get('/api/orders/:id', (req, res) => {
const orderId = parseInt(req.params.id);
const order = orders.find(o => o.id === orderId);
console.log(`๐ Fetching order ${orderId}`);
if (order) {
res.json({ order: order });
} else {
res.status(404).json({ error: 'Order not found' });
}
});
// Create new order
app.post('/api/orders/', (req, res) => {
const { userId, product, amount } = req.body;
const newOrder = {
id: orders.length + 1,
userId: userId,
product: product,
amount: amount,
status: 'pending'
};
orders.push(newOrder);
console.log(`๐ Created order: ${product} for user ${userId}`);
res.status(201).json({ order: newOrder });
});
app.listen(port, () => {
console.log(`๐ฆ Order service running on port ${port}`);
});
EOF
# Create startup script
cat > start-services.sh << 'EOF'
#!/bin/sh
echo "๐ Starting mock API services..."
# Start services in background
node auth-service.js &
AUTH_PID=$!
node user-service.js &
USER_PID=$!
node order-service.js &
ORDER_PID=$!
echo "๐ Auth service PID: $AUTH_PID"
echo "๐ฅ User service PID: $USER_PID"
echo "๐ฆ Order service PID: $ORDER_PID"
echo ""
echo "โ
All services started!"
echo "๐ API Gateway available at: http://localhost"
echo ""
echo "๐ Test endpoints:"
echo " POST /api/auth/login"
echo " GET /api/users/"
echo " GET /api/orders/"
echo ""
echo "Press Ctrl+C to stop all services"
# Wait for interrupt
trap 'echo "๐ Stopping services..."; kill $AUTH_PID $USER_PID $ORDER_PID; exit' INT
wait
EOF
chmod +x start-services.sh
echo "โ
Mock services created!"
echo ""
echo "๐ To test the API gateway:"
echo "1. Run: ./start-services.sh"
echo "2. Test: curl http://localhost/health"
echo "3. Test: curl http://localhost/api/users/"
You should see:
๐ Starting mock API services...
๐ Auth service PID: 1234
๐ฅ User service PID: 1235
๐ฆ Order service PID: 1236
โ
All services started!
๐ API Gateway available at: http://localhost
Awesome work! ๐
๐ Quick Summary Table
Component | Purpose | Port | Endpoint |
---|---|---|---|
๐ API Gateway | ๐ง Main entry point | 80 | /api/* |
๐ Auth Service | ๐ ๏ธ Authentication | 3001 | /api/auth/* |
๐ฅ User Service | โ User management | 4001 | /api/users/* |
๐ฆ Order Service | โ Order processing | 5001 | /api/orders/* |
๐ Step 3: Adding Security Features
๐ก๏ธ Implementing Authentication and Rate Limiting
Letโs add security features to protect our API gateway from abuse! ๐
What weโre doing: Adding JWT authentication and advanced rate limiting to secure our gateway.
# Create enhanced security configuration
cat > /etc/nginx/conf.d/security.conf << 'EOF'
# Security Configuration for API Gateway
# Rate limiting with different zones
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_zone $http_authorization zone=user_api:10m rate=30r/m;
# IP blacklist map
geo $blocked_ip {
default 0;
# Add IPs to block here
# 192.168.1.100 1;
}
# Security headers map
map $sent_http_content_type $security_headers {
~*text/html "nosniff";
application/json "nosniff";
}
# JWT validation (simplified)
map $http_authorization $jwt_valid {
default 0;
"~*Bearer\s+token_\w+" 1;
}
EOF
# Create advanced gateway configuration with security
cat > /etc/nginx/conf.d/secure-gateway.conf << 'EOF'
# Secure API Gateway Configuration
# Include security config
include /etc/nginx/conf.d/security.conf;
server {
listen 443 ssl http2;
server_name api.example.com;
# SSL Configuration (self-signed for testing)
ssl_certificate /etc/ssl/certs/api-gateway.crt;
ssl_certificate_key /etc/ssl/private/api-gateway.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# Security headers
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options $security_headers always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Gateway-Version "1.0-secure" always;
# Block suspicious IPs
if ($blocked_ip) {
return 403 '{"error":"Access denied","code":"IP_BLOCKED"}';
}
# API Authentication endpoint (less strict rate limiting)
location /api/auth/login {
limit_req zone=login burst=5 nodelay;
proxy_pass http://auth_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Log authentication attempts
access_log /var/log/nginx/gateway/auth.log;
}
# Protected API endpoints
location /api/ {
# Check JWT token
if ($jwt_valid = 0) {
return 401 '{"error":"Authentication required","code":"NO_TOKEN"}';
}
# Apply rate limiting based on token
limit_req zone=user_api burst=10 nodelay;
# Route to appropriate service
location /api/users/ {
proxy_pass http://user_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-User-Token $http_authorization;
}
location /api/orders/ {
proxy_pass http://order_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-User-Token $http_authorization;
}
}
# Health check (no auth required)
location /health {
access_log off;
return 200 '{"status":"secure","ssl":true,"timestamp":"$time_iso8601"}';
add_header Content-Type application/json;
}
}
# Redirect HTTP to HTTPS
server {
listen 80;
server_name api.example.com;
return 301 https://$server_name$request_uri;
}
EOF
# Create self-signed SSL certificate for testing
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/private/api-gateway.key \
-out /etc/ssl/certs/api-gateway.crt \
-subj "/C=US/ST=State/L=City/O=Organization/CN=api.example.com"
# Set proper permissions
chmod 600 /etc/ssl/private/api-gateway.key
chmod 644 /etc/ssl/certs/api-gateway.crt
echo "๐ Security configuration added!"
echo "๐ Features enabled:"
echo " โ
SSL/TLS encryption"
echo " โ
JWT token validation"
echo " โ
Advanced rate limiting"
echo " โ
Security headers"
echo " โ
IP blocking capability"
What this does: Adds enterprise-level security features to your API gateway! ๐
๐ฎ Practice Time!
Letโs practice what you learned! Try these simple examples:
Example 1: API Gateway Monitoring ๐ข
What weโre doing: Creating a monitoring dashboard for the API gateway.
# Create monitoring script
cat > /opt/gateway-monitor.sh << 'EOF'
#!/bin/sh
echo "๐ API Gateway Monitoring Dashboard"
echo "=================================="
echo ""
# Check NGINX status
if rc-service nginx status >/dev/null 2>&1; then
echo "โ
NGINX Status: Running"
else
echo "โ NGINX Status: Stopped"
fi
echo ""
echo "๐ Request Statistics (last 1000 lines):"
if [ -f /var/log/nginx/gateway/access.log ]; then
echo " Total requests: $(tail -1000 /var/log/nginx/gateway/access.log | wc -l)"
echo " 2xx responses: $(tail -1000 /var/log/nginx/gateway/access.log | grep ' 2[0-9][0-9] ' | wc -l)"
echo " 4xx responses: $(tail -1000 /var/log/nginx/gateway/access.log | grep ' 4[0-9][0-9] ' | wc -l)"
echo " 5xx responses: $(tail -1000 /var/log/nginx/gateway/access.log | grep ' 5[0-9][0-9] ' | wc -l)"
else
echo " ๐ No access log found yet"
fi
echo ""
echo "๐ Top API Endpoints:"
if [ -f /var/log/nginx/gateway/access.log ]; then
tail -1000 /var/log/nginx/gateway/access.log | \
awk '{print $7}' | \
sort | uniq -c | sort -nr | head -5 | \
while read count endpoint; do
echo " $endpoint: $count requests"
done
else
echo " ๐ No data available"
fi
echo ""
echo "โฐ Recent Errors:"
if [ -f /var/log/nginx/gateway/error.log ]; then
tail -5 /var/log/nginx/gateway/error.log | while read line; do
echo " โ ๏ธ $line"
done
else
echo " โ
No recent errors"
fi
echo ""
echo "๐ก๏ธ System Resources:"
echo " CPU Load: $(uptime | awk -F'load average:' '{print $2}')"
echo " Memory: $(free -h | awk '/^Mem:/ {print $3 "/" $2}')"
echo " Disk: $(df -h / | awk 'NR==2 {print $3 "/" $2 " (" $5 " used)"}')"
EOF
chmod +x /opt/gateway-monitor.sh
# Run monitoring
/opt/gateway-monitor.sh
What this does: Creates a real-time monitoring dashboard for your API gateway! ๐
Example 2: Load Testing Script ๐ก
What weโre doing: Creating a script to test API gateway performance.
# Create load testing script
cat > /opt/load-test.sh << 'EOF'
#!/bin/sh
echo "๐ฅ API Gateway Load Testing"
echo "========================="
if [ -z "$1" ]; then
echo "Usage: $0 <number_of_requests>"
echo "Example: $0 100"
exit 1
fi
REQUESTS=$1
GATEWAY_URL="http://localhost"
echo "๐ Testing with $REQUESTS requests..."
echo ""
# Test health endpoint
echo "๐ฅ Testing health endpoint..."
for i in $(seq 1 10); do
response=$(curl -s -w "%{http_code}" -o /dev/null "$GATEWAY_URL/health")
if [ "$response" = "200" ]; then
echo "โ
Health check $i: OK"
else
echo "โ Health check $i: Failed ($response)"
fi
done
echo ""
echo "๐ฅ Testing user endpoint..."
# Test user endpoint
start_time=$(date +%s)
success_count=0
error_count=0
for i in $(seq 1 "$REQUESTS"); do
response=$(curl -s -w "%{http_code}" -o /dev/null "$GATEWAY_URL/api/users/")
if [ "$response" = "200" ]; then
success_count=$((success_count + 1))
else
error_count=$((error_count + 1))
fi
# Show progress every 10 requests
if [ $((i % 10)) = 0 ]; then
echo "Progress: $i/$REQUESTS requests sent"
fi
done
end_time=$(date +%s)
duration=$((end_time - start_time))
echo ""
echo "๐ Results:"
echo " Total requests: $REQUESTS"
echo " Successful: $success_count"
echo " Errors: $error_count"
echo " Duration: ${duration}s"
echo " Requests/second: $(($REQUESTS / $duration))"
EOF
chmod +x /opt/load-test.sh
echo "๐ฅ Load testing script created!"
echo "Usage: /opt/load-test.sh 50"
What this does: Tests how well your API gateway handles traffic! ๐
๐จ Fix Common Problems
Problem 1: NGINX wonโt start โ
What happened: NGINX fails to start after configuration changes. How to fix it: Check configuration syntax and logs!
# Test NGINX configuration
nginx -t
# Check NGINX error log
tail -20 /var/log/nginx/error.log
# Check if ports are already in use
netstat -tlnp | grep ':80\|:443'
# Restart NGINX
rc-service nginx restart
Problem 2: Backend services unreachable โ
What happened: API gateway canโt connect to backend services. How to fix it: Verify backend services and network connectivity!
# Check if backend services are running
ps aux | grep node
# Test backend services directly
curl http://localhost:3001/api/auth/login -X POST \
-H "Content-Type: application/json" \
-d '{"username":"user1","password":"pass123"}'
# Check backend service logs
tail -f /var/log/nginx/gateway/error.log
Donโt worry! API gateway issues are usually configuration problems that are easy to fix! ๐ช
๐ก Simple Tips
- Test configurations ๐
- Always run
nginx -t
before reloading - Monitor logs ๐ฑ - Watch access and error logs for issues
- Use health checks ๐ค - Implement health endpoints for all services
- Plan for scale ๐ช - Design your gateway to handle growth
โ Check Everything Works
Letโs make sure your API gateway is working perfectly:
# Test NGINX configuration
nginx -t && echo "โ
Configuration valid"
# Test health endpoint
curl -s http://localhost/health | jq '.' && echo "โ
Health check OK"
# Test backend connectivity
curl -s http://localhost/api/users/ | jq '.' && echo "โ
Backend services OK"
# Check NGINX is running
rc-service nginx status && echo "โ
NGINX running"
echo "๐ API Gateway is ready! โ
"
Good output:
โ
Configuration valid
โ
Health check OK
โ
Backend services OK
โ
NGINX running
๐ API Gateway is ready! โ
๐ What You Learned
Great job! Now you can:
- โ Install and configure NGINX as an API gateway
- โ Set up load balancing and rate limiting
- โ Implement security features and SSL/TLS
- โ Monitor and test API gateway performance
๐ฏ Whatโs Next?
Now you can try:
- ๐ Adding advanced authentication with OAuth2
- ๐ ๏ธ Implementing API versioning and routing
- ๐ค Setting up distributed tracing and monitoring
- ๐ Learning about service mesh technologies!
Remember: API gateways are the front door to your services! Youโre building scalable architecture! ๐
Keep practicing and youโll become a microservices expert too! ๐ซ