Building and Packaging Headscale from Source
Overview
This article explains how to build and package the Headscale source code yourself, and covers common errors that may occur during the build process along with their solutions.
- OS: Windows 11 Home (Chinese edition); WSL 2 with Ubuntu 24.04 LTS. The build was performed on Ubuntu 24 installed via WSL 2.
- Source directory:
C:\Users\XXX\Documents\develop\0me\headscale. Source code stored on the Windows filesystem. - Source download: https://github.com/juanfont/headscale
- Version: v0.26.1
Prerequisites
Downloading the Code
It is recommended to clone the repository using git rather than downloading a zip archive. When I tried to build from a zip archive, many errors appeared. I was ultimately able to produce an executable via go build -o headscale ./cmd/headscale, but make build could not complete successfully.
Use the following commands to download the source:
1 | git clone https://github.com/juanfont/headscale.git |
Then copy config-example.yaml from the root directory and rename it to config.yaml.
WSL
Enable WSL and install the Ubuntu distribution.
In your Windows user directory (e.g. C:\Users\XXX), create a .wslconfig file with the following content:
1 | [wsl2] |
Then restart WSL. This allows the Ubuntu environment to share your host machine’s VPN connection — which is required during the build, as many dependencies need to be downloaded from the internet.
Installing Nix
Install the Multi-user edition of nix using the root account.
1 | sh <(curl --proto '=https' --tlsv1.2 -L https://nixos.org/nix/install) --daemon |
Reference: https://nixos.org/download/
Building
Switch from the root account to a regular user account before building.
1 | # Enter the directory. Windows paths are accessible under /mnt/c/ in WSL |
Setting up the environment takes a while — please be patient.
Once make build completes successfully, a result directory will appear in the project folder. When viewed from Windows it appears as a 0 KB file, but it is actually a directory in the Linux filesystem.


Running
The compiled headscale binary can be run directly on the development machine. The following describes how to copy it to another server and run it there.
- Target server: Ubuntu 22.04 Server
1 | # Inspect the binary using ldd or file |
From the console output above, we can see that headscale requires /nix/store/vbrdc5wgzn0w1zdp10xd2favkjn5fk7y-glibc-2.40-66/lib/ld-linux-x86-64.so.2 at runtime. This path is symlinked to /lib64/ld-linux-x86-64.so.2. For the program to run correctly, you need to manually create the /nix/store/vbrdc5wgzn0w1zdp10xd2favkjn5fk7y-glibc-2.40-66/lib/ directory and copy ld-linux-x86-64.so.2 into it.
In addition, a config.yaml file is required, along with the directories /root/.headscale/ and /var/lib/headscale/, which must be created and granted appropriate permissions.
1 | # Start command: headscale serve |
Packaging as a Docker Image
If you want to package the source into a Docker image, refer to the following link:
Build Error Reference
All of the following errors occurred when building from a downloaded zip archive. None of these issues appear when building from a git clone.
Issue 1
1 | # Following the official build steps with nix. make test succeeds, but make build fails with the error below: |
- Solution:
Edit the flake.nix file.
Change headscaleVersion = self.shortRev or self.dirtyShortRev; to:
1 | headscaleVersion = if self ? shortRev |
Issue 2
1 | djc@jetron-djc:/mnt/c/Users/DJC/Documents/develop/0me/headscale-0.26.1$ make build |
This error occurs because the build is interrupted by a test failure. The test fails because it cannot find the configuration file.
Build the binary directly instead:
1 | cp config-example.yaml config.yaml |
After a successful build, a headscale binary approximately 80+ MB in size will appear in the project directory.
Issue 3
1 | root@jetron-djc:~# nix develop |
This error occurs because the nix-command feature in Nix is experimental and disabled by default.
1 | # Edit the Nix configuration file |
Run the above command as root.
Issue 4
1 | root@jetron-djc:~# nix develop |
This error occurs because nix develop must be run from a directory that contains a flake.nix file. cd into your project directory and run nix develop from there.
Issue 5
1 | === Failed |
This error occurs because PostgreSQL’s initdb command cannot be run as root for security reasons. The test code attempts to initialize a database as root, which is rejected. Run make build as a regular (non-root) user.
Installing Dependencies Manually
1 | # Install Buf |


































