AkurAI Build
Menu

AkurAI-Build

public

Latest 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 &amp;
    vectors</a
  >
  <a href="/docs/security"
    ><small>Next</small>Security <span aria-hidden="true">โ†’</span></a
  >
</nav>
{% endblock %}