Building for Production
When you develop locally, you run your app withgo run. But for production, you need to compile your code into an executable file (called a binary) that can run on your server without needing Go installed.
Go compiles your application into a single binary with no external dependencies. Unlike languages that need a runtime (like Python or Node.js), Go bundles everything into one file. This makes deployment remarkably simple—just copy the file to your server and run it.
Basic Build
Optimized Production Build
For production, you want a smaller, faster binary. You also need to specify which operating system and CPU architecture the binary should run on. This is called cross-compilation—building on your Mac or Windows machine for a Linux server.| Flag | Purpose |
|---|---|
CGO_ENABLED=0 | Creates a pure Go binary with no C dependencies, making it fully portable |
GOOS=linux | Tells Go to build for Linux (even if you’re on Mac or Windows) |
GOARCH=amd64 | Targets Intel/AMD 64-bit CPUs (most cloud servers use this) |
-ldflags="-s -w" | Strips debug symbols, reducing binary size by ~30% |
Common Architectures
| Target | GOOS | GOARCH |
|---|---|---|
| Linux x86-64 | linux | amd64 |
| Linux ARM64 (AWS Graviton, M1) | linux | arm64 |
| macOS Intel | darwin | amd64 |
| macOS Apple Silicon | darwin | arm64 |
| Windows | windows | amd64 |
Deployment Decision Guide
Choose your deployment method based on your needs:| Method | Best For | Complexity |
|---|---|---|
| Docker | Consistent environments, easy scaling | Low |
| Kubernetes | Large-scale, complex deployments | High |
| Cloud Platforms | Managed infrastructure, auto-scaling | Medium |
| Serverless | Event-driven, variable traffic | Low |
| Traditional | Simple apps, full control | Low |
Essential Configuration
Environment Variables
Read configuration from environment variables for flexibility:Common Environment Variables
| Variable | Purpose | Example |
|---|---|---|
PORT | HTTP listen port | 3000 |
ENV | Environment name | production |
DATABASE_URL | Database connection | postgres://... |
LOG_LEVEL | Logging verbosity | info |
SHUTDOWN_TIMEOUT | Graceful shutdown | 30s |
Configuration Pattern
Health Checks
In production, your application runs alongside infrastructure that monitors its status. Health checks are special endpoints that answer a simple question: “Is this application working properly?” Load balancers use health checks to decide which servers should receive traffic. If your app becomes unhealthy (maybe the database connection dropped), the load balancer stops sending requests to it until it recovers. Orchestrators like Kubernetes use health checks to automatically restart containers that have crashed or become unresponsive. Mizu provides built-in health check handlers that work with all major platforms:| Endpoint | Normal | Shutting Down | Use |
|---|---|---|---|
/livez | 200 | 200 | Container restart decision |
/readyz | 200 | 503 | Load balancer routing |
Custom Health Checks
Graceful Shutdown
When you need to update your application or restart the server, you don’t want to abruptly kill connections—that would interrupt users mid-request, potentially losing data or causing errors. Graceful shutdown solves this by giving active requests time to complete before the server stops. Here’s what happens: when your server receives a shutdown signal (like when you press Ctrl+C or when Kubernetes scales down), it stops accepting new requests but waits for current requests to finish. This ensures users don’t experience sudden disconnections. Mizu handles graceful shutdown automatically. You can configure how long to wait for active requests:Shutdown Process
- Server receives SIGINT or SIGTERM
/readyzstarts returning 503- Server stops accepting new connections
- Active requests complete (up to timeout)
- Server exits cleanly
Logging in Production
During development, you want human-readable logs that are easy to scan visually. But in production, your logs are consumed by machines—log aggregation systems that collect, search, and alert on your application’s output. These systems work best with structured JSON logs, where each log entry is a JSON object with consistent fields. JSON logs enable powerful queries like “show me all errors from the payment service in the last hour” or “find requests that took longer than 500ms.” This would be difficult with plain text logs. Configure structured JSON logging for production:Log Aggregation
In production, send logs to a centralized system:| Platform | How to Collect |
|---|---|
| AWS CloudWatch | CloudWatch Logs agent |
| Google Cloud | Automatic from stdout |
| Datadog | Datadog agent |
| Elastic | Filebeat or Fluentd |
| Loki | Promtail |
Security Checklist
Production environments are exposed to the internet, which means your application will face automated attacks, vulnerability scanners, and potentially malicious users. Security isn’t optional—it’s a core requirement for any public-facing application. The good news is that most security measures are straightforward to implement. Here’s a checklist of essential security practices to complete before deploying:- HTTPS only - Use TLS via reverse proxy or load balancer
- Security headers - Use the helmet middleware
- Rate limiting - Protect against abuse
- Input validation - Validate all user input
- Secrets management - Never commit secrets to git
- Minimal permissions - Run as non-root user
- Dependencies - Keep dependencies updated
- Error messages - Don’t expose internal errors to users
Security Middleware
Monitoring
Once your application is running in production, you need visibility into how it’s performing. Monitoring collects metrics like request counts, response times, and error rates. This data helps you answer questions like “Is my app getting slower?” or “Did that deployment cause more errors?” Without monitoring, you’re flying blind—you won’t know about problems until users complain. With proper monitoring, you can set up alerts to notify you before small issues become outages.Prometheus Metrics
Prometheus is the most popular open-source monitoring system. It collects metrics by periodically “scraping” a/metrics endpoint that your app exposes. Here’s how to add it:
Key Metrics to Monitor
| Metric | What to Watch |
|---|---|
| Request rate | Unusual spikes or drops |
| Error rate | Increase in 4xx/5xx |
| Latency p50/p95/p99 | Slow requests |
| CPU/Memory | Resource usage |
| Active connections | Connection pool exhaustion |