Golang’s cross compilation and static linking is amazing . But running a binary on older servers often gives this dreadful error:
version `GLIBC_2.34’ not found
There are plenty of solutions to solve this problem and I just want to help people avoid hours of pain. The best solution is the last one. tl;dr; use musl
Disable CGO
Some developers advocate for using CGO_ENABLED=0
. While that solution sometimes works, in my case it didn’t
Upgrade the OS
Yeah, upgrading the OS is a potential solution. But I don’t want to fiddle around right now, it’s been working fine since it last restarted 716 days ago (would have been 1500+ days but the hosting provider rebooted the system to fix some CPU vulnerabilities). Why would I bother it?
Use a VM or Docker instance
Another option is to use container, or a virtual machine. Vagrant, docker, etc. But this kind of beats the purpose for why I chose go use golang and cross compilation…
Simple CICD pipeline
PLus, I don’t want to complicate my simple build & deploy pipeline which consists of just 3 linux commands.
go build ./location
scp app remotehost:/usr/bin/
ssh remotehost "sudo systemctl reload myapp"
Install GO and compile it on the server
I did this for [soju] a while back. But this might not work when you have sensitive code and/or simply don’t want to complicate
Use musl instead of glibc
The best solution at the moment is to use musl
instead of gcc/glibc.
But you could probably also use zig cc
To get it on Debian based Linux distro’s
sudo apt install musl
sudo apt install musl-dev
To build YOUR Go binary with it
CC=/usr/bin/x86_64-linux-musl-gcc go build --ldflags '-linkmode external -extldflags "-static"' ./cmd/my-code/
Now copy the binary over to the server and you’re done.
Where did this problem arise from? GoBlog’s mattn sqlite dependency…
Inspired by: https://tangiblebytes.co.uk/2023/golang-glibc-not-found/