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 withcargo build --release - Generates shell completions for bash, zsh, and fish from the
tesbinary - Packages everything into a
.debfile withcargo 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 inpackaging/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