Something went wrong. Try again.
A lexicon-driven AppView for ATProto.
Something went wrong. Try again.
25 kB · 61 lines
HTML
at gh-pages
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061<!doctype html><html lang="en" dir="ltr" class="docs-wrapper plugin-docs plugin-id-default docs-version-current docs-doc-page docs-doc-id-reference/production-deployment" data-has-hydrated="false"><head><meta charset="UTF-8"><meta name="generator" content="Docusaurus v3.10.0"><title data-rh="true">Production | HappyView</title><meta data-rh="true" name="viewport" content="width=device-width,initial-scale=1"><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:image" content="https://happyview.dev/img/og.png"><meta data-rh="true" name="twitter:image" content="https://happyview.dev/img/og.png"><meta data-rh="true" property="og:url" content="https://happyview.dev/reference/production-deployment"><meta data-rh="true" property="og:locale" content="en"><meta data-rh="true" name="docusaurus_locale" content="en"><meta data-rh="true" name="docsearch:language" content="en"><meta data-rh="true" name="docusaurus_version" content="current"><meta data-rh="true" name="docusaurus_tag" content="docs-default-current"><meta data-rh="true" name="docsearch:version" content="current"><meta data-rh="true" name="docsearch:docusaurus_tag" content="docs-default-current"><meta data-rh="true" property="og:title" content="Production | HappyView"><meta data-rh="true" name="description" content="This page covers what to change when taking a HappyView instance from local development to production. For setup instructions, see Deployment. This page assumes you already have a working deployment and focuses on hardening and operational concerns."><meta data-rh="true" property="og:description" content="This page covers what to change when taking a HappyView instance from local development to production. For setup instructions, see Deployment. This page assumes you already have a working deployment and focuses on hardening and operational concerns."><link data-rh="true" rel="icon" href="/img/favicon.png"><link data-rh="true" rel="canonical" href="https://happyview.dev/reference/production-deployment"><link data-rh="true" rel="alternate" href="https://happyview.dev/reference/production-deployment" hreflang="en"><link data-rh="true" rel="alternate" href="https://happyview.dev/reference/production-deployment" hreflang="x-default"><script data-rh="true" type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Production","item":"https://happyview.dev/reference/production-deployment"}]}</script><link rel="stylesheet" href="/assets/css/styles.18b9c377.css"><script src="/assets/js/runtime~main.413aac68.js" defer="defer"></script><script src="/assets/js/main.c991874c.js" defer="defer"></script></head><body><svg style="display: none;"><defs><symbol id="theme-svg-external-link" viewBox="0 0 24 24"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"/></symbol></defs></svg><script>!function(){var t=function(){try{return new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}}()||function(){try{return window.localStorage.getItem("theme")}catch(t){}}();document.documentElement.setAttribute("data-theme",t||"light"),document.documentElement.setAttribute("data-theme-choice",t||"light")}(),function(){try{const c=new URLSearchParams(window.location.search).entries();for(var[t,e]of c)if(t.startsWith("docusaurus-data-")){var a=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}()</script><div id="__docusaurus"><link rel="preload" as="image" href="/img/logo.light.png"><link rel="preload" as="image" href="/img/logo.dark.png"><div role="region" aria-label="Skip to main content"><a class="skipToContent_hn_G" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="theme-layout-navbar navbar navbar--fixed-top"><div class="navbar__inner"><div class="theme-layout-navbar-left navbar__items"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/img/logo.light.png" alt="HappyView" class="themedComponent_EfZ_ themedComponent--light_EnZ3"><img src="/img/logo.dark.png" alt="HappyView" class="themedComponent_EfZ_ themedComponent--dark_UTRq"></div><b class="navbar__title text--truncate"></b></a><a aria-current="page" class="navbar__item navbar__link navbar__link--active" href="/">Docs</a></div><div class="theme-layout-navbar-right navbar__items navbar__items--right"><a href="https://github.com/gamesgamesgamesgamesgames/happyview" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">GitHub<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_yqny"><use href="#theme-svg-external-link"></use></svg></a><div class="toggle_pDN8 colorModeToggle_WR5U"><button class="clean-btn toggleButton__Co1 toggleButtonDisabled_pTNf" type="button" disabled="" title="system mode" aria-label="Switch between dark and light mode (currently system mode)"><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_IF_c lightToggleIcon_z1QC"><path fill="currentColor" d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_IF_c darkToggleIcon_O_bk"><path fill="currentColor" d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_IF_c systemToggleIcon_SKeC"><path fill="currentColor" d="m12 21c4.971 0 9-4.029 9-9s-4.029-9-9-9-9 4.029-9 9 4.029 9 9 9zm4.95-13.95c1.313 1.313 2.05 3.093 2.05 4.95s-0.738 3.637-2.05 4.95c-1.313 1.313-3.093 2.05-4.95 2.05v-14c1.857 0 3.637 0.737 4.95 2.05z"></path></svg></button></div><div class="navbarSearchContainer_qQFS"></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="theme-layout-main main-wrapper mainWrapper_NcQk"><div class="docsWrapper_tjyD"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_J6bC" type="button"></button><div class="docRoot_mCS9"><aside class="theme-doc-sidebar-container docSidebarContainer_AIvH"><div class="sidebarViewport_v5_F"><div class="sidebar_TbVu"><nav aria-label="Docs sidebar" class="menu thin-scrollbar menu_hz51"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/"><span title="Introduction" class="linkLabel_GBZK">Introduction</span></a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="categoryLink_RHuM menu__link menu__link--sublist menu__link--sublist-caret menu__link--active" role="button" aria-expanded="true" href="/getting-started/quickstart"><span title="Getting Started" class="categoryLinkLabel_ppUb">Getting Started</span></a></div><ul class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/getting-started/quickstart"><span title="Quickstart" class="linkLabel_GBZK">Quickstart</span></a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item"><div class="menu__list-item-collapsible"><a class="categoryLink_RHuM menu__link menu__link--sublist menu__link--sublist-caret menu__link--active" role="button" aria-expanded="true" tabindex="0" href="/getting-started/deployment/railway"><span title="Deployment" class="categoryLinkLabel_ppUb">Deployment</span></a></div><ul class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class="menu__link" tabindex="0" href="/getting-started/deployment/railway"><span title="Railway" class="linkLabel_GBZK">Railway</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class="menu__link" tabindex="0" href="/getting-started/deployment/docker"><span title="Docker" class="linkLabel_GBZK">Docker</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class="menu__link" tabindex="0" href="/getting-started/deployment/other"><span title="From Source" class="linkLabel_GBZK">From Source</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class="menu__link menu__link--active" aria-current="page" tabindex="0" href="/reference/production-deployment"><span title="Production" class="linkLabel_GBZK">Production</span></a></li></ul></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/getting-started/configuration"><span title="Configuration" class="linkLabel_GBZK">Configuration</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/getting-started/authentication"><span title="Authentication" class="linkLabel_GBZK">Authentication</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/getting-started/dashboard"><span title="Dashboard" class="linkLabel_GBZK">Dashboard</span></a></li></ul></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_RHuM menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/tutorials/statusphere"><span title="Tutorials" class="categoryLinkLabel_ppUb">Tutorials</span></a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_RHuM menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/guides/lexicons"><span title="Guides" class="categoryLinkLabel_ppUb">Guides</span></a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_RHuM menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/sdk/overview"><span title="JavaScript SDK" class="categoryLinkLabel_ppUb">JavaScript SDK</span></a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_RHuM menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/reference/xrpc-api"><span title="Reference" class="categoryLinkLabel_ppUb">Reference</span></a></div></li></ul></nav></div></div></aside><main class="docMainContainer_Gcuv"><div class="container padding-top--md padding-bottom--lg"><div class="row"><div class="col docItemCol_SLVn"><div class="docItemContainer_gUK8"><article><nav class="theme-doc-breadcrumbs breadcrumbsContainer__5rh" aria-label="Breadcrumbs"><ul class="breadcrumbs"><li class="breadcrumbs__item"><a aria-label="Home page" class="breadcrumbs__link" href="/"><svg viewBox="0 0 24 24" class="breadcrumbHomeIcon_ilNI"><path d="M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z" fill="currentColor"></path></svg></a></li><li class="breadcrumbs__item"><span class="breadcrumbs__link">Getting Started</span></li><li class="breadcrumbs__item"><span class="breadcrumbs__link">Deployment</span></li><li class="breadcrumbs__item breadcrumbs__item--active"><span class="breadcrumbs__link">Production</span></li></ul></nav><div class="tocCollapsible_vaUl theme-doc-toc-mobile tocMobile_CcuZ"><button type="button" class="clean-btn tocCollapsibleButton__AHn">On this page</button></div><div class="theme-doc-markdown markdown"><header><h1>Production</h1></header><p>This page covers what to change when taking a HappyView instance from local development to production. For setup instructions, see <a class="" href="/getting-started/deployment/railway">Deployment</a>. This page assumes you already have a working deployment and focuses on hardening and operational concerns.</p><h2 class="anchor anchorTargetStickyNavbar_zGuS" id="session-secret">Session secret<a href="#session-secret" class="hash-link" aria-label="Direct link to Session secret" title="Direct link to Session secret" translate="no"></a></h2><p>Set <code>SESSION_SECRET</code> to a random string of at least 64 characters. This signs the session cookies issued during OAuth login; rotating it invalidates every existing session.</p><div class="language-sh codeBlockContainer_ei_j theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_p9UO"><pre tabindex="0" class="prism-code language-sh codeBlock_NBAy thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_AQpN"><div class="token-line" style="color:#bfc7d5"><span class="token plain">openssl rand -base64 48</span><br></div></code></pre></div></div><p>Never commit the secret to source control. Store it in your platform's secret manager (Railway variables, Docker secrets, Kubernetes secrets, etc.).</p><h2 class="anchor anchorTargetStickyNavbar_zGuS" id="token-encryption-key">Token encryption key<a href="#token-encryption-key" class="hash-link" aria-label="Direct link to Token encryption key" title="Direct link to Token encryption key" translate="no"></a></h2><p>If you use <a class="" href="/guides/plugins">plugins</a> that require secrets (API keys, OAuth credentials), set <code>TOKEN_ENCRYPTION_KEY</code> to a base64-encoded 32-byte key. This encrypts plugin secrets at rest using AES-256-GCM:</p><div class="language-sh codeBlockContainer_ei_j theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_p9UO"><pre tabindex="0" class="prism-code language-sh codeBlock_NBAy thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_AQpN"><div class="token-line" style="color:#bfc7d5"><span class="token plain">openssl rand -base64 32</span><br></div></code></pre></div></div><p>Without this variable, the dashboard's plugin secret fields are disabled and plugins can only read secrets from environment variables.</p><h2 class="anchor anchorTargetStickyNavbar_zGuS" id="tls-and-public_url">TLS and <code>PUBLIC_URL</code><a href="#tls-and-public_url" class="hash-link" aria-label="Direct link to tls-and-public_url" title="Direct link to tls-and-public_url" translate="no"></a></h2><p>HappyView does not terminate TLS. Put it behind a reverse proxy (nginx, Caddy, Cloudflare Tunnel, a platform-managed load balancer) and set <code>PUBLIC_URL</code> to the public HTTPS URL:</p><div class="language-sh codeBlockContainer_ei_j theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_p9UO"><pre tabindex="0" class="prism-code language-sh codeBlock_NBAy thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_AQpN"><div class="token-line" style="color:#bfc7d5"><span class="token plain">PUBLIC_URL=https://happyview.example.com</span><br></div></code></pre></div></div><p><code>PUBLIC_URL</code> is used to construct OAuth redirect URIs, so it must exactly match the URL users hit — including scheme. A mismatch breaks OAuth login.</p><h2 class="anchor anchorTargetStickyNavbar_zGuS" id="database">Database<a href="#database" class="hash-link" aria-label="Direct link to Database" title="Direct link to Database" translate="no"></a></h2><p>SQLite is fine for small to medium instances and is the default. Switch to Postgres if you need:</p><ul><li class="">Multiple HappyView replicas sharing one database</li><li class="">Larger-than-memory working sets</li><li class="">External tools that need direct read access to the records table</li></ul><p>See the <a class="" href="/guides/database-setup">database setup guide</a> for configuration details and <a class="" href="/guides/postgres-to-sqlite-migration">Postgres → SQLite migration</a> if you're moving the other direction. Migrations run automatically on startup regardless of backend.</p><h2 class="anchor anchorTargetStickyNavbar_zGuS" id="rate-limits">Rate limits<a href="#rate-limits" class="hash-link" aria-label="Direct link to Rate limits" title="Direct link to Rate limits" translate="no"></a></h2><p>HappyView has a per-client token-bucket rate limiter for XRPC endpoints. The defaults (set via <code>DEFAULT_RATE_LIMIT_CAPACITY</code> and <code>DEFAULT_RATE_LIMIT_REFILL_RATE</code>) apply to any <a class="" href="/guides/api-keys">API client</a> that doesn't have per-client overrides. Raise the defaults cautiously — they exist so one misbehaving integrator can't saturate the server.</p><p>Per-client overrides are set at client creation or via <code>PUT /admin/api-clients/{id}</code> (see <a class="" href="/reference/admin/api-clients">Admin API — API Clients</a>).</p><h2 class="anchor anchorTargetStickyNavbar_zGuS" id="logging">Logging<a href="#logging" class="hash-link" aria-label="Direct link to Logging" title="Direct link to Logging" translate="no"></a></h2><p>The default <code>RUST_LOG</code> setting (<code>happyview=debug,tower_http=debug</code>) is noisy. For production, drop the verbosity:</p><div class="language-sh codeBlockContainer_ei_j theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_p9UO"><pre tabindex="0" class="prism-code language-sh codeBlock_NBAy thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_AQpN"><div class="token-line" style="color:#bfc7d5"><span class="token plain">RUST_LOG=happyview=info,tower_http=info</span><br></div></code></pre></div></div><p>Structured logs go to stdout, so any platform that captures container stdout (Railway, Fly, ECS, Kubernetes) will ingest them without further configuration. For retention and querying, ship stdout to your usual log aggregator.</p><h2 class="anchor anchorTargetStickyNavbar_zGuS" id="event-log-retention">Event log retention<a href="#event-log-retention" class="hash-link" aria-label="Direct link to Event log retention" title="Direct link to Event log retention" translate="no"></a></h2><p>The admin <a class="" href="/guides/event-logs">event log</a> is stored in the same database as records. <code>EVENT_LOG_RETENTION_DAYS</code> (default <code>30</code>) controls automatic cleanup. Set to <code>0</code> to keep events indefinitely — useful for compliance-sensitive deployments, but plan for database growth.</p><h2 class="anchor anchorTargetStickyNavbar_zGuS" id="health-checks">Health checks<a href="#health-checks" class="hash-link" aria-label="Direct link to Health checks" title="Direct link to Health checks" translate="no"></a></h2><p><code>GET /health</code> returns <code>200 ok</code> when HappyView can bind its HTTP listener. Use it as the readiness/liveness probe for your platform.</p><p>For a deeper check, hit <code>GET /xrpc/com.atproto.server.describeServer</code> — this exercises the database and lexicon registry, and only returns <code>200</code> if HappyView can actually serve requests.</p><h2 class="anchor anchorTargetStickyNavbar_zGuS" id="backups">Backups<a href="#backups" class="hash-link" aria-label="Direct link to Backups" title="Direct link to Backups" translate="no"></a></h2><ul><li class=""><strong>SQLite</strong>: back up the database file (e.g. <code>data/happyview.db</code>) plus its <code>-wal</code> and <code>-shm</code> sidecar files. Use <code>sqlite3 happyview.db ".backup '/path/backup.db'"</code> for a consistent snapshot while HappyView is running.</li><li class=""><strong>Postgres</strong>: standard <code>pg_dump</code> / managed-Postgres snapshots.</li></ul><p>Most of what HappyView stores is derivable from the network — lost records can be re-indexed via <a class="" href="/guides/backfill">backfill</a>. You can't recover from the network: user accounts and permissions, API keys, API clients, plugin secrets, and the Jetstream cursor. Prioritize those in your backup plan.</p><h2 class="anchor anchorTargetStickyNavbar_zGuS" id="next-steps">Next steps<a href="#next-steps" class="hash-link" aria-label="Direct link to Next steps" title="Direct link to Next steps" translate="no"></a></h2><ul><li class=""><a class="" href="/getting-started/configuration">Configuration</a> — full environment variable reference</li><li class=""><a class="" href="/guides/permissions">Permissions</a> — lock down admin access before exposing the dashboard publicly</li><li class=""><a class="" href="/reference/troubleshooting">Troubleshooting</a> — diagnose issues with a running instance</li></ul></div></article><nav class="docusaurus-mt-lg pagination-nav" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--prev" href="/getting-started/deployment/other"><div class="pagination-nav__sublabel">Previous</div><div class="pagination-nav__label">From Source</div></a><a class="pagination-nav__link pagination-nav__link--next" href="/getting-started/configuration"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">Configuration</div></a></nav></div></div><div class="col col--3"><div class="tableOfContents_X45M thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#session-secret" class="table-of-contents__link toc-highlight">Session secret</a></li><li><a href="#token-encryption-key" class="table-of-contents__link toc-highlight">Token encryption key</a></li><li><a href="#tls-and-public_url" class="table-of-contents__link toc-highlight">TLS and <code>PUBLIC_URL</code></a></li><li><a href="#database" class="table-of-contents__link toc-highlight">Database</a></li><li><a href="#rate-limits" class="table-of-contents__link toc-highlight">Rate limits</a></li><li><a href="#logging" class="table-of-contents__link toc-highlight">Logging</a></li><li><a href="#event-log-retention" class="table-of-contents__link toc-highlight">Event log retention</a></li><li><a href="#health-checks" class="table-of-contents__link toc-highlight">Health checks</a></li><li><a href="#backups" class="table-of-contents__link toc-highlight">Backups</a></li><li><a href="#next-steps" class="table-of-contents__link toc-highlight">Next steps</a></li></ul></div></div></div></div></main></div></div></div><footer class="theme-layout-footer footer"><div class="container container-fluid"><div class="footer__bottom text--center"><div class="footer__copyright">Copyright © 2026 <a href="https://birb.house">Birbhouse Games</a>.</div></div></div></footer></div></body></html>