Stephan Schmidt

The Simplicity of Single-File Golang Deployments

Use Systemd with Go


I’ve gained some experience with deployments over the last three decades Starting without a VCS, copying files by zip to servers, sharing files by zip and manually tracking changes.

Fast forward some years and we deployed large Java applications with build scripts manually with a release train and release notes. Each release a huge event with coordinating many people in the company. Fast-forward and we were automatically deploying Scala applications from CI bundled in Docker in the startup of my wife.

Last forward and I have deployed a Golang application to a cloud server. The result of the build is one executable. The Go web application had all files like configurations (no credentials), static css and html templates embedded with embedfs (and proxied through a CDN). So no jar or ear files, no npm or pip and no Docker. Just one binary copied to the server, started and monitored with Systemd. Systemd also restarts the app daily to make sure it works properly long term. As Go starts up tremendously fast, and as Systemd is keeping the TCP connections, there is no impact to users.

The build pipleline is simple, deployments are copying a binary file to a server, with Systemd holding connections and restarting the new binary. Systemd is also used to degrade priveliges for the running binary to make it more secure.

Standing here it looks like Docker was invented to manage dependencies for Python, Javascript and Java. It looks strange from a platform that deploys as one single binary.

This one binary feels pure and simple, compared to large NPM or JAR deployments inside a Docker container. It feels manageable and not overwhelmed by complexity. Radical Simplicity

When sharing this on Mastodon, others chimed in with “yeah, like copy a single file and that’s the command to run”, “I see you are slowly joining the fanclub :)” and “yeah, so nice and simple! I still mostly package in containers for ease of deployment to the cloud, but it’s a pretty thin wrapper.” So I’m not alone with my joy and happyness.

Because the use case is small, we’re using SQLlite - especially the Go version of SQLite. It’s easier to integrate than the C version and easier to your build pipeline, it is just another dependency like every other. Using lifefs for distributing SQLite is on the roadmap.

About Stephan

As a CTO, Interim CTO, CTO Coach - and developer - Stephan has seen many technology departments in fast-growing startups. As a kid he taught himself coding in a department store around 1981 because he wanted to write video games. Stephan studied computer science with distributed systems and artificial intelligence at the University of Ulm. He also studied Philosophy. When the internet came to Germany in the 90 he worked as the first coder in several startups. He has founded a VC funded startup, worked in VC funded, fast growing startups with architecture, processes and growth challenges, worked as a manager for ImmoScout and as a CTO of an eBay Inc. company. After his wife successfully sold her startup they moved to the sea and Stephan took up CTO coaching. You can find him on LinkedIn, on Mastodon or on Twitter @KingOfCoders

Join the AMAZING CTO newsletter!
By signing up I agree to receive your newsletters and accept the terms and conditions and data protection

Other interesting articles for CTOs

Best books for CTOCTO versus CTOExperienced CTO CoachEngineering CoachingCTO JobsCTO MentorCTO MentoringCTO NewsletterCTO RoleHow many developers do you need?Outsourcing Guide Technology and RoadmapsHow to become a CTO in a company - a career pathWork from home and remote with ScrumWaterfall and Scrum
Other Articles

Hosting a Website on BunnyCDN - Radical Simplicity

Three Fundamentals of Software Estimation

Tests Are Bad For Developers

Musings about error handling mechanisms in programming languages

Automatic Management to Save Time