This project generates docker images to build static musl binaries using the Rust language. It has several pre-build C/C++ libraries to either speedup the compile time of the Rust project or make it possible to build a project at all like Diesel with MySQL.
These container images are based upon Ubuntu 22.04 and use GCC v11.2.0 to build both the toolchains and the libraries.
Since 2024-03-15 all images are build using musl v1.2.5 using https://github.com/richfelker/musl-cross-make.
The following libraries are pre-build and marked as STATIC
already via ENV
variables so that the Rust Crates know there are static libraries available already.
- OpenSSL (
v3.0.15
) - cURL (
v8.11.0
) - ZLib (
v1.3.1
) - PostgreSQL lib (
v16.4
) and (v15.8
) and legacy (v11.22
) - SQLite (
v3.47.0
) - MariaDB Connector/C (
v3.3.11
) (MySQL Compatible) - libxml2 (
v2.13.4
)
Both stable and nightly builds are available.
The latest nightly's are always postfixed with -nightly
, if you want to use a specific date check if the images exists then you can use the -nightly-YYYY-MM-DD
tag.
Nightly's are build every morning around 9:30 UTC.
For stable you can just use the tags listed below, or add -stable
to it.
If you want to be sure that you are using a specific stable version you can use -X.Y.Z
or -stable-X.Y.Z
.
Stables builds are automatically triggered if there is a new version available.
Since 2023-09-29 I stopped building OpenSSL v1.1.1 since it's EOL.
Now only OpenSSL v3.0 is being build.
Since 2024-03-15 I stopped adding the -openssl3
postfix to the tags.
The default PostgreSQL lib used is v16.
If you want to use v16 or legacy v11 you need to overwrite an environment variable so that the postgresql crate will look at the right directory.
Adding -e PQ_LIB_DIR="/usr/local/musl/pq15/lib"
at the cli or ENV PQ_LIB_DIR="/usr/local/musl/pq15/lib"
to your custom build image will trigger the v15 version to be used during the build. The same goes for using the legacy v11
, just use ENV PQ_LIB_DIR="/usr/local/musl/pq11/lib"
.
NOTE 2024-08-02:
In some situations it could be that the libpq v11 was still used. Depending if during the compilation of the code other crates added the main library path as a search path after pq-sys
did, which caused rustc to use a different libpq.a.
This has been solved now by moving the library file for v11 to a separate directory also. The default directory is changed and should not cause any issues unless you set the PQ_LIB_DIR
variable your self to anything else then the v15 directory.
NOTE 2024-08-08:
libpq v16 is now the default version. v15 and v11 are still build and available.
As of 2023-04-23 I stopped building arm-unknown-linux-musleabihf
and armv5te-unknown-linux-musleabi
.
They do not seem to be used at all. If someone is using them, please open an issue and let me know.
Cross Target | Docker Tag |
---|---|
x86_64-unknown-linux-musl | x86_64-musl |
armv7-unknown-linux-musleabihf | armv7-musleabihf |
aarch64-unknown-linux-musl | aarch64-musl |
arm-unknown-linux-musleabi | arm-musleabi |
To make use of these images you can either use them as your main FROM
in your Dockerfile
or use something like this:
The images are pushed to multiple container registries.
Container Registry |
---|
https://hub.docker.com/r/blackdex/rust-musl |
https://quay.io/repository/blackdex/rust-musl |
https://github.com/BlackDex/rust-musl/pkgs/container/rust-musl |
FROM docker.io/blackdex/rust-musl:aarch64-musl as build
COPY . /home/rust/src
# If you want to use PostgreSQL v15 add and uncomment the following ENV
# ENV PQ_LIB_DIR="/usr/local/musl/pq15/lib"
RUN cargo build --release
FROM scratch
WORKDIR /
COPY --from=build /home/rust/src/target/aarch64-unknown-linux-musl/release/my-application-name .
CMD ["/my-application-name"]
If you want to use PostgreSQL v15
client library add -e PQ_LIB_DIR="/usr/local/musl/pq15/lib"
before the -v "$(pwd)"
argument.
# First pull the image:
docker pull docker.io/blackdex/rust-musl:aarch64-musl
# Then you could either create an alias
alias rust-musl-builder='docker run --rm -it -v "$(pwd)":/home/rust/src docker.io/blackdex/rust-musl:aarch64-musl'
rust-musl-builder cargo build --release
# Or use it directly
docker run --rm -it -v "$(pwd)":/home/rust/src docker.io/blackdex/rust-musl:aarch64-musl cargo build --release
You can also use these images as a GitHub Actions container.
A very simple way looks like this to build aarch64 binaries.
name: "Build container"
on:
push:
branches:
- main
jobs:
build_container:
runs-on: ubuntu-latest
container: ghcr.io/blackdex/rust-musl:aarch64-musl-stable
steps:
- uses: actions/checkout@v4
- name: Build
run: |
cargo build --release
Sometimes musl based binaries are slower than glibc based binaries.
This is mostly because of the Memory Allocator (malloc) which just isn't that fast.
One way to improve the performance is to use a different allocator within your Rust project.
For example, with Vaultwarden we use MiMalloc via mimalloc_rust.
Other Memory Allocators exists too, just see which one fits your application the best.
During the automatic build workflow the images are first tested on a Rust projects which test all build C/C++ Libraries using Diesel for the database libraries, and openssl, zlib and curl for the other pre-build libraries.
If the test fails, the image will not be pushed to docker hub.
Because of some strange bugs/quirks it sometimes happens that on some platforms it reports missing __atomic*
libraries. The strange thing is, these are available, but for some reason ignored by the linker or rustc (If someone knows a good solution here, please share).
Because of this some platforms may need a(n) (extra) RUSTFLAGS
which provides the correct location of the c archive .a
file.
Cross Target | RUSTFLAG |
---|---|
arm-unknown-linux-musleabi | -Clink-arg=-latomic |
I started this project to make it possible for Vaultwarden to be build statically with all database's supported. SQLite is not really an issue, since that has a bundled option. But PostgreSQL and MariaDB/MySQL do not have a bundled/vendored feature available.
I also wanted to get a better understanding of the whole musl toolchain and Github Actions, which i did.
Some projects i got my inspiration from:
- https://github.com/messense/rust-musl-cross
- https://github.com/clux/muslrust
- https://github.com/emk/rust-musl-builder
Projects used to get this working: