Menu
AkurAI-Build
publicLatest change 0cf28150faedd8c150474a4f16be4c9922c04f56 - feat: add Ponytail UI design system by Olafur Bui
{% extends "layouts/docs.html" %} {% block title %}Deployment and recovery ยท
Bunfork docs{% endblock %} {% block description %}Create digest-owned Bunfork
deployment bundles, run hardened systemd units, and perform encrypted backup and
verified restore procedures.{% endblock %} {% block breadcrumb %}Deploy &
recover{% endblock %} {% block docs_title %}Deploy & recover{% endblock %}
{% block docs_summary %}A release should be identifiable, replaceable, and
recoverable. Bunfork builds a local owned bundle and keeps runtime state outside
it.{% endblock %} {% block docs_content %}
<section class="doc-section" aria-labelledby="native-deploy">
<h2 id="native-deploy">Create a native release</h2>
<pre><code>./target/release/bunfork deploy
./bunfork-dist/bunfork \
--database "$HOME/.local/share/bunfork/bunfork.db" \
--key-file "$HOME/.config/bunfork/db.key" \
serve --token-file "$HOME/.config/bunfork/api.token"</code></pre>
<p>
<code>deploy</code> takes a project lock, runs tests, release-builds,
stages, hashes, fsyncs, and atomically installs <code>bunfork-dist</code>.
Its <code>bunfork.json</code> inventory owns every bundled file except the
manifest itself.
</p>
<p>
Runtime database, key, and token paths are intentionally not bundled. Keep
immutable release files under <code>$HOME/.local/lib/bunfork</code>, mutable
data under <code>$HOME/.local/share/bunfork</code>, and secrets under
<code>$HOME/.config/bunfork</code>.
</p>
</section>
<section class="doc-section" aria-labelledby="static-deploy">
<h2 id="static-deploy">Bundle an admitted static site</h2>
<pre><code>./target/release/bunfork deploy \
--artifact frontend/out \
--static-manifest bunfork-static.json</code></pre>
<p>
The static bundle contains the Bunfork binary, admitted site, strict
artifact manifest, deployment inventory, and service units. It runs from any
working directory and needs no data secrets.
</p>
<pre><code>./bunfork-dist/bunfork serve \
--static ./bunfork-dist/site \
--manifest ./bunfork-dist/bunfork-static.json</code></pre>
</section>
<section class="doc-section" aria-labelledby="replace-release">
<h2 id="replace-release">Replace only what Bunfork owns</h2>
<p>
If the output already exists, <code>--force</code> first validates its
complete inventory and binary. Modified or unowned directories are refused.
A verified previous release is preserved as a sibling and is never
automatically deleted.
</p>
<aside class="doc-note">
<strong>Protected output names:</strong> Bunfork refuses hidden paths and
project roots such as <code>app</code>, <code>src</code>, <code>data</code>,
<code>backups</code>, <code>deploy</code>, <code>migrations</code>,
<code>public</code>, and <code>target</code>.
</aside>
</section>
<section class="doc-section" aria-labelledby="service-units">
<h2 id="service-units">Hardened user services</h2>
<p>
The bundle includes native and static systemd user units configured for
<code>0.0.0.0:3100</code>. They set a restrictive umask and enable
filesystem/process controls including <code>NoNewPrivileges</code>,
<code>ProtectSystem=strict</code>, an empty capability set, and restricted
address families.
</p>
<p>
Bunfork copies the units; the operator still installs/enables them and
configures the host firewall and TLS proxy.
</p>
</section>
<section class="doc-section" aria-labelledby="backup-restore">
<h2 id="backup-restore">Backup and restore</h2>
<ol class="steps compact-steps">
<li>
<h3>Create an explicit backup</h3>
<pre><code>./target/release/bunfork backup \
--out backups/pre-release.db</code></pre>
<p>
The destination must not already exist. Publication is synced and the
encrypted schema is reopened and verified.
</p>
</li>
<li>
<h3>Stop the server before restore</h3>
<pre><code>systemctl --user stop bunfork.service</code></pre>
<p>
Bunfork has no distributed or online-restore lock. Quiesce every writer
first.
</p>
</li>
<li>
<h3>Restore with acknowledgement</h3>
<pre><code>./target/release/bunfork restore \
backups/pre-release.db --yes</code></pre>
<p>
The backup is verified, installed atomically, and the prior live
database is retained with a timestamped name.
</p>
</li>
</ol>
<aside class="doc-callout warning" aria-labelledby="key-warning">
<h2 id="key-warning">A backup is not key rotation</h2>
<p>
Backups use the same database key as the live file. Protect and recover
that key separately; losing it makes both live and backup data unreadable.
</p>
</aside>
</section>
<section class="doc-section" aria-labelledby="deploy-boundary">
<h2 id="deploy-boundary">Deployment boundary</h2>
<p>
Bunfork creates and validates local release directories. It does not
provision machines, transfer releases, configure DNS or TLS, manage remote
backup storage, or remove retained releases. Those stay explicit operator
responsibilities.
</p>
</section>
<nav class="docs-pagination" aria-label="Documentation pagination">
<a href="/docs/data"
><small>Previous</small><span aria-hidden="true">โ</span> SQLite &
vectors</a
>
<a href="/docs/security"
><small>Next</small>Security <span aria-hidden="true">โ</span></a
>
</nav>
{% endblock %}