Live data from Hacker News

The simplicity of single-file Golang deployments

amazingcto.com

41–50 of 232 posts

Re: The simplicity of single-file Golang deployments

#41
post #18

Earlier quoted context omitted.

You still need jre so it's not really a "single file" like on Go

Eh. From an ops perspective there isn't much difference between an executable file that Golang statically compiled all dependencies into and embedded a file system into, and a WAR archive that the Java compiler embedded a file system including dependencies into. Both are self-contained single files you can give to a completely different organization and expect to run on the first attempt with no complications. It's j…

Try Guava or Spring. In either case the framework supplies you with a

   Factory, FactoryFactory, FactoryFactoryFactory, ...
that does the transitive closure so you can just get a "single" object injected into your app where you need it.

Re: The simplicity of single-file Golang deployments

#42

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…

> From what I understand Java does have facilities to bundle

jlink, jpackage, and if you need something complex you can use conveyor: https://hydraulic.software/index.html

Re: The simplicity of single-file Golang deployments

#43

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…

Anymore? When were we writing "deployable" software in the past?

A better question is what is deployable software? How does it contrast from non-deployable so we can understand what we're even talking about. Software gets "deployed" all the time so in what way is it currently non-deployable versus some rose tinted view of yesteryear's software?

Re: The simplicity of single-file Golang deployments

#44
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…

Socket activation via systemd[0] is an option, assuming you are fine with certain requests taking a longer time to complete (if they arrive while the service is being restarted). Otherwise using a proxy in front of your app is your best bet (which has other benefits too, as you can offload TLS and request logging/instrumentation).

- https://github.com/bojanz/httpx#systemd-setup

Re: The simplicity of single-file Golang deployments

#45

Earlier quoted context omitted.

Some of this is solved by using e.g. systemd, depending on your needs. > I couldn't have the old and the new version of my service running on the same port... You can, actually! You just can’t open the port twice by default. So one or both of the processes needs to inherit the port from a parent process, get passed the port over a socket (Unix sockets can transmit file descriptors), or use SO_REUSEADDR. There are som…

So can I just start another process with SO_REUSEADDR and gracefully shutdown the old process? The master/worker thing that nginx / gunicorn et al do is pretty neat, but relies on signals; so seems pretty messy and error prone to write yourself.

You may have to start both processes with SO_REUSEADDR, I don’t remember the exact semantics.

People have a healthy skepticism of signals from the C days, but if we’re talking about Go, you’d just call signal.Notify. Any way of signaling your app to shut down works, though.

https://pkg.go.dev/os/signal@go1.20.2#Notify

Re: The simplicity of single-file Golang deployments

#46
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…

This is where the simplicity of single-file golang deployments falls short.

Just make sure you’re not slowly recreating bad, homebrew versions of all of the nice things that Kubernetes does in an attempt to turn a simple deployment into a production ready deployment.

Re: The simplicity of single-file Golang deployments

#47
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…

Have you ever read https://medium.com/@gtrevorjay/you-could-have-invented-conta... ?

You were halfway there :-)

Re: The simplicity of single-file Golang deployments

#48

Earlier quoted context omitted.

You can definitely pack a Java application into a single JAR file and skip the Docker. Java's xenophobia (allergy to linking libraries) is the real root of "write once run everywhere" so often all you need is the Java runtime.

You still need jre so it's not really a "single file" like on Go

You can use JLink to embed only the needed modules and classes of the JRE for your application to run

Re: The simplicity of single-file Golang deployments

#49
post #8

I feel docker in many cases is a hack for languages and runtimes that don’t support single file static linked binaries. Often a single binary is a simpler and better option instead of a docker container.

Often ? It's 100% scenario. Complex apps (like Gitea for example) delivered as a single binary is basically the pinnacle of deployment.

gitea, caddy (which can update itself even with the same modules included), restic (again in-place updates), adguard home which embeds a dhcp and dns service etc etc. I really like the stuff the golang developers can put out.

I even asked someone to produce a fresbsd binary please and they added one line to their github ci to make it available that day.

Re: The simplicity of single-file Golang deployments

#50
post #40

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…

> Go isn't perfect either. The author isn't dealing with assets (images anyone?). From the article: "The Go web application had all files like configurations (no credentials), static css and html templates embedded with embedfs (and proxied through a CDN)." See https://pkg.go.dev/embed

OP here,

How are you doing caching without a mod time?

https://github.com/golang/go/issues/44854

Are you re-naming or hashing for cache clearing?

Post reply on HN