Packaging Tesseras for Debian
+2026-02-16
+Tesseras now ships a .deb package for Debian and Ubuntu. This post walks
+through building and installing the package from source using cargo-deb.
Prerequisites
+You need a working Rust toolchain and the required system libraries:
+sudo apt install build-essential pkg-config libsqlite3-dev
+rustup toolchain install stable
+cargo install cargo-deb
+
+Building
+Clone the repository and run the just deb recipe:
git clone https://git.sr.ht/~ijanc/tesseras
+cd tesseras
+just deb
+
+This recipe does three things:
+-
+
- Compiles
tesd(the daemon) andtes(the CLI) in release mode with +cargo build --release
+ - Generates shell completions for bash, zsh, and fish from the
tesbinary
+ - Packages everything into a
.debfile with +cargo deb -p tesseras-daemon --no-build
+
The result is a .deb file in target/debian/.
Installing
+sudo dpkg -i target/debian/tesseras-daemon_*.deb
+
+If there are missing dependencies, fix them with:
+sudo apt install -f
+
+Post-install setup
+The postinst script automatically creates a tesseras system user and the
+data directory /var/lib/tesseras. To use the CLI without sudo, add yourself to
+the group:
sudo usermod -aG tesseras $USER
+
+Log out and back in, then start the daemon:
+sudo systemctl enable --now tesd
+
+What the package includes
+| Path | Description |
|---|---|
/usr/bin/tesd | Full node daemon |
/usr/bin/tes | CLI client |
/etc/tesseras/config.toml | Default configuration (marked as conffile) |
/lib/systemd/system/tesd.service | Systemd unit with security hardening |
| Shell completions | bash, zsh, and fish |
How cargo-deb works
+The packaging metadata lives in crates/tesseras-daemon/Cargo.toml under
+[package.metadata.deb]. This section defines:
-
+
- depends — runtime dependencies:
libc6andlibsqlite3-0
+ - assets — files to include in the package (binaries, config, systemd unit, +shell completions) +
- conf-files — files treated as configuration (preserved on upgrade) +
- maintainer-scripts —
postinstandpostrmscripts in +packaging/debian/scripts/
+ - systemd-units — automatic systemd integration +
The postinst script creates the tesseras system user and data directory on
+install. The postrm script cleans up the user, group, and data directory only
+on purge (not on simple removal).
Systemd hardening
+The tesd.service unit includes security hardening directives:
NoNewPrivileges=true
+ProtectSystem=strict
+ProtectHome=true
+ReadWritePaths=/var/lib/tesseras
+PrivateTmp=true
+PrivateDevices=true
+ProtectKernelTunables=true
+ProtectControlGroups=true
+RestrictSUIDSGID=true
+MemoryDenyWriteExecute=true
+
+The daemon runs as the unprivileged tesseras user and can only write to
+/var/lib/tesseras.
Deploying to a remote server
+The justfile includes a deploy recipe for pushing the .deb to a remote host:
just deploy bootstrap1.tesseras.net
+
+This builds the .deb, copies it via scp, installs it with dpkg -i, and
+restarts the tesd service.
Updating
+After pulling new changes, simply run just deb again and reinstall:
git pull
+just deb
+sudo dpkg -i target/debian/tesseras-daemon_*.deb
+
+
+