• Stars
    star
    1,451
  • Rank 32,425 (Top 0.7 %)
  • Language
    Dockerfile
  • License
    Apache License 2.0
  • Created over 8 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Docker images for compiling static Rust binaries using musl-libc and musl-gcc, with static versions of useful C libraries. Supports openssl and diesel crates.

rust-musl-builder: Docker container for easily building static Rust binaries

Docker Image

UPDATED: We are now running builds on GitHub, including scheduled builds of stable and beta every Thursday!

However, rustls now works well with most of the Rust ecosystem, including reqwest, tokio, tokio-postgres, sqlx and many others. The only major project which still requires libpq and OpenSSL is Diesel. If you don't need diesel or libpq:

  • See if you can switch away from OpenSSL, typically by using features in Cargo.toml to ask your dependencies to use rustls instead.
  • If you don't need OpenSSL, try cross build --target=x86_64-unknown-linux-musl --release to cross-compile your binaries for libmusl. This supports many more platforms, with less hassle!

What is this?

This image allows you to build static Rust binaries using diesel, sqlx or openssl. These images can be distributed as single executable files with no dependencies, and they should work on any modern Linux system.

To try it, run:

alias rust-musl-builder='docker run --rm -it -v "$(pwd)":/home/rust/src ekidd/rust-musl-builder'
rust-musl-builder cargo build --release

This command assumes that $(pwd) is readable and writable by uid 1000, gid 1000. At the moment, it doesn't attempt to cache libraries between builds, so this is best reserved for making final release builds.

For a more realistic example, see the Dockerfiles for examples/using-diesel and examples/using-sqlx.

Deploying your Rust application

With a bit of luck, you should be able to just copy your application binary from target/x86_64-unknown-linux-musl/release, and install it directly on any reasonably modern x86_64 Linux machine. In particular, you should be able make static release binaries using TravisCI and GitHub, or you can copy your Rust application into an Alpine Linux container. See below for details!

Available tags

In general, we provide the following tagged Docker images:

  • latest, stable: Current stable Rust, now with OpenSSL 1.1. We try to update this fairly rapidly after every new stable release, and after most point releases.
  • X.Y.Z: Specific versions of stable Rust.
  • beta: This usually gets updated every six weeks alongside the stable release. It will usually not be updated for beta bugfix releases.
  • nightly-YYYY-MM-DD: Specific nightly releases. These should almost always support clippy, rls and rustfmt, as verified using rustup components history. If you need a specific date for compatibility with tokio or another popular library using unstable Rust, please file an issue.

At a minimum, each of these images should be able to compile examples/using-diesel and examples/using-sqlx.

Caching builds

You may be able to speed up build performance by adding the following -v commands to the rust-musl-builder alias:

-v cargo-git:/home/rust/.cargo/git
-v cargo-registry:/home/rust/.cargo/registry
-v target:/home/rust/src/target

You will also need to fix the permissions on the mounted volumes:

rust-musl-builder sudo chown -R rust:rust \
  /home/rust/.cargo/git /home/rust/.cargo/registry /home/rust/src/target

How it works

rust-musl-builder uses musl-libc, musl-gcc, and the new rustup target support. It includes static versions of several libraries:

  • The standard musl-libc libraries.
  • OpenSSL, which is needed by many Rust applications.
  • libpq, which is needed for applications that use diesel with PostgreSQL.
  • libz, which is needed by libpq.
  • SQLite3. See examples/using-diesel.

This library also sets up the environment variables needed to compile popular Rust crates using these libraries.

Extras

This image also supports the following extra goodies:

  • Basic compilation for armv7 using musl-libc. Not all libraries are supported at the moment, however.
  • mdbook and mdbook-graphviz for building searchable HTML documentation from Markdown files. Build manuals to use alongside your cargo doc output!
  • cargo about to collect licenses for your dependencies.
  • cargo deb to build Debian packages
  • cargo deny to check your Rust project for known security issues.

Making OpenSSL work

If your application uses OpenSSL, you will also need to take a few extra steps to make sure that it can find OpenSSL's list of trusted certificates, which is stored in different locations on different Linux distributions. You can do this using openssl-probe as follows:

fn main() {
    openssl_probe::init_ssl_cert_env_vars();
    //... your code
}

Making Diesel work

In addition to setting up OpenSSL, you'll need to add the following lines to your Cargo.toml:

[dependencies]
diesel = { version = "1", features = ["postgres", "sqlite"] }

# Needed for sqlite.
libsqlite3-sys = { version = "*", features = ["bundled"] }

# Needed for Postgres.
openssl = "*"

For PostgreSQL, you'll also need to include diesel and openssl in your main.rs in the following order (in order to avoid linker errors):

extern crate openssl;
#[macro_use]
extern crate diesel;

If this doesn't work, you might be able to fix it by reversing the order. See this PR for a discussion of the latest issues involved in linking to diesel, pq-sys and openssl-sys.

Making static releases with Travis CI and GitHub

These instructions are inspired by rust-cross.

First, read the Travis CI: GitHub Releases Uploading page, and run travis setup releases as instructed. Then add the following lines to your existing .travis.yml file, replacing myapp with the name of your package:

language: rust
sudo: required
os:
- linux
- osx
rust:
- stable
services:
- docker
before_deploy: "./build-release myapp ${TRAVIS_TAG}-${TRAVIS_OS_NAME}"
deploy:
  provider: releases
  api_key:
    secure: "..."
  file_glob: true
  file: "myapp-${TRAVIS_TAG}-${TRAVIS_OS_NAME}.*"
  skip_cleanup: true
  on:
    rust: stable
    tags: true

Next, copy build-release into your project and run chmod +x build-release.

Finally, add a Dockerfile to perform the actual build:

FROM ekidd/rust-musl-builder

# We need to add the source code to the image because `rust-musl-builder`
# assumes a UID of 1000, but TravisCI has switched to 2000.
ADD --chown=rust:rust . ./

CMD cargo build --release

When you push a new tag to your project, build-release will automatically build new Linux binaries using rust-musl-builder, and new Mac binaries with Cargo, and it will upload both to the GitHub releases page for your repository.

For a working example, see faradayio/cage.

Making tiny Docker images with Alpine Linux and Rust binaries

Docker now supports multistage builds, which make it easy to build your Rust application with rust-musl-builder and deploy it using Alpine Linux. For a working example, see examples/using-diesel/Dockerfile.

Adding more C libraries

If you're using Docker crates which require specific C libraries to be installed, you can create a Dockerfile based on this one, and use musl-gcc to compile the libraries you need. For an example, see examples/adding-a-library/Dockerfile. This usually involves a bit of experimentation for each new library, but it seems to work well for most simple, standalone libraries.

If you need an especially common library, please feel free to submit a pull request adding it to the main Dockerfile! We'd like to support popular Rust crates out of the box.

Development notes

After modifying the image, run ./test-image to make sure that everything works.

Other ways to build portable Rust binaries

If for some reason this image doesn't meet your needs, there's a variety of other people working on similar projects:

License

Either the Apache 2.0 license, or the MIT license.

More Repositories

1

heroku-buildpack-rust

A buildpack for Rust applications on Heroku, with full support for Rustup, cargo and build caching.
Shell
513
star
2

subtitles-rs

Use SRT subtitle files to study foreign languages (in progress)
Rust
283
star
3

toyos-rs

Just hacking around on a toy Rust-based on based on the blog posts at http://blog.phil-opp.com/
Rust
85
star
4

sinatra-url-for

Construct absolute paths and full URLs to actions in a Sinatra application
Ruby
60
star
5

rust-streaming

EXPERIMENTAL: Various hacks for zero-allocation stream parsing in Rust.
Rust
58
star
6

heroku-rust-cargo-hello

Simple Rust webserver built using Cargo, deployable to Heroku.
Rust
48
star
7

rust-buildpack-example-actix

Example Rust application for Heroku
Rust
40
star
8

duktape-rs

Rust wrapper for Duktape, a lightweight, embedded JavaScript interpreter.
Rust
35
star
9

rust-uchardet

Rust wrapper for the uchardet character encoding detection library
Rust
24
star
10

eshell

A complete OS command-shell, written entirely in Emacs Lisp.
Emacs Lisp
24
star
11

haskell-probability-monads

Composable probability monads in Haskell.
Haskell
22
star
12

credentials

Fetch secure credentials from multiple backends (environment, Vault, etc.) using Rust
Rust
20
star
13

rdf-agraph

Ruby AllegroGraph repository adapter for RDF.rb
Ruby
17
star
14

compose_yml

WIP: Read and write docker-compose.yml files using Rust
Rust
16
star
15

electron-test

OUT OF DATE! A fully buzzword-compliant experimental project: Electron, TypeScript, React, Redux, WebPack and Rust. It compiles and runs!
TypeScript
16
star
16

safe_erb

Automatically detect improperly escaped text in ERB templates
Ruby
16
star
17

pstsdk

Portability patches for Microsoft's pstsdk library, which reads PST-format email archives. Master branch tracks SVN; other branches contain patches.
C
15
star
18

rust-buildpack-example-rocket

Buildback example for Rust Rocket framework
Rust
14
star
19

node-feedhose

Experimental: Feedhose instant RSS protocol support for Node.js
JavaScript
13
star
20

rust-cld2

Rust wrapper for the cld2 language detection library.
Rust
12
star
21

accessors

(WIP) Getters and setters for Rust using macros 1.1
Rust
11
star
22

subtitles-rs-old

THIS IS AN ARCHIVE OF AN OLDER PROJECT, SEE subtitles-rs FOR THE CURRENT VERSION.
11
star
23

sinasi

Sinasi is not a SproutCore IDE: A SproutCore port of Rinari, for use with Emacs.
Emacs Lisp
11
star
24

resource_monitor

Detect when your Dockerized Rust application is low on memory
Rust
10
star
25

halyard

2D/3D multimedia engine scripted in Scheme
C++
9
star
26

wasm-bloat

WORK IN PROGRESS: wasm size analysis tools, may not go anywhere depending on schedule
Rust
8
star
27

cesu8-rs

Rust library which converts between UTF-8 and CESU-8 encodings.
Rust
8
star
28

xmonad-config

My Xmonad window manager configuration.
Haskell
8
star
29

rust-slow-iteration-demo

Trying to make non-copying iterators work over streaming input.
Rust
6
star
30

lexique-experiments

Experiments with the Lexique French frequency database
Python
6
star
31

blogitr

(Work in progress.) A blog storage engine based on git.
Ruby
5
star
32

mongoid_attachment

WORK IN PROGRESS: Lightweight Mongoid attachments using GridFS
Ruby
5
star
33

mongoid_references

references_one and references_many for Mongoid: Forward references through BSON::ObjectID
Ruby
4
star
34

elisp

My personal Emacs configuration
Emacs Lisp
3
star
35

hierogloss

Markdown extensions for hieroglyphic glosses (and BBCode output for forums)
Ruby
3
star
36

filtered_column_haskell_macro

A Mephisto port of Tom Moertel's typo:haskell plugin
2
star
37

wave-pick-several

An approval-voting gadget for use with Google Wave
Java
2
star
38

abort_on_panic-rs

Rust library to intercept panic! from unsafe locations and abort the process (for use with C FFI callbacks)
Rust
2
star
39

experimental-coq-proofs

Messing around with the Coq proof assistant
Coq
2
star
40

word-puzzler

WORK IN PROGRESS: Toolkit for solving various sorts of word puzzles.
Rust
2
star
41

buglinky

A Wave bot which turns bug numbers into links
Java
2
star
42

mongoid_attr_accessible

attr_accessible access control for Mongoid (replaces :accessible)
Ruby
2
star
43

ibus-ancient

ibus keyboards and input methods for ancient languages (prerelease).
Shell
2
star
44

heroku-rust-hello

A sample Rust application for use with emk/heroku-buildpack-rust. Uses Rustful and runs on Heroku.
Rust
2
star
45

jbob-rs

WIP: A Rust port of the J-Bob proof assistant from https://the-little-prover.github.io/
Scheme
2
star
46

pyjamas

Pyjamas is a Web Toolkit Widget set, AJAX library and python-to-javascript compiler.
Python
2
star
47

FactorioNuclearVehicles

An idea for a Factorio mod. This was fun to write!
Lua
1
star
48

snappy_framed-rs

Read and write the Snappy "framed" compression format from Rust (modest compression, very fast).
Rust
1
star
49

wave-protocol

hg-git mirror of Google's FedOne Wave server
1
star
50

cld2

Git mirror of cld2 language detection library from https://code.google.com/p/cld2/ (minus the file test_shuffle_1000_48_666.utf8)
C++
1
star
51

langforums

Temporary forum prototype to replace an existing site. UNMAINTED, RUNNING NOWHERE, WOULD NEED SECURITY UPDATES.
Ruby
1
star
52

uscheme

A random personal hack: A tiny fragment of Scheme in Haskell
Haskell
1
star
53

french-nlp-vagrant

A Vagrant VM which runs French natural language processing tools / Une machine virtuelle pour le traitement du langage naturel.
Shell
1
star
54

cstore

Really dodgy experiments with Go, Redis, and distributed SHA256 content-addressable storage.
Go
1
star
55

dribble-rs

Test your implementations of Rust's Read and Write traits by passing data in small, randomly-sized chunks.
Rust
1
star