Deployment
BlocMarket’s primary production path runs the API as a static MUSL binary under systemd on Linux, with nginx terminating TLS and serving the Leptos WASM frontend.
Client (browser/mobile) | vnginx (443) -- TLS termination | +-- api.blocmarket.org --> 127.0.0.1:8090 (bloc-api) +-- app.blocmarket.org --> /opt/blocmarket/web/dist (static files)| Component | Technology |
|---|---|
| API | Static MUSL binary (bloc-api) under systemd |
| Web | Leptos WASM frontend served by nginx |
| Database | PostgreSQL 16 + PostGIS 3.4 (Supabase or local) |
| Cache | Redis 7 |
One-Time Server Setup
Section titled “One-Time Server Setup”cd /opt/blocmarket/deploy/systemdsudo bash install.shThis installs the blocmarket-api.service unit and creates the dedicated service user.
Deploy from a Development Machine
Section titled “Deploy from a Development Machine”The deploy script in deploy/ builds the release binary and transfers it to the server:
./deploy.sh # Build and deploy./deploy.sh --build-only # Build only (no remote transfer)./deploy.sh --restart-only # Restart service only (no rebuild)The script automatically backs up the previous binary before uploading the new one.
Configuration
Section titled “Configuration”All runtime configuration lives in /opt/blocmarket/.env, read by the systemd service via EnvironmentFile=:
ssh <server>sudo nano /opt/blocmarket/.envsudo systemctl restart blocmarket-api| Variable | Description |
|---|---|
API_PORT | Port the API binds to (default: 8090) |
DATABASE_URL | PostgreSQL connection string |
REDIS_URL | Redis connection URL |
JWT_SECRET | Token signing secret (min 32 chars) |
CORS_ALLOWED_ORIGINS | Comma-separated allowed origins |
RUST_LOG | Log level filter |
Server Operations
Section titled “Server Operations”# Statussudo systemctl status blocmarket-api
# Logssudo journalctl -u blocmarket-api -f # Live tailsudo journalctl -u blocmarket-api -n 100 # Last 100 linessudo journalctl -u blocmarket-api -b # Since last boot
# Restart / stop / startsudo systemctl restart blocmarket-apisudo systemctl stop blocmarket-apisudo systemctl start blocmarket-apiRollback
Section titled “Rollback”The deploy script keeps timestamped backups of previous binaries:
# List backupsssh <server> 'ls -la /opt/blocmarket/bin/bloc-api.bak.*'
# Roll back to a previous versionssh <server>sudo cp /opt/blocmarket/bin/bloc-api.bak.YYYYMMDDHHMMSS /opt/blocmarket/bin/bloc-apisudo systemctl restart blocmarket-apinginx Setup
Section titled “nginx Setup”sudo apt install nginx
# Install configsudo cp deploy/nginx/blocmarket.conf /etc/nginx/sites-available/blocmarket.confsudo ln -sf /etc/nginx/sites-available/blocmarket.conf /etc/nginx/sites-enabled/blocmarket.confsudo rm -f /etc/nginx/sites-enabled/defaultsudo nginx -tsudo systemctl reload nginxTLS Certificates (Let’s Encrypt)
Section titled “TLS Certificates (Let’s Encrypt)”sudo apt install certbot python3-certbot-nginxsudo certbot --nginx -d api-blocmarket.wyattau.com -d app.blocmarket.wyattau.comCertbot modifies the nginx config to add TLS. Certificates auto-renew via the certbot systemd timer. HTTP is redirected to HTTPS with a 301.
systemd Hardening
Section titled “systemd Hardening”The service unit applies these restrictions:
- Runs as dedicated
blocmarketuser (no home, no shell) ProtectSystem=strictwith explicitReadWritePathsNoNewPrivileges,PrivateTmp,MemoryDenyWriteExecute- Only
CAP_NET_BIND_SERVICEcapability ProtectKernelTunables,ProtectKernelModules,ProtectControlGroups- File descriptor limit: 65536
Docker Compose (Production)
Section titled “Docker Compose (Production)”A production compose file is available at deploy/docker-compose.prod.yml for containerised single-node deployments. The API container maps port 3000; local development uses 8090.
Kubernetes / Helm
Section titled “Kubernetes / Helm”Kustomize bases and overlays live in deploy/k8s/ (with dev and prod overlays), and a Helm chart in deploy/helm/blocmarket/ including deployment, service, ingress, and HPA templates:
# Kustomizekubectl apply -k deploy/k8s/overlays/prod
# Helmhelm upgrade --install blocmarket deploy/helm/blocmarket --values deploy/helm/blocmarket/values.yamlBlue-Green Deployments
Section titled “Blue-Green Deployments”deploy/blue-green.sh supports zero-downtime cutover between two service generations for environments that require it.
Post-Deployment Verification
Section titled “Post-Deployment Verification”# Health endpoints (all must return 200)curl -sf https://api-blocmarket.wyattau.com/healthcurl -sf https://api-blocmarket.wyattau.com/health/dbcurl -sf https://api-blocmarket.wyattau.com/health/rediscurl -sf https://api-blocmarket.wyattau.com/ready
# Security headerscurl -sI https://api-blocmarket.wyattau.com/health | \ grep -iE 'strict-transport|x-frame|x-content-type|content-security|referrer-policy'
# TLS certificateecho | openssl s_client -servername api-blocmarket.wyattau.com \ -connect api-blocmarket.wyattau.com:443 2>/dev/null | \ openssl x509 -noout -subject -dates -issuerSecurity Checklist
Section titled “Security Checklist”-
JWT_SECRETis 32+ chars and unique per environment -
DATABASE_URLuses TLS (Supabase requires SSL) -
CORS_ALLOWED_ORIGINSexcludes*andlocalhost - Rate limiting is enabled (Redis reachable)
- TLS certificates valid and auto-renewing
- Security headers enforced
- Metrics endpoint restricted to the internal network