summaryrefslogtreecommitdiffstats
path: root/news/packaging-debian/index.html
blob: bfe756322395ae49a3dec402ac095fc339b79784 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Packaging Tesseras for Debian — Tesseras</title>
    <meta name="description" content="How to build and install the Tesseras .deb package on Debian&#x2F;Ubuntu using cargo-deb.">
    <!-- Open Graph -->
    <meta property="og:type" content="article">
    <meta property="og:title" content="Packaging Tesseras for Debian">
    <meta property="og:description" content="How to build and install the Tesseras .deb package on Debian&#x2F;Ubuntu using cargo-deb.">
    <meta property="og:image" content="https://tesseras.net/images/social.jpg">
    <meta property="og:image:width" content="1200">
    <meta property="og:image:height" content="630">
    <meta property="og:site_name" content="Tesseras">
    <!-- Twitter Card -->
    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:title" content="Packaging Tesseras for Debian">
    <meta name="twitter:description" content="How to build and install the Tesseras .deb package on Debian&#x2F;Ubuntu using cargo-deb.">
    <meta name="twitter:image" content="https://tesseras.net/images/social.jpg">
    <link rel="stylesheet" href="https://tesseras.net/style.css?h=21f0f32121928ee5c690">
    
        
            <link rel="alternate" type="application/atom+xml" title="Tesseras" href="https://tesseras.net/atom.xml">
        
    
    <link rel="icon" type="image/png" sizes="32x32" href="https://tesseras.net/images/favicon.png?h=be4e123a23393b1a027d">
    
</head>
<body>
    <header>
        <h1>
            <a href="https:&#x2F;&#x2F;tesseras.net/">
                <img src="https://tesseras.net/images/logo-64.png?h=c1b8d0c4c5f93b49d40b" alt="Tesseras" width="40" height="40" class="logo">
                Tesseras
            </a>
        </h1>
        <nav>
            
                <a href="https://tesseras.net/about/">About</a>
                <a href="https://tesseras.net/news/">News</a>
                <a href="https://tesseras.net/releases/">Releases</a>
                <a href="https://tesseras.net/faq/">FAQ</a>
                <a href="https://tesseras.net/subscriptions/">Subscriptions</a>
                <a href="https://tesseras.net/contact/">Contact</a>
            
        </nav>
        <nav class="lang-switch">
            
                <strong>English</strong> | <a href="/pt-br&#x2F;news&#x2F;packaging-debian&#x2F;">Português</a>
            
        </nav>
    </header>

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

</article>

    </main>

    <footer>
        <p>&copy; 2026 Tesseras Project. <a href="/atom.xml">News Feed</a> · <a href="https://git.sr.ht/~ijanc/tesseras">Source</a></p>
    </footer>
</body>
</html>