Skip to main content

nFPM (deb/rpm/apk)

Generate Linux packages using nFPM

Anodizer integrates with nFPM to generate native Linux packages.

Classification

Packager — generates deb/rpm/apk/archlinux/ipk packages from Linux binaries. Required: not a publisher; always runs unless disabled.

Minimal config

crates:
  - name: myapp
    nfpm:
      - package_name: myapp
        formats: [deb, rpm]
        vendor: "My Company"
        homepage: "https://example.com"
        maintainer: "maintainer@example.com"
        description: "My application"
        license: MIT

Full config reference

crates:
  - name: myapp
    nfpm:
      - package_name: myapp            # optional; defaults to crate name
        formats: [deb, rpm]            # REQUIRED (>= 1 entry): deb | rpm | apk | archlinux | ipk
                                       #   with no formats entry, this config emits nothing
        vendor: ""                     # optional
        homepage: ""                   # optional
        maintainer: ""                 # optional; maintainer email
        description: ""                # optional
        license: ""                    # optional; SPDX identifier
        bindir: /usr/bin               # optional; binary installation directory
        bin_alias: ""                  # optional; rename the installed binary inside the package only
        file_name_template: ""         # optional; custom filename template
        contents: []                   # optional; additional files to include
        dependencies: {}               # optional; per-format package dependencies
        recommends: []                 # optional; soft dependencies
        suggests: []                   # optional; weaker-than-recommends dependencies
        conflicts: []                  # optional; packages this conflicts with
        replaces: []                   # optional; packages this replaces (rename upgrades)
        provides: []                   # optional; virtual packages provided
        scripts:                       # optional; install scripts
          preinstall: ""
          postinstall: ""
          preremove: ""
          postremove: ""
        overrides: {}                  # optional; per-format field overrides
        rpm: {}                        # optional; RPM-specific block (see Per-format blocks)
        deb: {}                        # optional; deb-specific block
        apk: {}                        # optional; apk-specific block
        archlinux: {}                  # optional; archlinux-specific block
        ipk: {}                        # optional; ipk (OpenWrt) block

Authentication

Not applicable — nFPM generates package files locally. Uploading them to a package repository is handled by the cloudsmith, gemfury, or artifactory publishers.

Common gotchas

  • formats: the list must match the package types your downstream publishers expect. A mismatch (e.g., configuring cloudsmith for deb but nFPM only producing rpm) silently skips upload.
  • dependencies: per-format dependency maps allow different deps for deb vs rpm — use the overrides map for format-specific fields.
  • Linux only: nFPM only processes Linux binary artifacts. Darwin/Windows targets are ignored.

Republish / update behavior

Not applicable — this is a local packaging stage, not a publisher.

nFPM config fields

FieldTypeDefaultDescription
package_namestringcrate namePackage name
formatslistrequiredPackage formats: deb, rpm, apk, archlinux, ipk. At least one entry is required — a config with no formats produces no package.
vendorstringCargo first authorDistributing entity recorded in the rpm/deb Vendor field. Auto-derives from the crate's first Cargo.toml author (with any <email> suffix stripped); set to override. See Vendor.
homepagestringnoneHomepage URL
maintainerstringnoneMaintainer email
descriptionstringnonePackage description
licensestringnoneLicense identifier
bindirstring/usr/binBinary installation directory
bin_aliasstringnoneRename the installed binary inside the package only (e.g. fdfdfind for the Debian package); the build output and archive are untouched. Templated.
file_name_templatestringautoCustom filename template
contentslistnoneAdditional files to include
dependenciesmapnonePackage dependencies keyed by format (e.g., deb: [git])
recommendslistnoneSoft (recommended) dependencies
suggestslistnoneSuggested dependencies (weaker than recommends)
conflictslistnonePackages this package conflicts with
replaceslistnonePackages this package replaces (upgrade paths from renamed packages)
provideslistnoneVirtual packages this package provides
scriptsobjectnonePre/post install/remove scripts (preinstall, postinstall, preremove, postremove)
overridesmapnonePer-format field overrides
rpmobjectnoneRPM-specific block (see Per-format blocks)
debobjectnoneDeb-specific block
apkobjectnoneAPK-specific block
archlinuxobjectnoneArchlinux-specific block
ipkobjectnoneIPK (OpenWrt) block

Vendor

The Vendor field of a deb/rpm package names the distributing entity. anodizer auto-derives it from the crate's first Cargo.toml author, stripping any <email> suffix — so a crate authored by TJ Smith <tj@jarvispro.io> produces Vendor: TJ Smith without any nfpm config. Set vendor: only to override:

# Cargo.toml
[package]
authors = ["TJ Smith <tj@jarvispro.io>"]
nfpm:
  - package_name: myapp
    formats: [deb, rpm]
    # vendor omitted -> derived as "TJ Smith"

vendor: "Some Other Org" overrides the derived value.

File contents

Include additional files in the package:

nfpm:
  - package_name: myapp
    formats: [deb, rpm]
    contents:
      - src: config.example.yaml
        dst: /etc/myapp/config.yaml
        type: config
      - src: myapp.service
        dst: /usr/lib/systemd/system/myapp.service

Install scripts

nfpm:
  - package_name: myapp
    formats: [deb]
    scripts:
      preinstall: scripts/preinstall.sh
      postinstall: scripts/postinstall.sh
      preremove: scripts/preremove.sh
      postremove: scripts/postremove.sh

Per-format blocks

Each package format has an optional dedicated block carrying settings that only apply to that format. Set the block alongside formats; anodizer emits the matching nfpm section only for the formats you list.

nfpm:
  - package_name: myapp
    formats: [rpm, deb, apk, archlinux, ipk]
    rpm:
      summary: "A fast CLI tool"        # RPM Summary tag
      compression: zstd                 # lzma | gzip | xz | zstd
      group: "System/Tools"
      packager: "Build Team <build@example.com>"
      prefixes: ["/usr"]                # relocatable RPM prefixes
      build_host: "reproducible"        # override RPM BuildHost tag
      signature:
        key_file: signing.gpg
        key_passphrase: ""              # falls back to NFPM_PASSPHRASE
      scripts:
        pretrans: scripts/pretrans.sh   # %pretrans scriptlet
        posttrans: scripts/posttrans.sh # %posttrans scriptlet
    deb:
      compression: xz                   # gzip | xz | zstd | none
      predepends: ["dpkg (>= 1.17)"]    # stronger than Depends
      breaks: ["oldpkg (<< 2.0)"]       # Breaks relationship
      lintian_overrides: ["binary-without-manpage"]
      fields:                           # extra control fields
        Built-Using: "rustc"
      signature:
        key_file: signing.gpg
        type: origin                    # origin | maint | archive
      triggers:
        activate_noawait: ["ldconfig"]
      scripts:
        rules: debian/rules
        templates: debian/templates     # debconf templates
        config: debian/config           # debconf config script
    apk:
      signature:
        key_file: signing.rsa
        key_name: "build@example.com.rsa.pub"
      scripts:
        preupgrade: scripts/preupgrade.sh
        postupgrade: scripts/postupgrade.sh
    archlinux:
      pkgbase: myapp                    # base name for split packages
      packager: "Build Team <build@example.com>"
      scripts:
        preupgrade: scripts/preupgrade.sh
        postupgrade: scripts/postupgrade.sh
    ipk:
      abi_version: "1"
      auto_installed: false
      essential: false
      predepends: ["libc"]
      tags: ["net"]
      fields:
        Maintainer: "team@example.com"

Full example

crates:
  - name: myapp
    nfpm:
      - package_name: myapp
        formats: [deb, rpm, apk]
        vendor: "My Company"
        homepage: "https://github.com/myorg/myapp"
        maintainer: "team@example.com"
        description: "A fast CLI tool"
        license: MIT
        dependencies:
          deb:
            - git
          rpm:
            - git
        contents:
          - src: config.example.yaml
            dst: /etc/myapp/config.yaml
            type: config
        overrides:
          deb:
            dependencies:
              - git
              - ca-certificates