feat: Static musl builds via nix

fix: don't do check on all builds

Checks can be done with `nix flake check`, no need to slow down build process with this.

feat: add static binary build instructions to docs

feat: add max-perf package

feat: add build-nix workflow

chore: add changelog

fix: fix max-perf-static packages not statically linking

feat: improve docs for building with nix

chore: more descriptive name for binary build step of workflow

fix: resolve review comment about Haswell CPUs

chore: enable __structuredAttrs on build

This is a good practice for modern nix packages
This commit is contained in:
Henry-Hiles
2026-06-20 16:54:35 +01:00
committed by timedout
parent c76a235726
commit fddca8d534
6 changed files with 166 additions and 39 deletions
+71
View File
@@ -0,0 +1,71 @@
name: Build / Static via Nix
concurrency:
group: "build-nix-${{ forge.ref }}"
cancel-in-progress: true
on:
push:
tags:
- "v*.*.*"
workflow_dispatch:
schedule:
- cron: '30 0 * * *'
jobs:
build:
name: "Build ${{ matrix.filename }} Binary"
runs-on: ubuntu-latest
strategy:
matrix:
include:
- package: default-static-x86_64
filename: conduwuit-linux-static-amd64
- package: default-static-aarch64
filename: conduwuit-linux-static-arm64
- package: max-perf-static-aarch64
filename: conduwuit-linux-static-arm64-maxperf
- package: max-perf-haswell-static-x86_64
filename: conduwuit-haswell-linux-static-amd64-maxperf
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
- name: Install Lix
uses: https://github.com/samueldr/lix-gha-installer-action@a0fee77b2a98bb7c5c0ed7ae6d6ad4903dbdad0d
with:
extra_nix_config: experimental-features = nix-command flakes flake-self-attrs
- name: Build static binary
run: |
nix build .#${{ matrix.package }}
install -D result/bin/conduwuit /tmp/binaries/${{ matrix.filename }}
- name: Upload binary artifact
uses: forgejo/upload-artifact@v4
with:
name: ${{ matrix.filename }}
path: /tmp/binaries/${{ matrix.filename }}
release-binaries:
name: "Release Binaries"
runs-on: ubuntu-latest
needs:
- build
permissions:
contents: write
if: startsWith(github.ref, 'refs/tags/')
steps:
- name: Download binary artifacts
uses: forgejo/download-artifact@v4
with:
pattern: conduwuit*
path: binaries
merge-multiple: true
- name: Create Release and Upload
uses: https://github.com/softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3
with:
draft: true
files: binaries/*
+1
View File
@@ -0,0 +1 @@
Added static builds using Nix, allowing for Continuwuity on musl. During this, we also introduced a `max-perf-haswell` package, separating it from `max-perf`, so you may want to swap to this if you are on NixOS. Contributed by @Henry-Hiles (QuadRadical).
+8 -2
View File
@@ -47,9 +47,15 @@ #### Performance-optimised builds
### Nix
Theres a Nix package defined in our flake, available for Linux and MacOS. Add continuwuity as an input to your flake, and use `inputs.continuwuity.packages.${system}.default` to get a working Continuwuity package.
If you wish to generate a static binary, you can do so using Nix: `nix build git+https://forgejo.ellis.link/continuwuation/continuwuity#packageName`, where `packageName` is one of:
If you simply wish to generate a binary using Nix, you can run `nix build git+https://forgejo.ellis.link/continuwuation/continuwuity` to generate a binary in `result/bin/conduwuit`.
- `default-static-x86_64`
- `default-static-aarch64`
- `max-perf-static-x86_64`
- `max-perf-haswell-static-x86_64`
- `max-perf-static-aarch64`
`max-perf` takes longer to build, but has more runtime optimizations. Haswell builds are optimized for modern CPUs.
### Compiling
+8 -1
View File
@@ -47,9 +47,16 @@ ### Available options
- `extraEnvironment`: Extra environment variables to pass to the Continuwuity server
- `package`: The Continuwuity package to use, defaults to `pkgs.matrix-continuwuity`
- You may want to override this to be from our flake, for faster updates and unstable versions:
```nix
package = inputs.continuwuity.packages.${pkgs.stdenv.hostPlatform.system}.default;
package = inputs.continuwuity.packages.${pkgs.stdenv.hostPlatform.system}.packageName;
```
Where `packageName` is one of:
- `default`
- `max-perf`: Takes longer to build, but has more runtime optimizations
- `max-perf-haswell`: Optimized for modern CPUs, don't use if your CPU is not Haswell or later.
- `admin.enable`: Whether to add the `conduwuit` binary to `PATH` for administration (enabled by default)
- `settings`: The Continuwuity configuration
+10 -17
View File
@@ -5,11 +5,10 @@
liburing,
craneLib,
pkg-config,
callPackage,
rustPlatform,
cargoExtraArgs ? "",
rustflags ? "",
rocksdb ? callPackage ./rocksdb.nix { },
target_cpu ? null,
profile ? "release",
}:
let
@@ -28,18 +27,24 @@ let
};
attrs = {
__structuredAttrs = true;
strictDeps = true;
inherit src;
nativeBuildInputs = [
pkg-config
rustPlatform.bindgenHook
];
buildInputs = lib.optionals stdenv.hostPlatform.isLinux [ liburing ];
doCheck = false;
env = {
ROCKSDB_INCLUDE_DIR = "${rocksdb}/include";
ROCKSDB_LIB_DIR = "${rocksdb}/lib";
CARGO_PROFILE = profile;
RUSTFLAGS = rustflags;
};
}
// (lib.optionalAttrs (target_cpu != null) {
TARGET_CPU = target_cpu;
});
};
in
craneLib.buildPackage (
@@ -47,18 +52,6 @@ craneLib.buildPackage (
inherit cargoExtraArgs;
cargoArtifacts = craneLib.buildDepsOnly attrs;
# Needed to make continuwuity link to rocksdb
postFixup = lib.optionalString stdenv.hostPlatform.isLinux ''
old_rpath="$(patchelf --print-rpath $out/bin/conduwuit)"
extra_rpath="${
lib.makeLibraryPath [
rocksdb
]
}"
patchelf --set-rpath "$old_rpath:$extra_rpath" $out/bin/conduwuit
'';
meta = {
description = "A community-driven Matrix homeserver in Rust";
mainProgram = "conduwuit";
+68 -19
View File
@@ -1,4 +1,5 @@
{
inputs,
self,
...
}:
@@ -6,29 +7,77 @@
perSystem =
{
self',
lib,
pkgs,
system,
craneLib,
...
}:
{
packages = {
rocksdb = pkgs.callPackage ./rocksdb.nix { };
default = pkgs.callPackage ./continuwuity.nix {
inherit self craneLib;
# extra features via `cargoExtraArgs`
cargoExtraArgs = "-F http3";
# extra RUSTFLAGS via `rustflags`
# the stuff below is required for http3
rustflags = "--cfg reqwest_unstable";
};
# users may also override this with other cargo profiles to build for other feature sets
#
# other examples include:
#
# - release-high-perf
max-perf = self'.packages.default.override {
profile = "release-max-perf";
};
};
packages =
let
mkPackages =
pkgs:
let
fnx = inputs.fenix.packages.${system};
isStatic = pkgs.stdenv.hostPlatform.isMusl;
craneLib = (inputs.crane.mkLib pkgs).overrideToolchain (
_:
if isStatic then
fnx.combine [
self'.packages.stable-toolchain
(fnx.targets.${pkgs.stdenv.hostPlatform.config}.stable).rust-std
]
else
self'.packages.stable-toolchain
);
default = pkgs.callPackage ./continuwuity.nix {
inherit self craneLib;
liburing = (if isStatic then pkgs.pkgsStatic else pkgs).liburing;
# extra features via `cargoExtraArgs`
cargoExtraArgs = "-F http3";
# extra RUSTFLAGS via `rustflags`
# the stuff below is required for http3
rustflags = "--cfg reqwest_unstable";
};
# users may also override this with other cargo profiles to build for other feature sets
# for features configuration see `default` package which enables http3 by default
max-perf = default.override {
# compiles slower but with more thorough optimizations
profile = "release-max-perf";
};
max-perf-haswell = max-perf.override {
# compiles explicitly for haswell arch cpus
target_cpu = "haswell";
};
in
{
inherit default max-perf max-perf-haswell;
};
in
(mkPackages pkgs)
// (lib.mapAttrs' (name: value: lib.nameValuePair "${name}-static-x86_64" value) (
mkPackages (
import inputs.nixpkgs {
localSystem = system;
crossSystem = "x86_64-unknown-linux-musl";
}
)
))
// (lib.mapAttrs' (name: value: lib.nameValuePair "${name}-static-aarch64" value) (
mkPackages (
import inputs.nixpkgs {
localSystem = system;
crossSystem = "aarch64-unknown-linux-musl";
}
)
));
};
}