UPDATE: minor edits to mention that we do have a dedicated build server after this got posted to reddit.
This might end up getting a lot of hate. In other jobs, we’ve used docker and it’s
worked out just fine (for the most part… there was that time the RedHat filesystem
on our prod server got mysteriously hosed — maybe it wasn’t docker’s fault.) But no, the reason we don’t use docker is
because we don’t need it. Literally.
Writing golang web services and static html embedded with with golang
1.16’s new //embed directive, we end up with a single deployable binary.
As a self-sustaining startup, we have limited resources to
devote to tasks. We chose golang exactly
for this reason. It sure would be *nice*
if we could spend a couple weeks building the perfect CI/CD pipeline, an elegant
deployment process, along with pretty dashboards. But we have software we need to ship in order
to get users in order to drive subscriptions.
Anything that doesn’t directly serve that goal is a complication. So at best, docker is a complication. A 9 million LoC complication that brings its
own bugs and its own idiosyncrasie
Golang allows us to build web services that are insanely
fast (at least for the level of growth we are currently at) and insanely scalable
(again, for the level of growth we are currently at). We can handle thousands of transactions per
second on a single server. We don’t have
anywhere close to a thousand transactions per second. But, sure, we could have probably done the same
with node or deno. The V8 engine is also
insanely fast. When high traffic for
your app is probably 2 transactions per second (we have a workout video app – we
don’t have the same scalability problems as Twitter), it really doesn’t matter
what programming language you choose. If
you run out of capacity, upgrade your single server.
No, the reason we went with go was because golang’s
packaging is *so* much better than node.
Or java. Or C#. We get a single binary.
Building is as easy as:
Testing is as easy as
Deploying the app is as easy as:
scp app user@host:
ssh user@host “nohup ./app”
Note, we did get a *little* more complicated and create a SystemD
script to launch it at startup. We also made sure we had a dedicated build server, which essentially runs a 10 line shell script that does all the build goodness needed (git clone, go build, go test, go lint, go vet) But
there were those of us arguing that even that was too complicated. At some point we may even add a UI like https://www.rundeck.com/ to control deploys.
Total time to create our build and deploy system was so small we don’t even
know how to measure it.
Now, think about how much time you’ve spent learning docker. Deploying docker.
Troubleshooting docker. Even if you love
it, it changed your life, it’s better than sliced bread and it solves world
hunger… in the end can you really say it’s simpler than what we’ve got for free
built in to golang? I guarantee you it’s
Please comment below if you like these thoughts. And while you’re at it, you could give our app a try as well: https://meezeeworkouts.com/getapp