#debian #ubuntu #deploy #cargo-subcommand

bin+lib cargo-deb

Make Debian packages (.deb) easily with a Cargo subcommand

60 stable releases

Uses new Rust 2021

1.39.3 Sep 20, 2022
1.38.4 Aug 16, 2022
1.38.2 Jul 6, 2022
1.37.0 Mar 25, 2022
0.1.0 Jul 31, 2017

#8 in Cargo plugins

Download history 5156/week @ 2022-06-13 5083/week @ 2022-06-20 5432/week @ 2022-06-27 4462/week @ 2022-07-04 4970/week @ 2022-07-11 6144/week @ 2022-07-18 5167/week @ 2022-07-25 5859/week @ 2022-08-01 5333/week @ 2022-08-08 5363/week @ 2022-08-15 5076/week @ 2022-08-22 5855/week @ 2022-08-29 5105/week @ 2022-09-05 5211/week @ 2022-09-12 5296/week @ 2022-09-19 5592/week @ 2022-09-26

21,603 downloads per month
Used in cargo-prod

MIT license


Debian packages from Cargo projects Build Status

This is a Cargo helper command which automatically creates binary Debian packages (.deb) from Cargo projects.


cargo install cargo-deb

Requires Rust 1.42+, and optionally dpkg, dpkg-dev and liblzma-dev. Compatible with Ubuntu.


cargo deb

Upon running cargo deb from the base directory of your Rust project, the Debian package will be created in target/debian/<project_name>_<version>_<arch>.deb (or you can change the location with the --output option). This package can be installed with dpkg -i target/debian/*.deb.

Debug symbols are stripped from the main binary by default, unless [profile.release] debug = true is set in Cargo.toml. If cargo deb --separate-debug-symbols is run, the debug symbols will be packaged as a separate file installed at /usr/lib/debug/<path-to-binary>.debug.

cargo deb --install builds and installs the project system-wide.


No configuration is necessary to make a basic package from a Cargo project with a binary. This command obtains basic information it needs from the Cargo.toml file. It uses Cargo fields: name, version, license, license-file, description, readme, homepage, and repository.

For a more complete Debian package, you may also define a new table, [package.metadata.deb] that contains maintainer, copyright, license-file, changelog, depends, conflicts, breaks, replaces, provides, extended-description/extended-description-file, section, priority, and assets.

For a Debian package that includes one or more systemd unit files you may also wish to define a new (inline) table, [package.metadata.deb.systemd-units], so that the unit files are automatically added as assets and the units are properly installed. Systemd integration

[package.metadata.deb] options

Everything is optional:

  • name: The name of the Debian package. If not present, the name of the crate is used.
  • maintainer: The person maintaining the Debian packaging. If not present, the first author is used.
  • copyright: To whom and when the copyright of the software is granted. If not present, the list of authors is used.
  • license-file: 2-element array with a location of the license file and the amount of lines to skip at the top. If not present, package-level license-file is used.
  • depends: The runtime dependencies of the project. Generated automatically when absent, or if the list includes the $auto keyword.
  • pre-depends: The pre-dependencies of the project. This will be empty by default.
  • recommends: The recommended dependencies of the project. This will be empty by default.
  • suggests: The suggested dependencies of the project. This will be empty by default.
  • enhances: A list of packages this package can enhance. This will be empty by default.
  • conflicts, breaks, replaces, providespackage transition control.
  • extended-description: An extended description of the project — the more detailed the better. Either extended-description-file (see below) or package's readme file is used if it is not provided.
  • extended-description-file: A file with extended description of the project. When specified, used if extended-description is not provided.
  • revision: Version of the Debian package (when the package is updated more often than the project).
  • section: The application category that the software belongs to.
  • priority: Defines if the package is required or optional.
  • assets: Files to be included in the package and the permissions to assign them. If assets are not specified, then defaults are taken from binaries listed in [[bin]] (copied to /usr/bin/) and package readme (copied to usr/share/doc/).
    1. The first argument of each asset is the location of that asset in the Rust project. Glob patterns are allowed. You can use target/release/ in asset paths, even if Cargo is configured to cross-compile or use custom CARGO_TARGET_DIR. The target dir paths will be automatically corrected.
    2. The second argument is where the file will be copied.
      • If is argument ends with / it will be inferred that the target is the directory where the file will be copied.
      • Otherwise, it will be inferred that the source argument will be renamed when copied.
    3. The third argument is the permissions (octal string) to assign that file.
  • maintainer-scripts: directory containing templates, preinst, postinst, prerm, or postrm scripts.
  • conf-files: List of configuration files that the package management system will not overwrite when the package is upgraded.
  • triggers-file: Path to triggers control file for use by the dpkg trigger facility.
  • changelog: Path to Debian-formatted changelog file.
  • features: List of Cargo features to use when building the package.
  • default-features: whether to use default crate features in addition to the features list (default true).
  • separate-debug-symbols: whether to keep debug symbols, but strip them from executables and save them in separate files (default false).
  • preserve-symlinks: Whether to preserve symlinks in the asset files (default false).
  • systemd-units: Optional configuration settings for automated installation of systemd units.

Example of custom Cargo.toml additions

maintainer = "Michael Aaron Murphy <mmstickman@gmail.com>"
copyright = "2017, Michael Aaron Murphy <mmstickman@gmail.com>"
license-file = ["LICENSE", "4"]
extended-description = """\
A simple subcommand for the Cargo package manager for \
building Debian packages from Rust projects."""
depends = "$auto"
section = "utility"
priority = "optional"
assets = [
    ["target/release/cargo-deb", "usr/bin/", "755"],
    ["README.md", "usr/share/doc/cargo-deb/README", "644"],

Advanced usage

--fast flag uses lighter compression. Useful for very large packages or quick deployment.


There can be multiple variants of the metadata in one Cargo.toml file. --variant=name selects the variant to use. Options set in a variant override [package.metadata.deb] options. It automatically adjusts package name.


See systemd integration.


cargo deb supports a --target flag, which takes Rust target triple. See rustc --print target-list for the list of supported values.

Cross-compilation can be run from any host, including macOS and Windows, provided that Debian-compatible linker and system libraries are available to Rust. The target has to be installed for Rust (e.g. rustup target add i686-unknown-linux-gnu) and has to be installed for the host system (e.g. Debian) (e.g. apt-get install libc6-dev-i386). Note that Rust's and Debian's architecture names are different.

cargo deb --target=i686-unknown-linux-gnu

Cross-compiled archives are saved in target/<target triple>/debian/*.deb. The actual archive path is printed on success.

This option works well for crates that either have no library dependencies or don't want to target an older release. To cross-compile with support for a release older than the host's, consider using a container or VM.

In .cargo/config you can add [target.<target triple>] strip = { path = "" } objcopy = { path = "" } to specify a path to the architecture-specific strip and objcopy commands, or use --no-strip.

Separate debug info

cargo deb --separate-debug-symbols

Removes debug symbols from executables and places them as separate files in /usr/lib/debug. Requires GNU objcopy tool.

Custom build flags

If you would like to handle the build process yourself, you can use cargo deb --no-build so that the cargo-deb command will not attempt to rebuild your project.

cargo deb -- <cargo build flags>

Flags after -- are passed to cargo build, so you can use options such as -Z, --frozen, and --locked. Please use that only for features that cargo-deb doesn't support natively.


Cargo-deb understands workspaces, but doesn't have sophisticated control for packages in the workspace. Please leave feedback if you're interested in workspace support.

It's possible to build a project in another directory with cargo deb --manifest-path=<path/to/Cargo.toml>.

Custom version strings

cargo deb --deb-version my-custom-version

Overrides the version string generated from the Cargo manifest.


~203K SLoC