Skip to content

Production Deployment

This guide covers deploying tenement to production with HTTPS, automatic restarts, and proper security.

The fastest path to production on a Linux server:

Terminal window
# Install tenement
cargo install tenement-cli
# Create config
cat > /etc/tenement/tenement.toml << 'EOF'
[settings]
data_dir = "/var/lib/tenement"
[service.api]
command = "./my-api"
socket = "/tmp/tenement/api-{id}.sock"
health = "/health"
[instances]
api = ["prod"]
EOF
# Install as systemd service and generate Caddy config
ten install --caddy --domain example.com

This creates:

  • A systemd service (tenement.service)
  • A Caddyfile with automatic HTTPS
  • Proper file permissions and security hardening

tenement can handle TLS directly using Let’s Encrypt.

Terminal window
ten serve --tls --domain example.com --email admin@example.com
  1. tenement requests certificates from Let’s Encrypt
  2. HTTP-01 challenge verifies domain ownership
  3. Certificates auto-renew before expiry
  4. All traffic is encrypted

Check certificate status:

Terminal window
curl https://example.com/api/tls/status
{
"enabled": true,
"domain": "example.com",
"staging": false,
"https_port": 443,
"http_port": 80,
"status": "running"
}

For wildcard subdomain routing (*.example.com), use Caddy with DNS challenge:

Terminal window
# Generate Caddyfile with DNS provider support
ten caddy --domain example.com --dns-provider cloudflare
# Set DNS token via environment for Caddy
export CF_API_TOKEN=$CF_API_TOKEN
caddy run --config /etc/caddy/Caddyfile

Supported DNS providers (via Caddy):

  • cloudflare - Cloudflare API token
  • route53 - AWS Route53 (uses AWS credentials)
  • digitalocean - DigitalOcean API token

The DNS-01 challenge creates a TXT record to prove domain ownership, enabling wildcard certificates.

Use Caddy for TLS termination with tenement handling routing.

Terminal window
ten caddy --domain example.com --output /etc/caddy/Caddyfile

Generated Caddyfile:

{
email admin@example.com
}
example.com {
reverse_proxy unix//tmp/tenement/tenement.sock
}
*.example.com {
reverse_proxy unix//tmp/tenement/tenement.sock
}
Terminal window
# Debian/Ubuntu
apt install caddy
# Or with ten caddy --install
ten caddy --domain example.com --install
Terminal window
# tenement listens on a port (Caddy will proxy to it)
ten serve --port 8080
# Caddy handles TLS and proxies to tenement
systemctl start caddy
  • Automatic HTTPS with Let’s Encrypt
  • Wildcard certificates with DNS challenge
  • Zero-downtime certificate renewals
  • Battle-tested TLS configuration
Terminal window
ten install

This creates /etc/systemd/system/tenement.service:

[Unit]
Description=tenement process hypervisor
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/ten serve
Restart=always
RestartSec=5
# Security hardening
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/lib/tenement /tmp/tenement
PrivateTmp=yes
[Install]
WantedBy=multi-user.target
Terminal window
# Start/stop/restart
systemctl start tenement
systemctl stop tenement
systemctl restart tenement
# View logs
journalctl -u tenement -f
# Enable on boot
systemctl enable tenement
Terminal window
ten uninstall

Removes the systemd service file and disables the service.

Install tenement with systemd + Caddy + TLS in one command:

Terminal window
ten install --caddy --domain example.com --dns-provider cloudflare

What this does:

  1. Creates systemd service for tenement
  2. Generates Caddyfile with wildcard support
  3. Configures DNS-01 challenge for wildcards
  4. Enables both services on boot
FlagDescription
--caddyGenerate Caddyfile
--domain <domain>Domain for routing
--email <email>Email for Let’s Encrypt
--dns-provider <provider>DNS provider for Caddy wildcard certs
--installAlso install Caddy (apt)
--systemdEnable systemd services on boot
--dry-runShow what would be done
FilePurpose
/etc/tenement/tenement.tomlMain configuration
/var/lib/tenement/Instance data directories
/tmp/tenement/Unix sockets
/etc/systemd/system/tenement.servicesystemd unit
/etc/caddy/CaddyfileCaddy configuration

Only expose ports 80 and 443:

Terminal window
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

Generate and use auth tokens:

Terminal window
# Generate token
ten token-gen
# Use token for API calls
curl -H "Authorization: Bearer $TOKEN" https://example.com/api/instances

Prevent runaway processes:

[service.api]
memory_limit_mb = 256
cpu_shares = 100
storage_quota_mb = 100

Scrape https://example.com/metrics for:

  • Instance counts and states
  • Request latencies
  • Memory/CPU per instance
  • Storage usage
Terminal window
curl https://example.com/health

Returns 200 if the server is healthy.