Live data from Hacker News

The simplicity of single-file Golang deployments

amazingcto.com

121–130 of 232 posts

Re: The simplicity of single-file Golang deployments

#121
post #82
post #14

When I was stuck doing a web application in Java 15 years ago, I hated everything about it except for the deployment story, which boiled down to a single .war file being pushed to the server. When we upgraded to Perl, I liked that system so we designed deployment around "PAR" files in a similar way, bundling all of the dependencies together with the application in the CI build process, and I wrote a tiny bit of infra…

Well, system-wise Go app is just a binary that only needs network access, could be run directly from systemd and just have all permissions set there. Docker is a bunch of file mounts and app running in separate namespaces. So extra daemon, extra layers of complexity. Of course if you're already deploying other docker apps it doesn't really matter, as you'd want to have that one binary in docker container anyway just…

There is also the deployment part that is easier (au least for an amateur dev such as myself).

I have a CI/CD template, Erin all my web stuff via a dockerized caddy reverse proxy, do not need to touch the configuration of the host (to create .service &co. files)

I find deploying to docker just simpler.

Re: The simplicity of single-file Golang deployments

#122
post #9

How does one handle zero downtime deployments with single-file golang binaries? I remember I tried this setup some time ago and I couldn't successfully manage cleanly to accomplish no downtime when deploying a new version of my service. The reason was mainly port reuse. I couldn't have the old and the new version of my service running on the same port... so I started to hack together something and it became dirty pre…

I guess this is a problem inherent not just in a single-file go app, but in any deployment where the whole stack is contained within a single process. The post says the process starts up quick enough that the process being temporarily unavailable isn't noticeable - but what if the process _doesn't come back_? It's also impossible to do blue/green deployments this way. It's clearly not a solution suitable to large-sca…

If you want to do deployments with single-file apps or other "whole stack in a single process" type of deployments there are other options to do it with zero-downtime.

One good option would be to spin up a second server/instance/container, run binary on new system, ensure it's good, once comfortable then swap DNS entry to the new system.

Re: The simplicity of single-file Golang deployments

#124
post #89

Earlier quoted context omitted.

Directly addressing the topic of a upvoted article is starting random language fights?

The article is about Go, and while the article mentions other languages for comparison, Rust is not one of them. So traceroute66's comment comes across as starting a Rust vs. Go fight where not appropriate.

Doesn’t come across as starting a fight to me. Not even close.

Re: The simplicity of single-file Golang deployments

#125
post #114

Earlier quoted context omitted.

Rust's philosophy (unlike Python's, for example) consists in not including tons of stuff in the standard library, this way you can choose the best implementation for your specific use case from one of the many crates (which are super easy to install, by the way). There is no "always the best" implementation for a specific functionality, nor a legacy-but-still-officially-supported-in-std implementation that nobody use…

> legacy-but-still-officially-supported-in-std implementation There is massive value in this.

Not officially supported doesn't mean not updated or not supported in general.

Re: The simplicity of single-file Golang deployments

#126
post #91
post #35

Earlier quoted context omitted.

> I don't see what's special or better about compiling everything into a single binary, apart from fetishizing the executable format. Indeed. If you think of the docker image itself as an executable format like PE or ELF, this becomes clearer. Rather than targeting the OS API, which has completely the wrong set of security abstractions because it's built around "users", it defines a new API layer. > "I can deploy by…

> Indeed. If you think of the docker image itself as an executable format like PE or ELF, this becomes clearer. But I don’t, because a docker image will not run without docker. A standalone, executable file can be distributed and deployed all by itself. A docker image cannot.

A standalone executable doesn't remain a standalone executable for very long, though.

You need something to handle its lifecycle and restart it when it dies. You need something to handle logging. You need something to jail it and prevent it from owning your system when it has a bug. You need something to pass it database credentials. You need something to put a cpu/mem limit on it. Not to mention that most executables aren't standalone but depend on system libraries.

A lot of that can be handled by systemd these days. But now you have a single standalone executable, its mandatory companion config files, and all its dependencies. Docker was designed to create a platform where the only dependency is Docker itself, and it does that job reasonably well.

Re: The simplicity of single-file Golang deployments

#127

Earlier quoted context omitted.

Rust's philosophy (unlike Python's, for example) consists in not including tons of stuff in the standard library, this way you can choose the best implementation for your specific use case from one of the many crates (which are super easy to install, by the way). There is no "always the best" implementation for a specific functionality, nor a legacy-but-still-officially-supported-in-std implementation that nobody use…

"a legacy-but-still-officially-supported-in-std implementation that nobody uses anymore but still needs to be maintained with its own namespace." The cardinality of the set of "nobody uses anymore" is usually in tens of millions.

If something is used by tens of millions, be sure that it will be updated even if legacy. Just not officially by the people who maintain the language.

Re: The simplicity of single-file Golang deployments

#128

Earlier quoted context omitted.

> I don't see what's special or better about compiling everything into a single binary, apart from fetishizing the executable format. When you distribute your software to other people, it cuts the step of installing the correct interpreter... at the cost of requiring the correct computer architecture. It is very likely a gain.

Exactly - I primarily write Java and fat-jars are great when developing apps for environments I control. But if I want to send an app to a friend it's a few additional steps to make sure they have the correct version of Java, paths are setup correct, etc. This isn't always trivial if they already have a different version of Java and want things to play nice side by side. Just bundle everything into a native executabl…

For 20 years that AOT compilers for Java exist, even if only available in commercial JDKs at enterprise prices (PTC, Aonix, Aicas, Excelsior, J/Rockit, Websphere RT).

That alternative would be jlink, and GraalVM / OpenJ9 as free beer AOT.

Re: The simplicity of single-file Golang deployments

#129

From the article: "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." Let me say the quiet part out loud: Docker is covering up the fact that we don't write deployable software any more. Go isn't perfect either. The author isn't dealing with assets (images anyone?). I think there is plenty of room…

Java never needed Docker, in fact the Docker / Kubernetes is now re-inventing Java Application Servers with WASM containers.

Re: The simplicity of single-file Golang deployments

#130

The fact that it produces a single static binary is one of the nicest things about golang. This used to be easy with C (on BSD & Linux) a long time ago, but then everything started to depend on various shared libs, who then depend on other libs, then things started to even dlopen libs behind your back so they didn't even show up in ldd, etc. Sigh.

very true, for Go though if you need CGO it's hard to make a single executable, otherwise it is great. I run a few Go apps, all are single executables, upgrading to new releases has never been easier. if you have a network oriented application, nothing beats golang as far as release|maintenance is concerned.

> CGO_ENABLED=1 CC=musl-gcc go build --ldflags '-linkmode external -extldflags=-static'

Unless you cant use musl for some reason, but that’s a glibc problem, not Go

Post reply on HN