# Gordon
Gordon Mascot

The Smart Way to Deploy Containers on Your VPS

Push code → Auto-deploy → Zero complexity

## Why Gordon? **You have a $5 VPS. You want to run multiple apps. You don't want Kubernetes.** Gordon is the missing piece that makes container deployment on budget VPS servers as simple as expensive PaaS solutions. One binary, one config file, unlimited apps. ### 🎯 Perfect For - **Solo developers** with multiple side projects on one VPS - **Small teams** who want Heroku-like simplicity without the cost - **Agencies** deploying client apps across VPS servers - **Anyone** tired of complex deployment pipelines ## 🚀 How It Works ### Build Locally, Deploy Instantly ```bash # 1. Build & test on YOUR machine docker build -t myapp . docker run -p 8080:8080 myapp # Works? Great! # 2. Push to deploy docker tag myapp registry.yourdomain.com/myapp:latest docker push registry.yourdomain.com/myapp:latest # 3. That's it. Gordon deploys it automatically. ``` **No build servers. No CI/CD complexity. If it runs on your machine, it runs in production.** ### 🔄 Instant Rollbacks Something broke? Just change your config: ```toml # Before (in gordon.toml) "app.yourdomain.com" = "myapp:latest" # After - instant rollback! "app.yourdomain.com" = "myapp:v1.2.3" ``` Save the file. Gordon redeploys the previous version. Problem solved in seconds. ## ✨ Key Features ### 🏠 Local-First Development **Your machine is the build server.** Test locally, push when ready. No waiting for remote builds. ### 🏦 Built-in Docker Registry Your VPS becomes a private Docker registry. No Docker Hub subscription needed. ### 🔄 Push-to-Deploy Magic Gordon watches for new images and deploys them instantly to configured domains. ### ⏮️ Version Control Built-In Keep multiple versions in your registry. Switch between them instantly by editing the config. ### 🌐 Multi-Domain Routing Run unlimited apps on one server. Each gets its own domain with automatic HTTPS via Cloudflare. ### 📦 Zero-Downtime Updates Push new versions anytime. Gordon handles graceful container swaps. ### 🚀 Automatic Deployment Containers deploy instantly when you push new images. No manual deployment steps needed. ## 💰 Cost Comparison | Solution | Monthly Cost | Setup Complexity | # Apps | |----------|-------------|------------------|--------| | Heroku | $7-25/app | ⭐ | Limited | | AWS ECS | $50-200+ | ⭐⭐⭐⭐⭐ | Unlimited | | Kubernetes | $100+ | ⭐⭐⭐⭐⭐ | Unlimited | | **Gordon + VPS** | **$5-20 total** | **⭐⭐** | **Unlimited** | ## 🚀 Quick Start (5 minutes) ### 1. Get a VPS & Install Docker ```bash # Any VPS provider: DigitalOcean, Linode, Vultr, Hetzner # Ubuntu/Debian recommended curl -fsSL https://get.docker.com | sh ``` ### 2. Install Gordon ```bash wget https://github.com/yourusername/gordon/releases/latest/download/gordon-linux-amd64 chmod +x gordon-linux-amd64 sudo mv gordon-linux-amd64 /usr/local/bin/gordon ``` ### 3. Create Config ```toml # gordon.toml [server] port = 8080 registry_domain = "registry.yourdomain.com" runtime = "auto" # auto-detects Docker/Podman ssl_email = "you@yourdomain.com" [registry_auth] enabled = true username = "admin" password = "your-secure-password" [routes] "app.yourdomain.com" = "myapp:latest" "api.yourdomain.com" = "api:v1" "blog.yourdomain.com" = "wordpress:latest" ``` ### 4. Point Cloudflare DNS ``` A *.yourdomain.com → YOUR_VPS_IP A yourdomain.com → YOUR_VPS_IP ``` ### 5. Start Gordon & Configure Firewall ```bash # Start Gordon sudo gordon start # Set up port forwarding (choose one option) # Option A: iptables (most common) sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080 sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8080 # Option B: UFW with NAT (Ubuntu) sudo ufw allow 22,80,443,8080/tcp echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf sudo sysctl -p # Deploy your first app docker tag myapp:latest registry.yourdomain.com/myapp:latest docker push registry.yourdomain.com/myapp:latest # Visit https://app.yourdomain.com 🎉 ``` ## 🎯 Real-World Examples ### Deploy a Node.js App ```bash # Build and test locally first docker build -t myapp . docker run -p 3000:3000 myapp # Test it! # Tag with version AND latest docker tag myapp registry.yourdomain.com/myapp:v1.0.0 docker tag myapp registry.yourdomain.com/myapp:latest # Push both tags docker push registry.yourdomain.com/myapp:v1.0.0 docker push registry.yourdomain.com/myapp:latest # Auto-deployed to app.yourdomain.com ``` ### Smart Versioning Strategy ```bash # Always push versioned tags docker tag myapp registry.yourdomain.com/myapp:v1.0.1 docker push registry.yourdomain.com/myapp:v1.0.1 # Update config to test "app.yourdomain.com" = "myapp:v1.0.1" # Happy? Update latest docker tag myapp registry.yourdomain.com/myapp:latest docker push registry.yourdomain.com/myapp:latest ``` ### Instant Rollback When Things Break ```toml # Production broke after deploying v1.0.2? # Just edit gordon.toml: # From: "app.yourdomain.com" = "myapp:v1.0.2" # To: "app.yourdomain.com" = "myapp:v1.0.1" # Save. Fixed in seconds. No scripts, no drama. ``` ### Multiple Environments ```toml [routes] "app.yourdomain.com" = "myapp:v1.0.0" # Stable production "staging.yourdomain.com" = "myapp:latest" # Latest builds "feature-xyz.yourdomain.com" = "myapp:feature-xyz" # Feature branch ``` ## 🛡️ Production-Ready ### Systemd Service ```bash sudo tee /etc/systemd/system/gordon.service > /dev/null <

Stop overcomplicating container deployment.

Star ⭐ this repo if Gordon saves you money!