Prerequisites
- A Linux server (Ubuntu 22.04, Debian 12, or similar)
- SSH access with sudo privileges
- A domain name pointing to your server’s IP
Building the Binary
Build your application for the target server:Uploading to Server
Using SCP
Using rsync (Recommended)
Setting Up the Service User
Running your application as the root user is a security risk—if your app is compromised, the attacker has full system access. Instead, create a dedicated service user with minimal permissions. This user can only access what your application needs, limiting potential damage. Create a dedicated user for running the application:Systemd Service
Systemd is the standard service manager on modern Linux distributions. It starts your application when the server boots, restarts it if it crashes, and provides tools for monitoring and managing the process. You define your service in a unit file that specifies what to run, which user to run as, and how to handle restarts and failures.Basic Service
Create/etc/systemd/system/myapp.service. This basic configuration gets you started quickly:
Production Service (Recommended)
Create/etc/systemd/system/myapp.service:
Environment File
Create/etc/myapp/env:
Enable and Start
Common Commands
Reverse Proxy with Caddy
A reverse proxy sits in front of your application and handles incoming requests. It provides several benefits:- HTTPS termination: Manages SSL certificates so your app doesn’t have to
- Load balancing: Distributes traffic across multiple instances of your app
- Security: Hides your app behind a hardened web server, adds security headers
- Static files: Serves static assets more efficiently than your app
Install Caddy
Configure Caddy
Edit/etc/caddy/Caddyfile:
Multiple Apps
Start Caddy
Reverse Proxy with Nginx
Nginx is the most widely-used web server and reverse proxy. It’s battle-tested, extremely performant, and has extensive documentation. Unlike Caddy, you need to configure HTTPS separately (usually with Certbot), but this gives you more control.Install Nginx
Configure Nginx
Create/etc/nginx/sites-available/myapp:
Enable Site
SSL with Certbot
Firewall Configuration
A firewall controls which network traffic can reach your server. Without a firewall, all ports are exposed to the internet—including ones you might accidentally leave open. A properly configured firewall allows only the traffic you explicitly need (typically SSH, HTTP, and HTTPS).UFW (Ubuntu)
UFW (Uncomplicated Firewall) is Ubuntu’s user-friendly interface to the Linux firewall. It’s much easier to use than raw iptables:iptables
Log Rotation
Using logrotate
Create/etc/logrotate.d/myapp:
Using journald
Logs are managed by journald automatically. Configure limits in/etc/systemd/journald.conf:
Zero-Downtime Deployments
Blue-Green Deployment
Run two instances and switch traffic:Rolling Restart Script
/usr/local/bin/deploy-myapp.sh:
Monitoring
Basic Monitoring with systemd
Process Monitoring with monit
/etc/monit/conf.d/myapp:
Complete Deployment Checklist
- Build binary for target architecture
- Upload binary to server
- Create service user
- Create systemd service file
- Create environment file with secrets
- Configure reverse proxy (Caddy/Nginx)
- Set up SSL certificates
- Configure firewall
- Set up log rotation
- Test health endpoints
- Set up monitoring/alerting