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
158
159
|
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Empacotando o Tesseras para Debian — Tesseras</title>
<meta name="description" content="Como compilar e instalar o pacote .deb do Tesseras no Debian/Ubuntu usando cargo-deb.">
<!-- Open Graph -->
<meta property="og:type" content="article">
<meta property="og:title" content="Empacotando o Tesseras para Debian">
<meta property="og:description" content="Como compilar e instalar o pacote .deb do Tesseras no Debian/Ubuntu usando 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="Empacotando o Tesseras para Debian">
<meta name="twitter:description" content="Como compilar e instalar o pacote .deb do Tesseras no Debian/Ubuntu usando 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://tesseras.net/pt-br/">
<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/pt-br/about/">Sobre</a>
<a href="https://tesseras.net/pt-br/news/">Notícias</a>
<a href="https://tesseras.net/pt-br/releases/">Lançamentos</a>
<a href="https://tesseras.net/pt-br/faq/">FAQ</a>
<a href="https://tesseras.net/pt-br/subscriptions/">Inscrições</a>
<a href="https://tesseras.net/pt-br/contact/">Contato</a>
</nav>
<nav class="lang-switch">
<a href="https://tesseras.net/news/packaging-debian/">English</a> | <strong>Português</strong>
</nav>
</header>
<main>
<article>
<h2>Empacotando o Tesseras para Debian</h2>
<p class="news-date">2026-02-16</p>
<p>O Tesseras agora inclui um pacote <code>.deb</code> para Debian e Ubuntu. Este post explica
como compilar e instalar o pacote a partir do código-fonte usando <code>cargo-deb</code>.</p>
<h2 id="pre-requisitos">Pré-requisitos</h2>
<p>Você precisa de uma toolchain Rust funcional e das bibliotecas de sistema
necessárias:</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="compilando">Compilando</h2>
<p>Clone o repositório e execute a recipe <code>just deb</code>:</p>
<pre><code data-lang="sh">git clone https://git.sr.ht/~ijanc/tesseras
cd tesseras
just deb
</code></pre>
<p>Essa recipe faz três coisas:</p>
<ol>
<li><strong>Compila</strong> <code>tesd</code> (o daemon) e <code>tes</code> (o CLI) em modo release com
<code>cargo build --release</code></li>
<li><strong>Gera completions de shell</strong> para bash, zsh e fish a partir do binário <code>tes</code></li>
<li><strong>Empacota</strong> tudo em um arquivo <code>.deb</code> com
<code>cargo deb -p tesseras-daemon --no-build</code></li>
</ol>
<p>O resultado é um arquivo <code>.deb</code> em <code>target/debian/</code>.</p>
<h2 id="instalando">Instalando</h2>
<pre><code data-lang="sh">sudo dpkg -i target/debian/tesseras-daemon_*.deb
</code></pre>
<p>Se houver dependências faltando, corrija com:</p>
<pre><code data-lang="sh">sudo apt install -f
</code></pre>
<h2 id="configuracao-pos-instalacao">Configuração pós-instalação</h2>
<p>O script <code>postinst</code> cria automaticamente um usuário de sistema <code>tesseras</code> e o
diretório de dados <code>/var/lib/tesseras</code>. Para usar o CLI sem sudo, adicione seu
usuário ao grupo:</p>
<pre><code data-lang="sh">sudo usermod -aG tesseras $USER
</code></pre>
<p>Faça logout e login novamente, depois inicie o daemon:</p>
<pre><code data-lang="sh">sudo systemctl enable --now tesd
</code></pre>
<h2 id="o-que-o-pacote-inclui">O que o pacote inclui</h2>
<table><thead><tr><th>Caminho</th><th>Descrição</th></tr></thead><tbody>
<tr><td><code>/usr/bin/tesd</code></td><td>Daemon do nó completo</td></tr>
<tr><td><code>/usr/bin/tes</code></td><td>Cliente CLI</td></tr>
<tr><td><code>/etc/tesseras/config.toml</code></td><td>Configuração padrão (marcado como conffile)</td></tr>
<tr><td><code>/lib/systemd/system/tesd.service</code></td><td>Unit systemd com hardening de segurança</td></tr>
<tr><td>Completions de shell</td><td>bash, zsh e fish</td></tr>
</tbody></table>
<h2 id="como-o-cargo-deb-funciona">Como o cargo-deb funciona</h2>
<p>Os metadados de empacotamento ficam em <code>crates/tesseras-daemon/Cargo.toml</code> na
seção <code>[package.metadata.deb]</code>. Essa seção define:</p>
<ul>
<li><strong>depends</strong> — dependências em tempo de execução: <code>libc6</code> e <code>libsqlite3-0</code></li>
<li><strong>assets</strong> — arquivos incluídos no pacote (binários, config, unit systemd,
completions de shell)</li>
<li><strong>conf-files</strong> — arquivos tratados como configuração (preservados na
atualização)</li>
<li><strong>maintainer-scripts</strong> — scripts <code>postinst</code> e <code>postrm</code> em
<code>packaging/debian/scripts/</code></li>
<li><strong>systemd-units</strong> — integração automática com systemd</li>
</ul>
<p>O script <code>postinst</code> cria o usuário de sistema <code>tesseras</code> e o diretório de dados
na instalação. O script <code>postrm</code> remove o usuário, grupo e diretório de dados
apenas no <code>purge</code> (não na remoção simples).</p>
<h2 id="hardening-do-systemd">Hardening do systemd</h2>
<p>A unit <code>tesd.service</code> inclui diretivas de hardening de segurança:</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>O daemon roda como o usuário não-privilegiado <code>tesseras</code> e só pode escrever em
<code>/var/lib/tesseras</code>.</p>
<h2 id="deploy-para-um-servidor-remoto">Deploy para um servidor remoto</h2>
<p>O justfile inclui uma recipe <code>deploy</code> para enviar o <code>.deb</code> a um host remoto:</p>
<pre><code data-lang="sh">just deploy bootstrap1.tesseras.net
</code></pre>
<p>Isso compila o <code>.deb</code>, copia via <code>scp</code>, instala com <code>dpkg -i</code> e reinicia o
serviço <code>tesd</code>.</p>
<h2 id="atualizando">Atualizando</h2>
<p>Depois de baixar novas mudanças, basta rodar <code>just deb</code> novamente e reinstalar:</p>
<pre><code data-lang="sh">git pull
just deb
sudo dpkg -i target/debian/tesseras-daemon_*.deb
</code></pre>
</article>
</main>
<footer>
<p>© 2026 Tesseras Project. <a href="/atom.xml">News Feed</a> · <a href="https://git.sr.ht/~ijanc/tesseras">Source</a></p>
</footer>
</body>
</html>
|