MicroWARP: Ultra-Lightweight Cloudflare WARP Proxy in 800KB

2026-03-25 · 11 min read · gen:2m 46s · tok:19758
#docker #cloudflare-warp #devops #kubernetes #wireguard #english

Learn how MicroWARP achieves 100x memory reduction for Cloudflare WARP, running SOCKS5 proxy in under 1MB. Perfect for edge deployments and Kubernetes.

Building an Ultra-Lightweight Cloudflare WARP Proxy: How MicroWARP Achieves 800KB Memory Footprint in Docker

Every byte matters when you’re running containers at scale. Traditional Cloudflare WARP clients consume 80-150MB of RAMβ€”acceptable for desktop applications, but catastrophic for edge deployments where you need thousands of proxy instances. MicroWARP changes this equation entirely, delivering full SOCKS5 proxy functionality in under 1MB of memory.

This isn’t theoretical optimization. When you’re deploying IoT gateways, serverless functions, or high-density Kubernetes pods, the difference between 100MB and 800KB per instance determines whether your infrastructure costs $10,000 or $100 per month. I’ve seen teams abandon WARP entirely because they couldn’t justify the memory overheadβ€”MicroWARP solves this problem at the architectural level.

In this guide, you’ll understand exactly why MicroWARP achieves roughly 100x memory reduction, how to deploy it in production environments, and when this approach makes sense for your infrastructure.

Prerequisites

Before diving in, ensure you have:

  • Docker Engine 20.10+ with BuildKit enabled
  • Linux kernel 5.6+ (for native WireGuard support)
  • Basic understanding of networking concepts (TCP/IP, proxies, VPNs)
  • A Cloudflare account with WARP registration capability
  • kubectl if deploying to Kubernetes
  • 2GB free disk space for building images

Verify your kernel supports WireGuard:

1
2
3
4
5
6
7
8
# Check kernel version
uname -r
# Should output 5.6 or higher

# Verify WireGuard module availability
sudo modprobe wireguard
lsmod | grep wireguard
# Should show wireguard module loaded

πŸ’‘ If you’re on an older kernel, WireGuard can be compiled as a DKMS module, but native kernel support provides the performance benefits we’ll discuss.

Architecture and Key Concepts

Why Traditional WARP Clients Are Memory-Hungry

The official Cloudflare WARP client (warp-cli) is designed for end-user devices. It includes:

  • A full GUI framework (even in CLI mode, libraries are loaded)
  • User-space TUN/TAP packet processing
  • DNS resolution caching with extensive buffers
  • Connection pooling for multiple simultaneous tunnels
  • Automatic update mechanisms
  • Telemetry and diagnostics systems

Each of these features adds memory overhead. The user-space packet processing alone requires copying every network packet between kernel and application memoryβ€”twice per packet direction.

MicroWARP’s Kernel-First Architecture

MicroWARP takes a fundamentally different approach: push everything possible into kernel space and keep user space minimal.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Traditional WARP Architecture     β”‚    β”‚      MicroWARP Architecture         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€    β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                     β”‚    β”‚                                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                  β”‚    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                  β”‚
β”‚  β”‚  Application  β”‚                  β”‚    β”‚  β”‚  Application  β”‚                  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚
β”‚          β–Ό                          β”‚    β”‚          β–Ό                          β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” ◄─ User Space    β”‚    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” ◄─ User Space    β”‚
β”‚  β”‚ SOCKS5 Proxy  β”‚    (High Memory) β”‚    β”‚  β”‚ Minimal SOCKS5β”‚    (~200KB RSS)  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚    β”‚  β”‚    Server     β”‚                  β”‚
β”‚          β–Ό                          β”‚    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” ◄─ User Space    β”‚    β”‚          β–Ό                          β”‚
β”‚  β”‚  TUN Device   β”‚    Processing    β”‚    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” ◄─ Kernel Space  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚    β”‚  β”‚   WireGuard   β”‚    (Zero RSS)    β”‚
β”‚          β–Ό                          β”‚    β”‚  β”‚ Kernel Module β”‚                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” ◄─ User Space    β”‚    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚
β”‚  β”‚   WireGuard   β”‚                  β”‚    β”‚          β–Ό                          β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                  β”‚
β”‚          β–Ό                          β”‚    β”‚  β”‚ Kernel Networkβ”‚                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                  β”‚    β”‚  β”‚     Stack     β”‚                  β”‚
β”‚  β”‚ Kernel Networkβ”‚                  β”‚    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚
β”‚  β”‚     Stack     β”‚                  β”‚    β”‚          β–Ό                          β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                  β”‚
β”‚          β–Ό                          β”‚    β”‚  β”‚  Physical NIC β”‚                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                  β”‚    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚
β”‚  β”‚  Physical NIC β”‚                  β”‚    β”‚                                     β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚    β”‚                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The critical insight: WireGuard has been part of the Linux kernel since version 5.6. When you use the kernel module instead of user-space implementations, packet processing happens entirely in kernel memory. No buffer copies, no context switches, no garbage collection overhead.

Memory Breakdown Comparison

ComponentTraditional WARPMicroWARP
WireGuard processing15-30MB (user-space)0MB (kernel)
SOCKS5 proxy20-40MB~200KB
DNS caching10-20MB0MB (delegated)
Connection buffers30-50MB~400KB
Runtime overhead10-20MB~200KB
Total85-160MB~800KB

The SOCKS5 Minimal Implementation

MicroWARP’s SOCKS5 server is written in pure C with zero external dependencies beyond libc. It uses:

  • Single-threaded event loop with epoll() instead of thread-per-connection
  • Fixed-size buffer pools instead of dynamic allocation
  • Direct socket forwarding without intermediate buffering when possible
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        MicroWARP Data Flow                                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                             β”‚
β”‚  Application          SOCKS5 Server       WireGuard (Kernel)   Cloudflare  β”‚
β”‚      β”‚                     β”‚                     β”‚                  β”‚       β”‚
β”‚      β”‚ SOCKS5 CONNECT      β”‚                     β”‚                  β”‚       β”‚
β”‚      │────────────────────►│                     β”‚                  β”‚       β”‚
β”‚      β”‚                     β”‚                     β”‚                  β”‚       β”‚
β”‚      β”‚                     β”‚ Parse destination   β”‚                  β”‚       β”‚
β”‚      β”‚                     β”‚ (minimal allocation)β”‚                  β”‚       β”‚
β”‚      β”‚                     β”‚                     β”‚                  β”‚       β”‚
β”‚      β”‚                     β”‚ Connect via wg0     β”‚                  β”‚       β”‚
β”‚      β”‚                     │────────────────────►│                  β”‚       β”‚
β”‚      β”‚                     β”‚                     β”‚                  β”‚       β”‚
β”‚      β”‚                     β”‚                     β”‚ Encrypted tunnel β”‚       β”‚
β”‚      β”‚                     β”‚                     β”‚ (kernel space)   β”‚       β”‚
β”‚      β”‚                     β”‚                     │─────────────────►│       β”‚
β”‚      β”‚                     β”‚                     β”‚                  β”‚       β”‚
β”‚      β”‚                     β”‚                     │◄─────────────────│       β”‚
β”‚      β”‚                     β”‚                     β”‚ Connection       β”‚       β”‚
β”‚      β”‚                     │◄────────────────────│ established      β”‚       β”‚
β”‚      β”‚                     β”‚ Socket ready        β”‚                  β”‚       β”‚
β”‚      │◄────────────────────│                     β”‚                  β”‚       β”‚
β”‚      β”‚ SOCKS5 success      β”‚                     β”‚                  β”‚       β”‚
β”‚      β”‚                     β”‚                     β”‚                  β”‚       β”‚
β”‚      β”‚ ═══════════════════════════════════════════════════════════ β”‚       β”‚
β”‚      β”‚                    Data Transfer Loop                        β”‚       β”‚
β”‚      β”‚ ═══════════════════════════════════════════════════════════ β”‚       β”‚
β”‚      β”‚                     β”‚                     β”‚                  β”‚       β”‚
β”‚      β”‚ Application data    β”‚                     β”‚                  β”‚       β”‚
β”‚      │────────────────────►│                     β”‚                  β”‚       β”‚
β”‚      β”‚                     β”‚ splice() zero-copy  β”‚                  β”‚       β”‚
β”‚      β”‚                     │────────────────────►│                  β”‚       β”‚
β”‚      β”‚                     β”‚                     β”‚ Encrypted        β”‚       β”‚
β”‚      β”‚                     β”‚                     │─────────────────►│       β”‚
β”‚      β”‚                     β”‚                     │◄─────────────────│       β”‚
β”‚      β”‚                     │◄────────────────────│ Response         β”‚       β”‚
β”‚      β”‚                     β”‚ splice() zero-copy  β”‚                  β”‚       β”‚
β”‚      │◄────────────────────│                     β”‚                  β”‚       β”‚
β”‚      β”‚ Response data       β”‚                     β”‚                  β”‚       β”‚
β”‚                                                                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The splice() system call is crucial hereβ€”it transfers data between file descriptors entirely in kernel space, avoiding the copy to user memory that read()/write() would require.

Step-by-Step Implementation

Setting Up the Base MicroWARP Container

First, create the project structure:

1
2
mkdir microwarp-deployment && cd microwarp-deployment
mkdir -p config scripts

Create the Docker Compose configuration:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# docker-compose.yml
version: '3.8'

services:
  microwarp:
    image: ghcr.io/microwarp/microwarp:latest
    container_name: microwarp-proxy
    
    # Required for WireGuard kernel module access
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    
    # Access to kernel networking
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
      - net.ipv4.ip_forward=1
      - net.ipv6.conf.all.disable_ipv6=0
    
    # Mount WireGuard configuration
    volumes:
      - ./config/wg0.conf:/etc/wireguard/wg0.conf:ro
      - /lib/modules:/lib/modules:ro
    
    # Expose SOCKS5 proxy port
    ports:
      - "1080:1080"
    
    # Resource constraints demonstrating minimal footprint
    deploy:
      resources:
        limits:
          memory: 4M  # 4MB limit with 800KB typical usage
          cpus: '0.1'
        reservations:
          memory: 1M
    
    # Health check for orchestration
    healthcheck:
      test: ["CMD", "nc", "-z", "localhost", "1080"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s
    
    restart: unless-stopped
    
    environment:
      - SOCKS5_PORT=1080
      - SOCKS5_BIND=0.0.0.0
      - LOG_LEVEL=warn
      - BUFFER_SIZE=16384  # 16KB buffers, tunable

⚠️ The NET_ADMIN and SYS_MODULE capabilities are required for WireGuard interface management. In production Kubernetes, use a privileged init container or pre-configure the interface at the node level.

Generating WARP Configuration

Cloudflare WARP uses WireGuard under the hood. We need to register with WARP and extract the WireGuard configuration:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#!/bin/bash
# scripts/generate-warp-config.sh

# This script registers with Cloudflare WARP and generates WireGuard config
# Requires: curl, jq, wg (wireguard-tools)

set -euo pipefail

CONFIG_DIR="${1:-./config}"
mkdir -p "$CONFIG_DIR"

echo "Generating WireGuard keypair..."
PRIVATE_KEY=$(wg genkey)
PUBLIC_KEY=$(echo "$PRIVATE_KEY" | wg pubkey)

echo "Registering with Cloudflare WARP..."
# Registration endpoint (this creates a new device)
REGISTRATION=$(curl -sS -X POST "https://api.cloudflareclient.com/v0a2158/reg" \
  -H "Content-Type: application/json" \
  -H "CF-Client-Version: a-6.11-2223" \
  -d "{
    \"key\": \"$PUBLIC_KEY\",
    \"install_id\": \"\",
    \"fcm_token\": \"\",
    \"tos\": \"$(date -u +%Y-%m-%dT%H:%M:%S.000Z)\",
    \"model\": \"Linux\",
    \"serial_number\": \"$(cat /proc/sys/kernel/random/uuid)\"
  }")

# Check for registration errors
if echo "$REGISTRATION" | jq -e '.success == false' > /dev/null 2>&1; then
    echo "Error: Registration failed"
    echo "$REGISTRATION" | jq '.errors'
    exit 1
fi

# Extract configuration values
WARP_ID=$(echo "$REGISTRATION" | jq -r '.id')
WARP_TOKEN=$(echo "$REGISTRATION" | jq -r '.token')
WARP_ENDPOINT=$(echo "$REGISTRATION" | jq -r '.config.peers[0].endpoint.host')
WARP_PEER_KEY=$(echo "$REGISTRATION" | jq -r '.config.peers[0].public_key')
CLIENT_IPV4=$(echo "$REGISTRATION" | jq -r '.config.interface.addresses.v4')
CLIENT_IPV6=$(echo "$REGISTRATION" | jq -r '.config.interface.addresses.v6')

echo "Generating WireGuard configuration..."
cat > "$CONFIG_DIR/wg0.conf" << EOF
[Interface]
# MicroWARP WireGuard Configuration
# Generated: $(date -u +%Y-%m-%dT%H:%M:%SZ)
PrivateKey = $PRIVATE_KEY
Address = $CLIENT_IPV4/32, $CLIENT_IPV6/128
DNS = 1.1.1.1, 2606:4700:4700::1111
# Keep MTU low to avoid fragmentation in containers
MTU = 1280

[Peer]
# Cloudflare WARP endpoint
PublicKey = $WARP_PEER_KEY
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = ${WARP_ENDPOINT}:2408
# Keepalive essential for NAT traversal in containers
PersistentKeepalive = 25
EOF

# Store credentials for potential re-registration
cat > "$CONFIG_DIR/warp-credentials.json" << EOF
{
  "id": "$WARP_ID",
  "token": "$WARP_TOKEN",
  "public_key": "$PUBLIC_KEY"
}
EOF

chmod 600 "$CONFIG_DIR/wg0.conf" "$CONFIG_DIR/warp-credentials.json"

echo "Configuration generated successfully!"
echo "WARP Device ID: $WARP_ID"
echo "Client IPv4: $CLIENT_IPV4"
echo "Client IPv6: $CLIENT_IPV6"

Run the configuration generator:

1
2
chmod +x scripts/generate-warp-config.sh
./scripts/generate-warp-config.sh

πŸ“ The generated configuration registers a new WARP device with Cloudflare. Each device has usage limits on the free tier. For production, use WARP+ or Cloudflare Zero Trust with your organization’s credentials.

Deploying as a Kubernetes Sidecar

For Kubernetes deployments, MicroWARP excels as a sidecar proxy. Here’s a complete deployment manifest:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# kubernetes/deployment-with-sidecar.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-with-warp-proxy
  labels:
    app: proxied-application
spec:
  replicas: 3
  selector:
    matchLabels:
      app: proxied-application
  template:
    metadata:
      labels:
        app: proxied-application
      annotations:
        # Track MicroWARP sidecar for monitoring
        prometheus.io/scrape: "true"
        prometheus.io/port: "9090"
    spec:
      # Init container to set up WireGuard interface
      initContainers:
        - name: wireguard-init
          image: ghcr.io/microwarp/microwarp-init:latest
          securityContext:
            capabilities:
              add:
                - NET_ADMIN
            privileged: false
          volumeMounts:
            - name: wg-config
              mountPath: /etc/wireguard
              readOnly: true
          command:
            - /bin/sh
            - -c
            - |
              # Load WireGuard kernel module if not loaded
              modprobe wireguard || true
              # Create interface (will be used by sidecar)
              wg-quick up wg0 || true
              echo "WireGuard interface initialized"
      
      containers:
        # Main application container
        - name: application
          image: your-app:latest
          env:
            # Configure app to use sidecar SOCKS5 proxy
            - name: HTTP_PROXY
              value: "socks5://127.0.0.1:1080"
            - name: HTTPS_PROXY
              value: "socks5://127.0.0.1:1080"
            - name: ALL_PROXY
              value: "socks5://127.0.0.1:1080"
          resources:
            limits:
              memory: "256Mi"
              cpu: "500m"
        
        # MicroWARP sidecar - note the minimal resources
        - name: microwarp-sidecar
          image: ghcr.io/microwarp/microwarp:latest
          ports:
            - containerPort: 1080
              name: socks5
              protocol: TCP
          env:
            - name: SOCKS5_PORT
              value: "1080"
            - name: SOCKS5_BIND
              value: "127.0.0.1"  # Only localhost in sidecar mode
            - name: LOG_LEVEL
              value: "error"  # Minimal logging for production
          resources:
            # These limits are not aspirational - they're real
            limits:
              memory: "4Mi"
              cpu: "50m"
            requests:
              memory: "1Mi"
              cpu: "10m"
          securityContext:
            capabilities:
              add:
                - NET_ADMIN
            readOnlyRootFilesystem: true
            runAsNonRoot: false  # Required for interface management
          livenessProbe:
            tcpSocket:
              port: 1080
            initialDelaySeconds: 5
            periodSeconds: 10
          readinessProbe:
            tcpSocket:
              port: 1080
            initialDelaySeconds: 2
            periodSeconds: 5
          volumeMounts:
            - name: wg-config
              mountPath: /etc/wireguard
              readOnly: true
      
      volumes:
        - name: wg-config
          secret:
            secretName: microwarp-wg-config
            defaultMode: 0600

---
# Secret containing WireGuard configuration
apiVersion: v1
kind: Secret
metadata:
  name: microwarp-wg-config
type: Opaque
stringData:
  wg0.conf: |
    [Interface]
    PrivateKey = YOUR_PRIVATE_KEY_HERE
    Address = 172.16.0.2/32
    MTU = 1280
    
    [Peer]
    PublicKey = CLOUDFLARE_PUBLIC_KEY
    AllowedIPs = 0.0.0.0/0, ::/0
    Endpoint = engage.cloudflareclient.com:2408
    PersistentKeepalive = 25

Production Configuration

Multi-Container Network Topology

When multiple containers need to share a single MicroWARP proxy, use Docker’s network features:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# docker-compose.production.yml
version: '3.8'

networks:
  proxy-network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.28.0.0/16

services:
  microwarp:
    image: ghcr.io/microwarp/microwarp:latest
    container_name: shared-proxy
    networks:
      proxy-network:
        ipv4_address: 172.28.0.10
    cap_add:
      - NET_ADMIN
    volumes:
      - ./config/wg0.conf:/etc/wireguard/wg0.conf:ro
    environment:
      - SOCKS5_PORT=1080
      - SOCKS5_BIND=0.0.0.0
      # Connection limits to prevent resource exhaustion
      - MAX_CONNECTIONS=500
      - CONNECTION_TIMEOUT=30
    deploy:
      resources:
        limits:
          memory: 8M  # Higher limit for shared proxy
          cpus: '0.2'
    healthcheck:
      test: ["CMD", "nc", "-z", "localhost", "1080"]
      interval: 10s
      timeout: 3s
      retries: 3

  # Example application containers using shared proxy
  web-scraper:
    image: python:3.11-slim
    networks:
      - proxy-network
    environment:
      - HTTP_PROXY=socks5://172.28.0.10:1080
      - HTTPS_PROXY=socks5://172.28.0.10:1080
    depends_on:
      microwarp:
        condition: service_healthy
    command: python scraper.py

  api-client:
    image: node:20-alpine
    networks:
      - proxy-network
    environment:
      - ALL_PROXY=socks5://172.28.0.10:1080
    depends_on:
      microwarp:
        condition: service_healthy
    command: node client.js

Tuning Buffer Sizes

The buffer size directly impacts memory usage and throughput. Here’s how to tune it:

1
2
3
4
5
6
7
8
9
# Environment variables for MicroWARP tuning
BUFFER_SIZE=16384      # 16KB - good for most HTTP traffic
BUFFER_SIZE=65536      # 64KB - better for file transfers
BUFFER_SIZE=4096       # 4KB - minimum for memory-constrained environments

# Calculate expected memory usage:
# Base overhead: ~200KB
# Per-connection: BUFFER_SIZE * 2 (read + write buffers)
# Example with 100 connections and 16