The Problem
Hosting side projects on a VPS means manually wiring Docker, Traefik, SSL certificates, secrets management, and SSH hardening. That setup is repetitive, error-prone, and a day of work each time. Sidekick automates the entire path from a bare Ubuntu VPS to a deployed application with zero-downtime deploys and automatic SSL.
What This Does
Sidekick is a Go CLI that provisions a VPS and deploys Dockerized applications to it. The cmd/initialize/initialize.go file runs a six-stage setup: local requirements check, SSH login, user creation, VPS security hardening, Docker installation, and Traefik configuration. The cmd/deploy/deploy.go file handles the deploy pipeline: login, environment file encryption with SOPS, Docker image build, transfer, and zero-downtime rollout.
The CLI also supports preview environments (cmd/preview/) and teardown (cmd/destroy.go). The render/ package provides a TUI for progress display, and the utils/ package holds SSH, Docker, and command execution helpers.
How It Is Wired
Execution starts at main.go:19 and calls cmd/root.go's Execute, which dispatches to subcommands. The setup flow runs through cmd/initialize/initialize.go, where stage1LocalReqs checks for brew and sops locally, stage2Login authenticates via SSH, and stage4VPSSetup runs remote commands. The deploy flow in cmd/deploy/deploy.go follows prelude → stage1Login → stage2EnvFile → stage3BuildDockerImage → stage6Deploy, with each stage calling RunCommand to execute remote shell commands.
utils/utils.go is the hub: RunCommand is called from 10 places and RunCommandsWithTUIHook from 3. It routes all remote execution through SSH (utils/auth.go) and streams output to the TUI (render/tui.go). utils/config.go owns the sidekick config file, with LoadAppConfig called from 5 places. The two Python scripts (scripts/make-droplet.py, scripts/destroy-droplets.py) are standalone DigitalOcean utilities, not part of the main flow.
How To Use It
git clone https://github.com/moses-y/sidekick
cd sidekick
go build -o sidekick .
./sidekick init # provision a VPS
./sidekick deploy # deploy an app from a Dockerfile
Setup requires: a Ubuntu LTS VPS with a public IP, an SSH key in ~/.ssh/, and brew installed locally (used to install sops). The init command prompts for the VPS IP and an email for SSL certs.
Real-World Use
A developer with a DigitalOcean droplet runs sidekick init once, which hardens SSH, creates a sidekick user, installs Docker and Traefik, and configures SSL certs. For each app, they run sidekick deploy from a repo with a Dockerfile. The tool encrypts the .env with SOPS, builds the image locally, transfers it, and rolls it out behind Traefik with automatic SSL and zero downtime. A typical $8/month VPS handles the traffic.
Code Health & Issues
Static analysis found 4 issues (1 high, 3 medium):
- High - Duplicated code blocks - 40 repeated 6-line blocks across 21 files, including
cmd/config/config.go,cmd/deploy/deploy.go,cmd/destroy.go. Extract shared helpers. - Medium - Deep nesting -
cmd/preview/preview.goandrender/tui.goreach indentation depth 6. Use early returns or guard clauses. - Medium - High branching density -
scripts/make-droplet.pyhas 15 branch points over 50 lines. Decompose the logic. - Medium - No CI/CD - 24 source files with no build/test workflow. Add one that runs
go buildandgo teston push. - Medium - No dependency updates - One manifest (
go.mod), no Dependabot or Renovate configured. - Medium - Missing timeouts -
scripts/make-droplet.pymakes 3 outbound calls withouttimeout=, which can hang workers.
Tests exist (utils/utils_test.go) but are minimal.
The Bottom Line
Sidekick is a practical, opinionated tool that genuinely reduces VPS deployment friction. The staged pipeline design is clear, though the duplicated logic and deep nesting suggest it grew organically. Worth using if you deploy side projects to a single VPS and want Fly.io-like convenience without the vendor lock-in.