{"id":13578274,"url":"https://github.com/clux/muslrust","last_synced_at":"2025-05-14T21:10:19.048Z","repository":{"id":38808119,"uuid":"53975706","full_name":"clux/muslrust","owner":"clux","description":"Docker environment for building musl based static linux rust binaries","archived":false,"fork":false,"pushed_at":"2025-02-26T00:17:19.000Z","size":246,"stargazers_count":999,"open_issues_count":18,"forks_count":90,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-04-06T14:07:20.341Z","etag":null,"topics":["build","docker","linux","musl","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/clux.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["clux"]}},"created_at":"2016-03-15T20:19:47.000Z","updated_at":"2025-03-19T07:01:04.000Z","dependencies_parsed_at":"2024-02-13T20:26:45.298Z","dependency_job_id":"4e3a49e8-e58e-4b36-9bd7-c3a4971a55bc","html_url":"https://github.com/clux/muslrust","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clux%2Fmuslrust","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clux%2Fmuslrust/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clux%2Fmuslrust/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clux%2Fmuslrust/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clux","download_url":"https://codeload.github.com/clux/muslrust/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248753270,"owners_count":21156243,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["build","docker","linux","musl","rust"],"created_at":"2024-08-01T15:01:29.009Z","updated_at":"2025-04-13T17:36:45.191Z","avatar_url":"https://github.com/clux.png","language":"Rust","readme":"# muslrust\n\n[![nightly](https://github.com/clux/muslrust/actions/workflows/nightly.yml/badge.svg)](https://github.com/clux/muslrust/actions/workflows/nightly.yml)\n[![stable](https://github.com/clux/muslrust/actions/workflows/stable.yml/badge.svg)](https://github.com/clux/muslrust/actions/workflows/stable.yml)\n[![docker pulls](https://img.shields.io/docker/pulls/clux/muslrust.svg)](https://hub.docker.com/r/clux/muslrust/tags)\n\nA docker environment for building **static** rust binaries for `x86_64` and `arm64` **linux** environments using **[musl](https://musl.libc.org/)**. Built daily via [github actions](https://github.com/clux/muslrust/actions).\n\nBinaries compiled with `muslrust` are **light-weight**, call straight into the kernel without other dynamic system library dependencies, can be shipped to most linux distributions without compatibility issues, and can be inserted as-is into lightweight docker images such as [static distroless](https://github.com/GoogleContainerTools/distroless/blob/main/base/README.md), [scratch](https://hub.docker.com/_/scratch), or [alpine](https://hub.docker.com/_/alpine).\n\nThe goal is to **simplify** the creation of small and **efficient cloud containers**, or **stand-alone linux binary releases**.\n\nThis image includes popular [C libraries](#c-libraries) compiled with `musl-gcc`, enabling static builds even when these libraries are used.\n\n## Usage\n\nPull and run from a rust project root:\n\n```sh\ndocker pull clux/muslrust:stable\ndocker run -v $PWD:/volume --rm -t clux/muslrust:stable cargo build --release\n```\n\nYou should have a static executable in the target folder:\n\n```sh\nldd target/x86_64-unknown-linux-musl/release/EXECUTABLE\n        not a dynamic executable\n```\n\n## Examples\n\n- [Kubernetes controller with actix-web using plain distroless/static](https://github.com/kube-rs/controller-rs/blob/main/Dockerfile)\n- [Kubernetes reflector with axum using builder pattern](https://github.com/kube-rs/version-rs/blob/main/Dockerfile)\n- [Kubernetes controller using cargo-chef for caching layers](https://github.com/qualified/ephemeron/blob/main/k8s/controller/Dockerfile)\n- [Github release assets uploaded via github actions](https://github.com/kube-rs/kopium/blob/f554ad9780dec3c76b4cef8a16a02bc82dded2be/.github/workflows/release.yml)\n- [Using muslrust with sccache \u0026 github actions](./SCCACHE.md)\n\nThe binaries and images for small apps generally end up `\u003c10MB` compressed or `~20MB` uncompressed without stripping.\n\nThe **recommended** production image is [distroless static](https://github.com/GoogleContainerTools/distroless/tree/main/base) or [chainguard static](https://github.com/chainguard-images/images/tree/main/images/static) as these contain a non-root users + SSL certs (unlike `scratch`), and disallows shell access (use `kubectl debug` if you want this). See also [kube.rs security doc on base image recommendations](https://kube.rs/controllers/security/#base-images).\n\n## Available Tags\n\nThe standard tags are **`:stable`** or a dated **`:nightly-{YYYY-mm-dd}`**.\n\nFor pinned, or historical builds, see the [available tags on dockerhub](https://hub.docker.com/r/clux/muslrust/tags/).\n\n## C Libraries\n\nThe following system libraries are compiled against `musl-gcc`:\n\n- [x] openssl ([openssl crate](https://github.com/sfackler/rust-openssl))\n- [x] pq ([pq-sys crate](https://github.com/sgrif/pq-sys) used by [diesel](https://github.com/diesel-rs/diesel))\n- [x] sqlite3 ([libsqlite3-sys crate](https://github.com/jgallagher/rusqlite/tree/master/libsqlite3-sys) used by [diesel](https://github.com/diesel-rs/diesel))\n- [x] zlib (used by pq and openssl)\n\nWe **[try](https://github.com/clux/muslrust/blob/main/update_libs.py)** to keep these up to date.\n\nNB: C library for `curl` has been removed in newer tags from 2025. See [#96](https://github.com/clux/muslrust/issues/96).\n\n## Developing\n\nClone, tweak, build, and run tests:\n\n```sh\ngit clone git@github.com:clux/muslrust.git \u0026\u0026 cd muslrust\njust build\njust test\n```\n\n## Tests\n\nBefore we push a new version of muslrust we [test](https://github.com/clux/muslrust/blob/main/test.sh#L4-L17) to ensure that we can use and statically link:\n\n- [x] [serde](https://crates.io/crates/serde)\n- [x] [diesel](https://crates.io/crates/diesel)\n- [x] [hyper](https://crates.io/crates/hyper)\n- [x] [rustls](https://crates.io/crates/rustls)\n- [x] [openssl](https://crates.io/crates/openssl)\n- [x] [flate2](https://crates.io/crates/flate2)\n- [x] [rand](https://crates.io/crates/rand)\n\n## Caching\n\n### Local Volume Caches\n\nRepeat builds locally are always from scratch (thus slow) without a cached cargo directory. You can set up a docker volume by just adding `-v cargo-cache:/root/.cargo/registry` to the docker run command.\n\nYou'll have an extra volume that you can inspect with `docker volume inspect cargo-cache`.\n\nSuggested developer usage is to add the following function to your `~/.bashrc`:\n\n```sh\nmusl-build() {\n  docker run \\\n    -v cargo-cache:/root/.cargo/registry \\\n    -v \"$PWD:/volume\" \\\n    --rm -it clux/muslrust cargo build --release\n}\n```\n\nThen use in your project:\n\n```sh\n$ cd myproject\n$ musl-build\n    Finished release [optimized] target(s) in 0.0 secs\n```\n\n## Caching on CI\n\nOn CI, you need to find a way to either store the `cargo-cache` referenced above, or rely on docker layer caches with layers (see [`cargo-chef`](https://github.com/LukeMathWalker/cargo-chef)).\n\n#### Github Actions\nGithub actions supports both methods:\n\n- [GHA: direct folder cache (manual docker build)](https://github.com/kube-rs/controller-rs/blob/607d824d3a34959c5eded9c54f6f5c1bd14dc78e/.github/workflows/ci.yml#L67-L85)\n- [GHA: via docker layer caches (builder-pattern)](https://github.com/qualified/ephemeron/blob/fc52e2b0373c4ebfba552e8a0d402dee0bc08f9c/.github/workflows/images.yaml#L30-L48) (with `cargo-chef`)\n\n#### CircleCI\nCircleCI supports both methods:\n\n- [Circle: direct folder cache (manual docker build)](https://github.com/clux/webapp-rs/blob/master/.circleci/config.yml)\n- Circle also supports [docker layer caching](https://circleci.com/docs/2.0/docker-layer-caching/) (no example atm)\n\n## Allocator Performance\n\nTo optimise memory performance (see [#142](https://github.com/clux/muslrust/issues/142)) consider changing the global allocators in sensitive applications:\n\n- [jemalloc](https://github.com/tikv/jemallocator)\n- [mimalloc](https://github.com/microsoft/mimalloc)\n\n```rust\nuse tikv_jemallocator::Jemalloc;\n#[global_allocator]\nstatic GLOBAL: Jemalloc = Jemalloc;\n```\n\n## Troubleshooting\n\n### SSL Verification\n\nYou might need to point `openssl` at the location of your certificates **explicitly** to avoid certificate errors on https requests.\n\n```sh\nexport SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt\nexport SSL_CERT_DIR=/etc/ssl/certs\n```\n\nThese can be [hardcoded in your Dockerfile](https://docs.docker.com/engine/reference/builder/#env), or you can rely on the [openssl-probe crate](https://crates.io/crates/openssl-probe) to detect the cert location. You should not have to do this if you are using the static variants of `distroless` or `chainguard`.\n\n### Diesel and PQ builds\n\nWorks with the older version of libpq we bundle (see [#81](https://github.com/clux/muslrust/issues/81)). See the [test/dieselpgcrate](./test/dieselpgcrate) for specifics.\n\nFor stuff like `infer_schema!` to work you need to explicitly pass on `-e DATABASE_URL=$DATABASE_URL` to the `docker run`. It's probably easier to just make `diesel print-schema \u003e src/schema.rs` part of your migration setup though.\n\nNote that diesel compiles with `openssl` statically since `1.34.0`, so you need to include the `openssl` crate **before** `diesel` due to [pq-sys#25](https://github.com/sgrif/pq-sys/issues/25):\n\n```rs\nextern crate openssl;\n#[macro_use] extern crate diesel;\n```\n\nThis is true even if you connect without `sslmode=require`.\n\n### Filesystem permissions on local builds\n\nWhen building locally, the permissions of the musl parts of the `./target` artifacts dir will be owned by `root` and requires `sudo rm -rf target/` to clear. This is an [intended](https://github.com/clux/muslrust/issues/65) complexity tradeoff with user builds.\n\n### Debugging in blank containers\n\nIf you are running a plain alpine/scratch container with your musl binary in there, then you might need to compile with debug symbols, and set the `RUST_BACKTRACE=full` evar to see crashes.\n\nIn alpine, if this doesn't work (or fails to give you line numbers), try installing the `rust` package (via `apk`). This should not be necessary anymore though!\n\nFor easily grabbing backtraces from rust docker apps; try adding [sentry](https://crates.io/crates/sentry). It seems to be able to grab backtraces regardless of compile options/evars.\n\n### SELinux\n\nOn SELinux enabled systems like Fedora, you will need to [configure selinux labels](https://docs.docker.com/storage/bind-mounts/#mounting-into-a-non-empty-directory-on-the-container). E.g. adding the `:Z` or `:z` flags where appropriate: `-v $PWD:/volume:Z`.\n\n## Extending\n\n### Extra C libraries\n\nIf you need extra C libraries, you can inherit from this image `FROM clux/muslrust:stable as builder` and add extra `curl` -\u003e `make` instructions. We are unlikely to include other C libraries herein unless they are very popular.\n\n### Extra Rustup components\n\nYou can install extra components distributed via Rustup like normal:\n\n```sh\nrustup component add clippy\n```\n\n### Binaries distributed via Cargo\n\nIf you need to install a binary crate such as [ripgrep](https://github.com/BurntSushi/ripgrep) on a CI build image, you need to build it against the GNU toolchain (see [#37](https://github.com/clux/muslrust/issues/37#issuecomment-357314202)):\n\n```sh\nCARGO_BUILD_TARGET=x86_64-unknown-linux-gnu cargo install ripgrep\n```\n\n## Alternatives\n\n- `rustup target add x86_64-unknown-linux-musl` works locally when not needing [C libraries](#c-libraries)\n- [official rust image](https://hub.docker.com/_/rust) can `target add` and easily cross-build when not needing [C libraries](#c-libraries)\n- [cross](https://github.com/japaric/cross) can cross-build different embedded targets\n","funding_links":["https://github.com/sponsors/clux"],"categories":["Dockerfile","Rust"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclux%2Fmuslrust","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclux%2Fmuslrust","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclux%2Fmuslrust/lists"}