Skip to content

Production Deployment

This guide covers everything needed to deploy mik in a production environment.

Before deploying to production:

  1. Build mik with release optimizations: cargo build --release
  2. Configure reverse proxy (nginx/Caddy) for TLS termination
  3. Set up monitoring and alerting
  4. Configure log aggregation
  5. Test health endpoints
ResourceMinimumRecommended
CPU2 cores4+ cores
RAM512 MB2+ GB
Disk1 GB10+ GB (for AOT cache)
  • Each WASM module consumes memory when loaded
  • AOT-compiled modules are cached on disk (.wasm.aot files)
  • LRU cache evicts least-used modules when max_cache_mb is reached
[Client] --> [Reverse Proxy (nginx/Caddy)] --> [mik :3000] --> [Sidecars]
|
[TLS, Rate Limiting]
PortServiceAccess
443Reverse proxy (HTTPS)Public
3000mik HTTP serverInternal only
9919Daemon APIInternal only

Always set a strong API key for daemon endpoints:

Terminal window
# Generate a strong API key
export MIK_API_KEY="$(openssl rand -hex 32)"
# Start with API key
mik run --api-key "$MIK_API_KEY" myapp.wasm
# Or for daemon mode
mik dev

All daemon API requests must include the key:

Terminal window
curl -H "X-API-Key: $MIK_API_KEY" http://localhost:9919/instances
Terminal window
# Restrict mik data directory
chmod 700 /var/lib/mik
# Protect configuration
chmod 600 /etc/mik/mik.toml
# Ensure WASM modules are read-only
chmod 644 /var/lib/mik/modules/*.wasm

Limit outbound HTTP access in mik.toml:

[server]
# Only allow specific hosts
http_allowed = ["api.internal.example.com", "*.supabase.co"]
# Or disable all outbound HTTP
http_allowed = []
upstream mik {
server 127.0.0.1:3000;
keepalive 32;
}
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/ssl/certs/api.example.com.pem;
ssl_certificate_key /etc/ssl/private/api.example.com.key;
# Security headers
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# Rate limiting
limit_req zone=api burst=20 nodelay;
location / {
proxy_pass http://mik;
proxy_http_version 1.1;
proxy_set_header Connection "";
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;
# Timeouts
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
# Health check endpoint (no rate limiting)
location /health {
proxy_pass http://mik;
limit_req off;
}
}
api.example.com {
reverse_proxy localhost:3000 {
header_up X-Forwarded-Proto {scheme}
}
# Rate limiting
rate_limit {
zone api {
key {remote_host}
events 100
window 1m
}
}
}
[project]
name = "production-api"
version = "1.0.0"
[server]
port = 3000
modules = "modules/"
cache_size = 100
max_cache_mb = 512
execution_timeout_secs = 30
max_concurrent_requests = 2000
max_per_module_requests = 50
shutdown_timeout_secs = 60
log_max_size_mb = 50
log_max_files = 10
http_allowed = ["*.internal.example.com"]
[tracing]
service_name = "production-api"
otlp_endpoint = "http://tempo:4317"
VariableDescriptionExample
PORTServer port3000
HOSTBind address127.0.0.1
RUST_LOGLog levelinfo
MIK_API_KEYDaemon API key<hex string>
MIK_HOT_RELOADEnable hot reload0 (disabled in prod)

Simplest deployment for low-traffic services:

Terminal window
mik run --port 3000 /var/lib/mik/app.wasm

For horizontal scaling:

Terminal window
# Instance 1
mik run --port 3001 app.wasm
# Instance 2
mik run --port 3002 app.wasm

nginx upstream:

upstream mik {
least_conn;
server 127.0.0.1:3001;
server 127.0.0.1:3002;
}

For applications needing KV, SQL, or Storage:

Terminal window
# Starts daemon on 9919, app on 3000
mik run --detach --name myapp --port 3000

Configure load balancer health checks:

Terminal window
# Basic liveness
curl -sf http://localhost:3000/health
# Readiness (checks module cache)
curl -sf http://localhost:3000/health

Expected response:

{
"status": "ready",
"cache_size": 5,
"cache_capacity": 100,
"total_requests": 1000
}

mik handles SIGTERM gracefully:

  1. Stops accepting new connections
  2. Waits for in-flight requests (up to shutdown_timeout_secs)
  3. Closes connections cleanly
  4. Exits with code 0
Terminal window
# Graceful shutdown
kill -TERM $(pgrep mik)
PathContentsFrequency
/var/lib/mik/modules/WASM modulesOn deploy
/var/lib/mik/data/Daemon state (redb, SQLite)Daily
/etc/mik/mik.tomlConfigurationOn change
  1. Stop mik: systemctl stop mik
  2. Restore files from backup
  3. Verify permissions
  4. Start mik: systemctl start mik
  5. Verify health: curl http://localhost:3000/health