Rust produces fast, memory-safe binaries that deploy as easily as Go’s. The standard way to install it is rustup, the official toolchain manager — distribution packages usually lag behind and don’t support multiple toolchains well.

Install with rustup

Install build essentials first (Rust uses the system linker):

sudo apt update
sudo apt install -y build-essential curl pkg-config libssl-dev

Then:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"
rustc --version
cargo --version

rustup installs into ~/.rustup and ~/.cargo for your user — no root needed. The installer adds ~/.cargo/bin to your shell profile.

pkg-config and libssl-dev are needed by the many crates that link against OpenSSL; crates using rustls don’t need them.

Keep it updated

rustup update
rustup self update

Rust releases a new stable version every six weeks.

Toolchains and components

rustup toolchain install nightly
rustup default stable
rustup override set nightly        # use nightly in the current directory only
rustup component add clippy rustfmt

A rust-toolchain.toml in a project pins the version for everyone:

[toolchain]
channel = "1.83"
components = ["clippy", "rustfmt"]

Build a project

cargo new hello --bin
cd hello
cargo run
cargo build --release
ls -lh target/release/hello

Release builds are optimised and much faster than debug builds. Make them smaller in Cargo.toml:

[profile.release]
strip = true
lto = true
codegen-units = 1

Static binaries with musl

Like Go’s static binaries, a musl build runs on any Linux distribution without glibc version worries:

rustup target add x86_64-unknown-linux-musl
sudo apt install -y musl-tools
cargo build --release --target x86_64-unknown-linux-musl

Crates with C dependencies (like OpenSSL) need musl-compatible versions; prefer rustls-based crates for easier static builds. For cross-compiling to ARM or other targets, cross (cargo install cross) uses Docker containers with the right toolchains.

Compiling on a small VPS

Rust compilation is CPU- and memory-hungry. Large projects can exhaust 1–2 GB RAM and get killed by the OOM killer (“signal: 9, SIGKILL” during linking). Options:

  • Build elsewhere — on your workstation or in CI, then copy the binary to the server. This is the best approach.
  • Add swap — slower, but prevents crashes: see swap file vs partition.
  • Reduce parallelism — cargo build --release -j 1.
  • Disable LTO for faster, lighter builds while iterating.

Run as a service

Copy the binary to /opt/hello/, create a system user, and use a systemd unit like the one in installing Go — the deployment pattern is identical. Put Nginx or Caddy in front for HTTPS.

Docker builds

Multi-stage builds keep the toolchain out of the runtime image:

FROM rust:1 AS build
WORKDIR /src
COPY . .
RUN cargo build --release

FROM debian:bookworm-slim
COPY --from=build /src/target/release/hello /usr/local/bin/hello
USER nobody
CMD ["hello"]

Cache dependency builds with BuildKit cache mounts on /usr/local/cargo/registry and /src/target — see Docker build cache.

Uninstall

rustup self uninstall

Useful tools

cargo clippy            # lints
cargo fmt               # formatting
cargo install cargo-audit && cargo audit   # known vulnerabilities in dependencies

Related: installing Go and systemd unit files. A build server or CI runner with more cores — our KVM VPS plans go up to 14 vCPU — speeds up Rust compiles considerably.

  • Rust
  • Linux
  • Development