bonfire-app/deploy.html
2024-04-16 21:21:08 +00:00

387 lines
36 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="ExDoc v0.31.2">
<meta name="project" content="bonfire_umbrella v0.9.10-cooperation-beta.62">
<title>Deployment guide — bonfire_umbrella v0.9.10-cooperation-beta.62</title>
<link rel="stylesheet" href="dist/html-elixir-JKHCEBPC.css" />
<script src="dist/handlebars.runtime-NWIB6V2M.js"></script>
<script src="dist/handlebars.templates-A7S2WMC7.js"></script>
<script src="dist/sidebar_items-0AD831F9.js"></script>
<script src="docs_config.js"></script>
<script async src="dist/html-JRPQ5PR6.js"></script>
</head>
<body data-type="extras" class="page-extra">
<script>
try {
var settings = JSON.parse(localStorage.getItem('ex_doc:settings') || '{}');
if (settings.theme === 'dark' ||
((settings.theme === 'system' || settings.theme == null) &&
window.matchMedia('(prefers-color-scheme: dark)').matches)
) {
document.body.classList.add('dark')
}
} catch (error) { }
</script>
<div class="main">
<button id="sidebar-menu" class="sidebar-button sidebar-toggle" aria-label="toggle sidebar" aria-controls="sidebar">
<i class="ri-menu-line ri-lg" title="Collapse/expand sidebar"></i>
</button>
<div class="background-layer"></div>
<nav id="sidebar" class="sidebar">
<div class="sidebar-header">
<div class="sidebar-projectInfo">
<a href="https://bonfirenetworks.org" class="sidebar-projectImage">
<img src="assets/logo.png" alt="bonfire_umbrella" />
</a>
<div>
<a href="https://bonfirenetworks.org" class="sidebar-projectName" translate="no">
bonfire_umbrella
</a>
<div class="sidebar-projectVersion" translate="no">
v0.9.10-cooperation-beta.62
</div>
</div>
</div>
<ul id="sidebar-listNav" class="sidebar-listNav" role="tablist">
<li>
<button id="extras-list-tab-button" role="tab" data-type="extras" aria-controls="extras-tab-panel" aria-selected="true" tabindex="0">
Pages
</button>
</li>
<li>
<button id="modules-list-tab-button" role="tab" data-type="modules" aria-controls="modules-tab-panel" aria-selected="false" tabindex="-1">
Modules
</button>
</li>
</ul>
</div>
<div id="extras-tab-panel" class="sidebar-tabpanel" role="tabpanel" aria-labelledby="extras-list-tab-button">
<ul id="extras-full-list" class="full-list"></ul>
</div>
<div id="modules-tab-panel" class="sidebar-tabpanel" role="tabpanel" aria-labelledby="modules-list-tab-button" hidden>
<ul id="modules-full-list" class="full-list"></ul>
</div>
</nav>
<main class="content">
<output role="status" id="toast"></output>
<div class="content-outer">
<div id="content" class="content-inner">
<div class="top-search">
<div class="search-settings">
<form class="search-bar" action="search.html">
<label class="search-label">
<span class="sr-only">Search documentation of bonfire_umbrella</span>
<input name="q" type="text" class="search-input" placeholder="Press / to search" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" />
</label>
<button type="submit" class="search-button" aria-label="Submit Search">
<i class="ri-search-2-line ri-lg" aria-hidden="true" title="Submit search"></i>
</button>
<button type="button" tabindex="-1" class="search-close-button" aria-hidden="true">
<i class="ri-close-line ri-lg" title="Cancel search"></i>
</button>
</form>
<div class="autocomplete">
</div>
<button class="icon-settings display-settings">
<i class="ri-settings-3-line"></i>
<span class="sr-only">Settings</span>
</button>
</div>
</div>
<h1>
<a href="https://github.com/bonfire-networks/bonfire-app/blob/main/docs/DEPLOY.md#L1" title="View Source" class="icon-action" rel="help">
<i class="ri-code-s-slash-line" aria-hidden="true"></i>
<span class="sr-only">View Source</span>
</a>
<span>Deployment guide</span>
</h1>
<h3 id="warning-beta-status-have-fun-but-don-t-rely-on-it-yet" class="section-heading">
<a href="#warning-beta-status-have-fun-but-don-t-rely-on-it-yet" class="hover-link">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">WARNING: beta status - have fun but don't rely on it yet 🙏</span>
</h3>
<p>Bonfire is currently beta software. While it's fun to play with it, we would not recommend running any production instances yet (meaning not using it for your primary fediverse identity) because it's not quite ready for that today. </p><p><em>These instructions are for setting up Bonfire in production. If you want to run the backend in development, please refer to our developer guide instead.</em></p><h2 id="security-warning" class="section-heading">
<a href="#security-warning" class="hover-link">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Security Warning</span>
</h2>
<p>We recommend only granting an account to people you trust to minimise the attack surface. Accordingly, Bonfire ships with public registration disabled. The admin panel has an <code class="inline">invite</code> facility. </p><hr class="thin"/><h2 id="step-0-decide-how-you-want-to-deploy-and-manage-the-app" class="section-heading">
<a href="#step-0-decide-how-you-want-to-deploy-and-manage-the-app" class="hover-link">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Step - 0 - Decide how you want to deploy and manage the app</span>
</h2>
<ul><li>Option A - Install using <a href="https://coopcloud.tech">Co-op Cloud</a> (recommended) which is an alternative to corporate cloud services built by tech co-ops, and provides handy tools for setting up and managing many self-hosted free software tools using ready-to-use &quot;recipes&quot;. Very useful if you'd like to host Bonfire alongside other open and/or federated projects. </li><li>Option B - Install using Docker containers <ul><li>Option B1 - Using pre-built Docker images (easy mode)</li><li>Option B2 - Building your own Docker image (if you want to make code changes or add your own extensions)</li></ul></li><li>Option C - Manual installation (without Docker)</li></ul><h2 id="step-1-download-and-configure-the-app" class="section-heading">
<a href="#step-1-download-and-configure-the-app" class="hover-link">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Step 1 - Download and configure the app</span>
</h2>
<h3 id="option-a-install-using-co-op-cloud-recommended" class="section-heading">
<a href="#option-a-install-using-co-op-cloud-recommended" class="hover-link">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Option A - Install using Co-op Cloud (recommended)</span>
</h3>
<ol><li>Install <a href="https://docs.coopcloud.tech/abra/">Abra</a> on your machine</li><li><a href="https://docs.coopcloud.tech/operators/">Set up a server with co-op cloud</a> </li><li>Use the <a href="https://recipes.coopcloud.tech/bonfire">Bonfire recipe</a> and follow the instructions there. </li><li><a href="#step-4-run">Done!</a></li></ol><h3 id="options-b-and-c" class="section-heading">
<a href="#options-b-and-c" class="hover-link">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Options B and C</span>
</h3>
<ol><li><p>Install dependencies.
You may need to install <a href="https://github.com/casey/just#packages">just</a>, and other requirements such as Docker (check the exact list of requirements based on the option you choose in step 2.)</p></li><li><p>Clone this repository and change into the directory:</p></li></ol><pre><code class="makeup sh" translate="no"><span class="">git clone --depth 1 https://github.com/bonfire-networks/bonfire-app.git bonfire &amp;&amp; cd bonfire
</span></code></pre><ol start="3"><li>Specify what flavour you want to run in production:</li></ol><p>The first thing to do is choose what flavour of Bonfire (eg. classic, community, or cooperation) you want to deploy, as each flavour uses different Docker images and set of configs. For example if you want to run the <code class="inline">classic</code> flavour:</p><ul><li><code class="inline">export MIX_ENV=prod FLAVOUR=classic</code> </li></ul><p>You may also want to put this in the appropriate place in your system so your choice of flavour is remembered for next time (eg. <code class="inline">~/.bashrc</code> or <code class="inline">~/.zshrc</code>)</p><p>If you're not planning on using Docker, you'll also need:</p><ul><li><code class="inline">export WITH_DOCKER=no</code></li></ul><h2 id="step-2-prepare-the-config" class="section-heading">
<a href="#step-2-prepare-the-config" class="hover-link">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Step 2- Prepare the config</span>
</h2>
<ul><li><p><strong>Option A</strong>: if deploying with co-op cloud, edit the env file at <code class="inline">~/.abra/servers/your_server/your_app.env</code> instead.</p></li><li><p><strong>Option B and C</strong>: </p></li></ul><ul><li>Run <code class="inline">just config</code> to initialise some default config and then edit the config in the <code class="inline">./.env</code> file.</li></ul><h3 id="config-keys-you-should-pay-special-attention-to" class="section-heading">
<a href="#config-keys-you-should-pay-special-attention-to" class="hover-link">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Config keys you should pay special attention to:</span>
</h3>
<p>The app needs these environment variables to be configured in order to work.</p><ul><li><code class="inline">FLAVOUR</code> should reflect your chosen flavour</li><li><code class="inline">HOSTNAME</code> (your domain name, eg: <code class="inline">bonfire.example.com</code>)</li><li><code class="inline">PUBLIC_PORT</code> (usually 443)</li><li><code class="inline">MAIL_DOMAIN</code> and <code class="inline">MAIL_KEY</code> and related keys to configure transactional email, for example set <code class="inline">MAIL_BACKEND=mailgun</code> and sign up at <a href="https://www.mailgun.com/">Mailgun</a> and then configure the domain name and key (you may also need to set <code class="inline">MAIL_BASE_URI</code> if your domain is not setup in EU, as the default <code class="inline">MAIL_BASE_URI</code> is set as <code class="inline">https://api.eu.mailgun.net/v3</code>). </li><li>SMTP is supported as well, through the following env vars <pre><code class="makeup elixir" translate="no"><span class="nc">MAIL_SERVER</span><span class="w"> </span><span class="p" data-group-id="3762647395-1">(</span><span class="n">smtp</span><span class="w"> </span><span class="n">domain</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">mail</span><span class="w"> </span><span class="n">server</span><span class="p" data-group-id="3762647395-1">)</span><span class="w">
</span><span class="nc">MAIL_DOMAIN</span><span class="w"> </span><span class="p" data-group-id="3762647395-2">(</span><span class="n">the</span><span class="w"> </span><span class="n">bit</span><span class="w"> </span><span class="k">after</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="err">@</span><span class="w"> </span><span class="ow">in</span><span class="w"> </span><span class="n">your</span><span class="w"> </span><span class="n">email</span><span class="p" data-group-id="3762647395-2">)</span><span class="w">
</span><span class="nc">MAIL_USER</span><span class="w">
</span><span class="nc">MAIL_PASSWORD</span><span class="w">
</span><span class="nc">MAIL_FROM</span><span class="w">
</span><span class="nc">MAIL_PORT</span><span class="w"> </span><span class="p" data-group-id="3762647395-3">(</span><span class="n">optional</span><span class="p" data-group-id="3762647395-3">)</span><span class="w">
</span><span class="nc">MAIL_SSL</span><span class="w"> </span><span class="p" data-group-id="3762647395-4">(</span><span class="n">optional</span><span class="p" data-group-id="3762647395-4">)</span></code></pre></li><li><code class="inline">UPLOADS_S3_BUCKET</code> and the related API key and secret for uploads. WARNING: If you want to store uploads in an object storage rather than directly on your server (which you probably want, to not run out of space), you need to configure that up front, otherwise URLs will break if you change it later. See <code class="inline">config/runtime.exs</code> for extra variables to set if you're not using the default service and region (which is <a href="https://www.scaleway.com/en/object-storage/">Scaleway</a> Paris).</li></ul><h3 id="secret-keys-for-which-you-should-put-random-secrets" class="section-heading">
<a href="#secret-keys-for-which-you-should-put-random-secrets" class="hover-link">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Secret keys for which you should put random secrets.</span>
</h3>
<p>You can run <code class="inline">just secrets</code> to generate some for you.</p><ul><li><code class="inline">SECRET_KEY_BASE</code></li><li><code class="inline">SIGNING_SALT</code></li><li><code class="inline">ENCRYPTION_SALT</code></li><li><code class="inline">POSTGRES_PASSWORD</code></li><li><code class="inline">MEILI_MASTER_KEY</code> </li></ul><h3 id="further-information-on-config" class="section-heading">
<a href="#further-information-on-config" class="hover-link">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Further information on config</span>
</h3>
<p>In the <code class="inline">./config/</code> (which is a symbolic link to the config of the flavour you choose to run) directory of the codebase, there are following config files:</p><ul><li><code class="inline">config.exs</code>: default base configuration, which itself loads many other config files, such as one for each installed Bonfire extension.</li><li><code class="inline">prod.exs</code>: default extra configuration for <code class="inline">MIX_ENV=prod</code></li><li><code class="inline">runtime.exs</code>: extra configuration which is loaded at runtime (vs the others which are only loaded once at compile time, i.e. when you build a release)</li><li><code class="inline">bonfire_*.exs</code>: configs specific to different extensions, which are automatically imported by <code class="inline">config.exs</code></li></ul><p>You should <em>not</em> have to modify the files above. Instead, overload any settings from the above files using env variables or in <code class="inline">./.env</code>. If any settings in the <code class="inline">.exs</code> config files are not available in env or in the instance settings UI, please open an issue or PR.</p><h2 id="step-3-install" class="section-heading">
<a href="#step-3-install" class="hover-link">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Step 3 - Install</span>
</h2>
<h3 id="option-a-install-using-co-op-cloud-recommended-1" class="section-heading">
<a href="#option-a-install-using-co-op-cloud-recommended-1" class="hover-link">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Option A - Install using Co-op Cloud (recommended)</span>
</h3>
<p>Follow the instructions in the coop-cloud recipe readme.</p><h3 id="option-b-install-using-docker-containers-easy-mode" class="section-heading">
<a href="#option-b-install-using-docker-containers-easy-mode" class="hover-link">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Option B - Install using Docker containers (easy mode)</span>
</h3>
<p>The easiest way to launch the docker image is using the just commands.
The <code class="inline">docker-compose.release.yml</code> uses <code class="inline">config/prod/.env</code> to launch a container with the necessary environment variables along with its dependencies, currently that means an extra postgres container, along with a reverse proxy (Caddy server, which you may want to replace with nginx or whatever you prefer).</p><p>Make sure you have <a href="https://www.docker.com/">Docker</a>, with the <a href="https://docs.docker.com/compose/install/#install-compose">compose</a> plugin, and <a href="https://github.com/casey/just#packages">just</a> installed:</p><pre><code class="makeup sh" translate="no"><span class="gp unselectable">$ </span><span class="">docker version
</span><span class="">Docker Engine - Community - 23.0.1
</span><span class="">
</span><span class="gp unselectable">$ </span><span class="">docker compose version
</span><span class="">Docker Compose version v2.16.0
</span><span class="">
</span><span class="gp unselectable">$ </span><span class="">just --version
</span><span class="">just 1.13.0
</span><span class="">...
</span></code></pre><p>Now that your tooling is set up, you have the choice of using pre-built images or building your own. For example if your flavour does not have a prebuilt image on Docker Hub, or if you want to customise any of the extensions, you can build one yourself - see option B2 below. </p><h4>Option B1 - Using pre-built Docker images (recommended to start with)</h4><ul><li>The <code class="inline">image</code> entry in <code class="inline">docker-compose.release.yml</code> will by default use the image on Docker Hub which corresponds to your chosen flavour (see step 1 above for choosing your flavour).</li></ul><p>You can see the images available per flavour, version (we currently recommend using the <code class="inline">latest</code> tag), and architecture at <a href="https://hub.docker.com/r/bonfirenetworks/bonfire/tags">https://hub.docker.com/r/bonfirenetworks/bonfire/tags</a> </p><ul><li>Start the docker containers with docker-compose:</li></ul><pre><code class="makeup elixir" translate="no"><span class="n">just</span><span class="w"> </span><span class="n">rel</span><span class="o">-</span><span class="n">run</span></code></pre><p>Run this at the prompt: </p><p><code class="inline">bin/bonfire remote</code> to enter Elixir's iex environment
<code class="inline">Bonfire.Common.Repo.migrate</code> to initialise your database</p><p>The backend should now be running at <a href="http://localhost:4000/">http://localhost:4000/</a>.</p><ul><li>If that worked, start the app as a daemon next time:</li></ul><pre><code class="makeup elixir" translate="no"><span class="n">just</span><span class="w"> </span><span class="n">rel</span><span class="o">-</span><span class="n">run</span><span class="o">-</span><span class="n">bg</span></code></pre><p>(Alternatively, <code class="inline">just rel-run-bg db</code> if you want to run the backend + db but not the web proxy, or <code class="inline">just rel-run-bg db search</code> if you want to run the full-text search index.)</p><h4>Docker-related handy commands</h4><ul><li><code class="inline">just update</code> to update to the latest release of Bonfire </li><li><code class="inline">just rel-run</code> Run the app in Docker, in the foreground</li><li><code class="inline">just rel-run-bg</code> Run the app in Docker, and keep running in the background</li><li><code class="inline">just rel-stop</code> Stop the running release</li><li><code class="inline">just rel-shell</code> Runs a simple shell inside of the container, useful to explore the image </li></ul><p>Once in the shell, you can run <code class="inline">bin/bonfire</code> with the following commands:
Usage: <code class="inline">bonfire COMMAND [ARGS]</code></p><p>The known commands are:</p><ul><li><code class="inline">start</code> Starts the system</li><li><code class="inline">start_iex</code> Starts the system with IEx attached</li><li><code class="inline">daemon</code> Starts the system as a daemon</li><li><code class="inline">daemon_iex</code> Starts the system as a daemon with IEx attached</li><li><code class="inline">eval &quot;EXPR&quot;</code> Executes the given expression on a new, non-booted system</li><li><code class="inline">rpc &quot;EXPR&quot;</code> Executes the given expression remotely on the running system</li><li><code class="inline">remote</code> Connects to the running system via a IEx remote shell</li><li><code class="inline">restart</code> Restarts the running system via a remote command</li><li><code class="inline">stop</code> Stops the running system via a remote command</li><li><code class="inline">pid</code> Prints the operating system PID of the running system via a remote command</li><li><code class="inline">version</code> Prints the release name and version to be booted</li></ul><p>There are some useful database-related release tasks under <code class="inline">EctoSparkles.Migrator.</code> that can be run in an <code class="inline">iex</code> console (which you get to with <code class="inline">just rel.shell</code> followed by <code class="inline">bin/bonfire remote</code>, assuming the app is already running):</p><ul><li><code class="inline">migrate</code> runs all up migrations</li><li><code class="inline">rollback(step)</code> roll back to step X</li><li><code class="inline">rollback_to(version)</code> roll back to a specific version</li><li><code class="inline">rollback_all</code> rolls back all migrations back to zero (caution: this means losing all data)</li></ul><p>You can also directly call some functions in the code from the command line, for example:</p><ul><li>to migrate: <code class="inline">docker exec bonfire_web bin/bonfire rpc 'Bonfire.Common.Repo.migrate'</code></li><li>to just yourself an admin: <code class="inline">docker exec bonfire_web bin/bonfire rpc 'Bonfire.Me.Users.make_admin(&quot;my_username&quot;)'</code></li></ul><h4>Option B2 - Building your own Docker image</h4><p><code class="inline">Dockerfile.release</code> uses the <a href="https://docs.docker.com/develop/develop-images/multistage-build/">multistage build</a> feature to just the image as small as possible. It generates the OTP release which is later copied into the final image packaged in an Alpine linux container.</p><p>There is a <code class="inline">justfile</code> with relevant commands (make sure set the <code class="inline">MIX_ENV=prod</code> env variable):</p><ul><li><code class="inline">just rel-build-release</code> which builds the docker image of the latest release</li><li><code class="inline">just rel-build</code> which builds the docker image, including local changes to any cloned extensions in <code class="inline">./extensions/</code> </li><li><code class="inline">just rel-tag</code> adds the &quot;latest&quot; tag to your last build, so that it will be used when running</li></ul><p>Once you've built and tagged your image, you may need to update the <code class="inline">image</code> name in <code class="inline">docker-compose.release.release.yml</code> to match (either your local image name if running on the same machine you used for the build, or a remote image on Docker Hub if you pushed it) and then follow the same steps as for option A1.</p><p>For production, we recommend to set up a CI workflow to automate this, for an example you can look at the one <a href="../github/workflows/release.yaml">we currently use</a>.</p><hr class="thin"/><h3 id="option-c-manual-installation-without-docker" class="section-heading">
<a href="#option-c-manual-installation-without-docker" class="hover-link">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Option C - Manual installation (without Docker)</span>
</h3>
<h4>Dependencies</h4><ul><li>Postgres (or Postgis) version 12 or newer</li><li><a href="https://github.com/casey/just#packages">just</a></li><li>Elixir version 1.15+ with OTP 25+. If your distribution only has an old version available, check <a href="https://elixir-lang.org/install.html">Elixir's install page</a> or use a tool like <a href="https://github.com/jdx/mise">mise</a> (run <code class="inline">mise install</code> in this directory) or asdf.</li></ul><ol><li>Building the release</li></ol><ul><li><p>Make sure you have erlang and elixir installed (check <code class="inline">Dockerfile</code> for what version we're currently using)</p></li><li><p><code class="inline">export WITH_DOCKER=no</code> OR add <code class="inline">WITH_DOCKER=no</code> to the end of <code class="inline">.env</code> and source it with <code class="inline">source .env</code></p></li><li><p>Run <code class="inline">just rel-build</code> to create an elixir release. This will create an executable in your <code class="inline">_build/prod/rel/bonfire</code> directory. Note that you will need <code class="inline">just</code> to pass in the <code class="inline">.env</code> file to the executable, like so: <code class="inline">just cmd _build/prod/rel/bonfire/bin/bonfire &lt;bonfire command&gt;</code>. Alternatively, this file can be sourced by <code class="inline">source .env</code> instead. We will be using the <code class="inline">bin/bonfire</code> executable as called from <code class="inline">just</code> from here on. </p></li></ul><ol start="2"><li>Running the release</li></ol><ul><li><p>Create a database, and a user, fill out the <code class="inline">.env</code> with your credentials and secrets</p></li><li><p>You will need to use <code class="inline">just</code> in order to pass the <code class="inline">.env</code> file to the executable. This can be accomplished by running <code class="inline">just cmd _build/prod/rel/bonfire/bin/bonfire &lt;bonfire command&gt;</code>. Just works from the root directory of the <code class="inline">justfile</code>, not your current directory.</p></li><li><p>If youre using RDS or some other locked down DB, you may need to run <code class="inline">CREATE EXTENSION IF NOT EXISTS citext WITH SCHEMA public;</code> on your database with elevated privileges.</p></li><li><p>You can check if your instance is configured correctly and get to the iex console by running <code class="inline">bin/bonfire start</code></p></li><li><p>The migrations should automatically run on first boot, but if you run into troubles the migration command is: <code class="inline">Bonfire.Common.Repo.migrate()</code> in the iex console. </p></li><li><p>To run the instance as a daemon, use <code class="inline">bin/bonfire start daemon</code>.</p></li></ul><hr class="thin"/><h3 id="option-d-with-nix" class="section-heading">
<a href="#option-d-with-nix" class="hover-link">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Option D - with Nix</span>
</h3>
<p>This repo is a Flake and includes a Nix module.</p><p>Here are the detailed steps to deploy it:</p><ul><li>run a recent version of Nix or NixOS: <a href="https://nixos.wiki">https://nixos.wiki</a></li><li>enable Flakes: <a href="https://nixos.wiki/wiki/Flakes#Installing_flakes">https://nixos.wiki/wiki/Flakes#Installing_flakes</a></li><li>add <code class="inline">sandbox = false</code> in your nix.conf</li><li>fetch and build the app and dependencies: <code class="inline">nix run github:bonfire-networks/bonfire-app start_iex</code></li><li>add it as an input to your system flake.</li><li>add an overlay to just the package available</li><li>add the required configuration in your system</li></ul><p>Your <code class="inline">flake.nix</code> file would look like the following. Remember to replace <code class="inline">myHostName</code> with your actual hostname or however your deployed system is called.</p><pre><code class="nix">{
inputs.bonfire.url = &quot;github:bonfire-networks/bonfire-app/main&quot;;
outputs = { self, nixpkgs, bonfire }: {
overlay = final: prev: with final;{
# a package named bonfire already exists on nixpkgs so we put it under a different name
elixirBonfire = bonfire.packages.x86_64-linux.default;
};
nixosConfigurations.myHostName = nixpkgs.lib.nixosSystem {
system = &quot;x86_64-linux&quot;;
modules = [
{
environment.systemPackages = [ agenix.defaultPackage.x86_64-linux ];
nixpkgs.overlays = [ self.overlay ];
}
./myHostName.nix
bonfire.nixosModules.bonfire
];
};
};
}</code></pre><p>Then your <code class="inline">myHostName.nix</code> would look like the following:</p><pre><code class="nix">{ config, lib, pkgs, ... }:
{
services.bonfire = {
# you will additionally need to expose bonfire with a reverse proxy, for example caddy
port = 4000;
package = pkgs.elixirBonfire;
dbName = &quot;bonfire&quot;;
# the environment should contain a minimum of
# SECRET_KEY_BASE
# SIGNING_SALT
# ENCRYPTION_SALT
# RELEASE_COOKIE
# have a look into nix/module.nix for more details
# the way to deploy secrets is beyond this readme, but I would recommend agenix
environmentFile = &quot;/run/secrets/bonfireEnv&quot;;
dbSocketDir = &quot;/var/run/postgresql&quot;;
};
# this is specifically for a reverse proxy, which is primarily used for SSL certs
services.ngnix = {
enable = true;
forceSSL = true;
enableACME = true;
virtualHosts.&quot;myHostName&quot;.locations.proxyPass = &quot;http://localhost:4000&quot;;
};
# You will need to accept ACME's terms and conditions if you haven't elsewhere in your configuration
security.acme.defaults.email = &quot;you@myHostName.com&quot;;
security.acme.acceptTerms = true;
# this is uniquely for database backup purposes
# replace myBackupUserName with the user name that will do the backups
# if you want to do backups differently, feel free to remove this part of the config
services.postgresql = {
ensureDatabases = [ &quot;bonfire&quot; ];
ensureUsers = [{
name = &quot;myBackupUserName&quot;;
ensurePermissions = { &quot;DATABASE bonfire&quot; = &quot;ALL PRIVILEGES&quot;; };
}];
};
}</code></pre><h2 id="step-4-run" class="section-heading">
<a href="#step-4-run" class="hover-link">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Step 4 - Run</span>
</h2>
<p>By default, the backend listens on port 4000 (TCP), so you can access it on <a href="http://localhost:4000/">http://localhost:4000/</a> (if you are on the same machine). In case of an error it will restart automatically.</p><p>Once you've signed up, you will automatically be an instance admin if you were the first to register.</p><blockquote><p>NOTE: If you are running in a restricted environment such as Amazon RDS, you will need to execute some sql against the database before migrations can run: <code class="inline">CREATE EXTENSION IF NOT EXISTS citext;</code></p></blockquote><h4>Step 5 - Adding HTTPS</h4><p>The common and convenient way for adding HTTPS is by using a reverse proxy like Nginx or Caddyserver (the latter of which is bundled as part of the docker compose setup).</p><p>Caddyserver and other servers can handle generating and setting up HTTPS certificates automatically, but if you need TLS/SSL certificates for nginx, you can look get some for free with <a href="https://letsencrypt.org/">letsencrypt</a>. The simplest way to obtain and install a certificate is to use <a href="https://certbot.eff.org">Certbot.</a>. Depending on your specific setup, certbot may be able to get a certificate and configure your web server automatically.</p><p>If you've built from source, you should point the nginx root directory to be <code class="inline">_build/prod/rel/bonfire/lib/bonfire-[current-version]/priv/static</code></p><h2 id="admin-tools" class="section-heading">
<a href="#admin-tools" class="hover-link">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Admin tools</span>
</h2>
<ul><li>LiveDashboard for viewing real-time metrics and logs at <code class="inline">/admin/system/</code></li><li>Oban logs for viewing queued jobs (e.g. for processing federated activities) <code class="inline">/admin/system/oban_queues</code></li><li>LiveAdmin for browsing data in the database at <code class="inline">/admin/system/data</code></li><li>Orion for dynamic distributed performance profiling at <code class="inline">/admin/system/orion</code></li><li>Web Observer as an alternative way to view metrics at <code class="inline">/admin/system/wobserver</code></li></ul><h2 id="troubleshooting" class="section-heading">
<a href="#troubleshooting" class="hover-link">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Troubleshooting</span>
</h2>
<p>Some common issues that may arise during deployment and our suggestions for resolving them.</p><h4>WebSocket connections not establishing behind a reverse proxy</h4><p>If you are running Bonfire behind your own reverse proxy (e.g. nginx), you might experience issues with WebSocket connections not establishing. WebSocket connections require specific configuration to work, in nginx the following configuration is necessary for websockets to work:</p><pre><code class="makeup elixir" translate="no"><span class="n">location</span><span class="w"> </span><span class="o">/</span><span class="n">live</span><span class="o">/</span><span class="n">websocket</span><span class="w"> </span><span class="p" data-group-id="6882563131-1">{</span><span class="w">
</span><span class="n">proxy_pass</span><span class="w"> </span><span class="n">http</span><span class="ss">://</span><span class="mf">127.0</span><span class="o">.</span><span class="mf">0.1</span><span class="p">:</span><span class="mi">4000</span><span class="p">;</span><span class="w">
</span><span class="c1"># these configurations are necessary to proxy WebSocket requests</span><span class="w">
</span><span class="n">proxy_http_version</span><span class="w"> </span><span class="mf">1.1</span><span class="p">;</span><span class="w">
</span><span class="n">proxy_set_header</span><span class="w"> </span><span class="nc">Upgrade</span><span class="w"> </span><span class="err">$</span><span class="n">http_upgrade</span><span class="p">;</span><span class="w">
</span><span class="n">proxy_set_header</span><span class="w"> </span><span class="nc">Connection</span><span class="w"> </span><span class="s">&quot;upgrade&quot;</span><span class="p">;</span><span class="w">
</span><span class="p" data-group-id="6882563131-1">}</span></code></pre>
<div class="bottom-actions">
<div class="bottom-actions-item">
<a href="hacking.html" class="bottom-actions-button" rel="prev">
<span class="subheader">
← Previous Page
</span>
<span class="title">
Development guide
</span>
</a>
</div>
<div class="bottom-actions-item">
<a href="architecture.html" class="bottom-actions-button" rel="next">
<span class="subheader">
Next Page →
</span>
<span class="title">
Bonfire Architecture
</span>
</a>
</div>
</div>
<footer class="footer">
<p>
<span class="line">
<button class="a-main footer-button display-quick-switch" title="Search HexDocs packages">
Search HexDocs
</button>
<a href="bonfire_umbrella.epub" title="ePub version">
Download ePub version
</a>
</span>
</p>
<p class="built-using">
Built using
<a href="https://github.com/elixir-lang/ex_doc" title="ExDoc" target="_blank" rel="help noopener" translate="no">ExDoc</a> (v0.31.2) for the
<a href="https://elixir-lang.org" title="Elixir" target="_blank" translate="no">Elixir programming language</a>
</p>
</footer>
</div>
</div>
</main>
</div>
</body>
</html>