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.