2026-03-08 18:11:26 -06:00

3254 lines
99 KiB
HTML
Raw 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" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="System requirements, configuration wizard walkthrough, and initial service startup.">
<meta name="author" content="Bunker Operations">
<link rel="canonical" href="https://bnkserve.org/docs/getting-started/installation/">
<link rel="prev" href="../">
<link rel="next" href="../services/">
<link rel="icon" href="../../../assets/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.2">
<title>Installation - Changemaker Lite</title>
<link rel="stylesheet" href="../../../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../../../assets/stylesheets/palette.ab4e12ef.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter:300,300i,400,400i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Inter";--md-code-font:"JetBrains Mono"}</style>
<link rel="stylesheet" href="../../../stylesheets/extra.css">
<link rel="stylesheet" href="../../../stylesheets/home.css">
<link rel="stylesheet" href="../../../stylesheets/docs-comments.css">
<link rel="stylesheet" href="../../../assets/css/video-player.css">
<link rel="stylesheet" href="../../../assets/css/image-gallery.css">
<link rel="stylesheet" href="../../../assets/css/payment-widgets.css">
<script>__md_scope=new URL("../../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
<script>
(function () {
// API URL injected from MkDocs config.extra (set by env_config_hook.py)
var apiUrl = "http://localhost:4002";
if (!apiUrl) return;
var trackUrl = apiUrl + "/api/docs-analytics/track";
// Anonymous session UUID (sessionStorage — dies with tab close, no cookies)
function getSessionHash() {
var key = "__docs_sh";
var hash = sessionStorage.getItem(key);
if (!hash) {
hash = crypto.randomUUID
? crypto.randomUUID()
: "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
var r = (Math.random() * 16) | 0;
return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
});
sessionStorage.setItem(key, hash);
}
return hash;
}
function trackPageView(path) {
var payload = JSON.stringify({
path: path,
referrer: document.referrer || undefined,
sessionHash: getSessionHash(),
});
// Prefer sendBeacon for reliability (works during tab close)
if (navigator.sendBeacon) {
navigator.sendBeacon(trackUrl, new Blob([payload], { type: "application/json" }));
} else {
fetch(trackUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: payload,
keepalive: true,
}).catch(function () {});
}
}
// Track initial page load
trackPageView(location.pathname);
// Subscribe to Material's SPA navigation observable (instant loading)
if (typeof document$ !== "undefined") {
document$.subscribe(function () {
trackPageView(location.pathname);
});
}
})();
</script>
<script>"undefined"!=typeof __md_analytics&&__md_analytics()</script>
<meta property="og:type" content="website" />
<meta property="og:title" content="Installation - Changemaker Lite" />
<meta property="og:description" content="System requirements, configuration wizard walkthrough, and initial service startup." />
<meta property="og:image" content="https://bnkserve.org/assets/images/social/docs/getting-started/installation.png" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:url" content="https://bnkserve.org/docs/getting-started/installation/" />
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:title" content="Installation - Changemaker Lite" />
<meta property="twitter:description" content="System requirements, configuration wizard walkthrough, and initial service startup." />
<meta property="twitter:image" content="https://bnkserve.org/assets/images/social/docs/getting-started/installation.png" />
</head>
<body dir="ltr" data-md-color-scheme="slate" data-md-color-primary="deep-purple" data-md-color-accent="amber">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#installation" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
<aside class="md-banner">
<div class="md-banner__inner md-grid md-typeset">
<button class="md-banner__button md-icon" aria-label="Don't show this again">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons+Outlined" rel="stylesheet">
<nav class="cm-header-nav" role="navigation" aria-label="Application">
<div class="cm-header-nav__brand">
<a href="#" data-path="/home" class="cm-header-nav__brand-link">
<span class="cm-header-nav__brand-text">Changemaker Lite</span>
</a>
</div>
<div class="cm-header-nav__links">
<div class="cm-header-nav__links-inner">
<a href="#" data-path="/home" class="cm-header-nav__link" data-nav-id="home"><span class="material-icons-outlined">home</span><span class="cm-header-nav__label">Home</span></a>
<a href="#" data-path="/campaigns" class="cm-header-nav__link" data-nav-id="campaigns"><span class="material-icons-outlined">send</span><span class="cm-header-nav__label">Campaigns</span></a>
<a href="#" data-path="/map" class="cm-header-nav__link" data-nav-id="map"><span class="material-icons-outlined">place</span><span class="cm-header-nav__label">Map</span></a>
<div class="cm-header-nav__dropdown">
<span class="cm-header-nav__link cm-header-nav__dropdown-trigger">
<span class="material-icons-outlined">apps</span>
<span class="cm-header-nav__label">Scheduling</span>
<span class="material-icons-outlined cm-header-nav__chevron">expand_more</span>
</span>
<div class="cm-header-nav__dropdown-menu">
<a href="#" data-path="/shifts" class="cm-header-nav__dropdown-item" data-nav-id="shifts"><span class="material-icons-outlined">schedule</span><span>Shifts</span></a>
<a href="#" data-path="/events" class="cm-header-nav__dropdown-item" data-nav-id="events"><span class="material-icons-outlined">event</span><span>Calendar</span></a>
<a href="#" data-path="/polls" class="cm-header-nav__dropdown-item" data-nav-id="polls"><span class="material-icons-outlined">bar_chart</span><span>Polls</span></a>
</div>
</div>
<a href="#" data-path="/gallery" class="cm-header-nav__link" data-nav-id="gallery"><span class="material-icons-outlined">play_circle</span><span class="cm-header-nav__label">Gallery</span></a>
<div class="cm-header-nav__dropdown">
<span class="cm-header-nav__link cm-header-nav__dropdown-trigger">
<span class="material-icons-outlined">account_balance_wallet</span>
<span class="cm-header-nav__label">Commerce</span>
<span class="material-icons-outlined cm-header-nav__chevron">expand_more</span>
</span>
<div class="cm-header-nav__dropdown-menu">
<a href="#" data-path="/pricing" class="cm-header-nav__dropdown-item" data-nav-id="pricing"><span class="material-icons-outlined">attach_money</span><span>Pricing</span></a>
<a href="#" data-path="/shop" class="cm-header-nav__dropdown-item" data-nav-id="shop"><span class="material-icons-outlined">shopping_bag</span><span>Shop</span></a>
<a href="#" data-path="/donate" class="cm-header-nav__dropdown-item" data-nav-id="donate"><span class="material-icons-outlined">favorite_border</span><span>Donate</span></a>
</div>
</div>
<a href="#" data-path="/wall-of-fame" class="cm-header-nav__link" data-nav-id="wall-of-fame"><span class="material-icons-outlined">emoji_events</span><span class="cm-header-nav__label">Wall of Fame</span></a>
<a href="#" data-path="/pages" class="cm-header-nav__link" data-nav-id="pages"><span class="material-icons-outlined">description</span><span class="cm-header-nav__label">Pages</span></a>
<a href="/" class="cm-header-nav__link" data-nav-id="landing"><span class="material-icons-outlined">language</span><span class="cm-header-nav__label">Website</span></a>
<a href="/docs/" class="cm-header-nav__link" data-nav-id="docs"><span class="material-icons-outlined">menu_book</span><span class="cm-header-nav__label">Docs</span></a>
<a href="#" data-path="/login" class="cm-header-nav__link" id="cm-signin-link">
<span class="material-icons-outlined">login</span>
<span class="cm-header-nav__label">Sign In</span>
</a>
<div class="cm-header-nav__dropdown" id="cm-admin-dropdown" style="display:none">
<span class="cm-header-nav__link cm-header-nav__dropdown-trigger">
<span class="material-icons-outlined">person</span>
<span class="cm-header-nav__label">Admin</span>
<span class="material-icons-outlined cm-header-nav__chevron">expand_more</span>
</span>
<div class="cm-header-nav__dropdown-menu cm-header-nav__dropdown-menu--right">
<a href="#" data-path="/app" class="cm-header-nav__dropdown-item"><span class="material-icons-outlined">dashboard</span><span>Admin Panel</span></a>
<a href="#" data-path="/volunteer" class="cm-header-nav__dropdown-item"><span class="material-icons-outlined">volunteer_activism</span><span>Volunteer Portal</span></a>
<a href="#" data-path="/volunteer/profile" class="cm-header-nav__dropdown-item"><span class="material-icons-outlined">account_circle</span><span>My Profile</span></a>
<a href="#" data-path="/logout" class="cm-header-nav__dropdown-item"><span class="material-icons-outlined">logout</span><span>Logout</span></a>
</div>
</div>
</div>
<button class="cm-header-nav__hamburger" aria-label="Open navigation menu">
<span class="material-icons-outlined">menu</span>
</button>
</div>
</nav>
<div class="cm-header-nav__mobile-drawer" id="cm-mobile-drawer">
<div class="cm-header-nav__mobile-header">
<span class="cm-header-nav__brand-text">Changemaker Lite</span>
<button class="cm-header-nav__mobile-close" aria-label="Close navigation menu">
<span class="material-icons-outlined">close</span>
</button>
</div>
<div class="cm-header-nav__mobile-links">
<a href="#" data-path="/home" class="cm-header-nav__mobile-link" data-nav-id="home"><span class="material-icons-outlined">home</span><span>Home</span></a>
<a href="#" data-path="/campaigns" class="cm-header-nav__mobile-link" data-nav-id="campaigns"><span class="material-icons-outlined">send</span><span>Campaigns</span></a>
<a href="#" data-path="/map" class="cm-header-nav__mobile-link" data-nav-id="map"><span class="material-icons-outlined">place</span><span>Map</span></a>
<div class="cm-header-nav__mobile-group" data-group-id="scheduling">
<span class="cm-header-nav__mobile-link cm-header-nav__mobile-group-trigger" role="button">
<span class="material-icons-outlined">apps</span>
<span style="flex:1">Scheduling</span>
<span class="material-icons-outlined cm-header-nav__mobile-chevron">expand_more</span>
</span>
<div class="cm-header-nav__mobile-group-children">
<a href="#" data-path="/shifts" class="cm-header-nav__mobile-link" data-nav-id="shifts" style="padding-left:48px"><span class="material-icons-outlined">schedule</span><span>Shifts</span></a>
<a href="#" data-path="/events" class="cm-header-nav__mobile-link" data-nav-id="events" style="padding-left:48px"><span class="material-icons-outlined">event</span><span>Calendar</span></a>
<a href="#" data-path="/polls" class="cm-header-nav__mobile-link" data-nav-id="polls" style="padding-left:48px"><span class="material-icons-outlined">bar_chart</span><span>Polls</span></a>
</div>
</div>
<a href="#" data-path="/gallery" class="cm-header-nav__mobile-link" data-nav-id="gallery"><span class="material-icons-outlined">play_circle</span><span>Gallery</span></a>
<div class="cm-header-nav__mobile-group" data-group-id="commerce">
<span class="cm-header-nav__mobile-link cm-header-nav__mobile-group-trigger" role="button">
<span class="material-icons-outlined">account_balance_wallet</span>
<span style="flex:1">Commerce</span>
<span class="material-icons-outlined cm-header-nav__mobile-chevron">expand_more</span>
</span>
<div class="cm-header-nav__mobile-group-children">
<a href="#" data-path="/pricing" class="cm-header-nav__mobile-link" data-nav-id="pricing" style="padding-left:48px"><span class="material-icons-outlined">attach_money</span><span>Pricing</span></a>
<a href="#" data-path="/shop" class="cm-header-nav__mobile-link" data-nav-id="shop" style="padding-left:48px"><span class="material-icons-outlined">shopping_bag</span><span>Shop</span></a>
<a href="#" data-path="/donate" class="cm-header-nav__mobile-link" data-nav-id="donate" style="padding-left:48px"><span class="material-icons-outlined">favorite_border</span><span>Donate</span></a>
</div>
</div>
<a href="#" data-path="/wall-of-fame" class="cm-header-nav__mobile-link" data-nav-id="wall-of-fame"><span class="material-icons-outlined">emoji_events</span><span>Wall of Fame</span></a>
<a href="#" data-path="/pages" class="cm-header-nav__mobile-link" data-nav-id="pages"><span class="material-icons-outlined">description</span><span>Pages</span></a>
<a href="/" class="cm-header-nav__mobile-link" data-nav-id="landing"><span class="material-icons-outlined">language</span><span>Website</span></a>
<a href="/docs/" class="cm-header-nav__mobile-link" data-nav-id="docs"><span class="material-icons-outlined">menu_book</span><span>Docs</span></a>
<a href="#" data-path="/login" class="cm-header-nav__mobile-link" id="cm-mobile-signin-link">
<span class="material-icons-outlined">login</span>
<span>Sign In</span>
</a>
<div class="cm-header-nav__mobile-group" data-group-id="admin" id="cm-mobile-admin-group" style="display:none">
<span class="cm-header-nav__mobile-link cm-header-nav__mobile-group-trigger" role="button">
<span class="material-icons-outlined">person</span>
<span style="flex:1">Admin</span>
<span class="material-icons-outlined cm-header-nav__mobile-chevron">expand_more</span>
</span>
<div class="cm-header-nav__mobile-group-children">
<a href="#" data-path="/app" class="cm-header-nav__mobile-link" style="padding-left:48px"><span class="material-icons-outlined">dashboard</span><span>Admin Panel</span></a>
<a href="#" data-path="/volunteer" class="cm-header-nav__mobile-link" style="padding-left:48px"><span class="material-icons-outlined">volunteer_activism</span><span>Volunteer Portal</span></a>
<a href="#" data-path="/volunteer/profile" class="cm-header-nav__mobile-link" style="padding-left:48px"><span class="material-icons-outlined">account_circle</span><span>My Profile</span></a>
<a href="#" data-path="/logout" class="cm-header-nav__mobile-link" style="padding-left:48px"><span class="material-icons-outlined">logout</span><span>Logout</span></a>
</div>
</div>
</div>
</div>
<div class="cm-header-nav__mobile-overlay" id="cm-mobile-overlay"></div>
<script>
(function() {
var h = location.hostname;
var base;
if (h === 'localhost' || h === '127.0.0.1') {
base = location.protocol + '//localhost:' + (3002 || 3000);
} else {
var parts = h.split('.');
if (parts.length >= 3) { parts[0] = 'app'; }
else { parts.unshift('app'); }
base = location.protocol + '//' + parts.join('.');
}
var links = document.querySelectorAll('[data-path]');
for (var i = 0; i < links.length; i++) {
links[i].setAttribute('href', base + links[i].getAttribute('data-path'));
}
// Highlight active nav link based on current path
var path = location.pathname;
var activeLink = null;
if (path.indexOf('/docs') === 0) activeLink = 'docs';
document.querySelectorAll('.cm-header-nav__link[data-nav-id], .cm-header-nav__mobile-link[data-nav-id]').forEach(function(el) {
if (el.getAttribute('data-nav-id') === activeLink) {
el.classList.add('cm-header-nav__link--active');
}
});
// Hamburger toggle
var hamburger = document.querySelector('.cm-header-nav__hamburger');
var drawer = document.getElementById('cm-mobile-drawer');
var overlay = document.getElementById('cm-mobile-overlay');
var closeBtn = document.querySelector('.cm-header-nav__mobile-close');
function openDrawer() { drawer.classList.add('open'); overlay.classList.add('open'); }
function closeDrawer() { drawer.classList.remove('open'); overlay.classList.remove('open'); }
if (hamburger) hamburger.addEventListener('click', openDrawer);
if (closeBtn) closeBtn.addEventListener('click', closeDrawer);
if (overlay) overlay.addEventListener('click', closeDrawer);
// Mobile group expand/collapse toggles
document.querySelectorAll('.cm-header-nav__mobile-group-trigger').forEach(function(trigger) {
trigger.addEventListener('click', function() {
var group = this.closest('.cm-header-nav__mobile-group');
var children = group.querySelector('.cm-header-nav__mobile-group-children');
var isExpanded = group.classList.contains('expanded');
if (isExpanded) {
group.classList.remove('expanded');
children.style.display = 'none';
} else {
group.classList.add('expanded');
children.style.display = 'block';
}
});
});
// Auth-aware: show Admin dropdown for logged-in users, Sign In for guests.
// Uses hidden iframe + postMessage to read auth state from the app's origin.
function showAdminMenu() {
var s1 = document.getElementById('cm-signin-link');
var s2 = document.getElementById('cm-mobile-signin-link');
var a1 = document.getElementById('cm-admin-dropdown');
var a2 = document.getElementById('cm-mobile-admin-group');
if (s1) s1.style.display = 'none';
if (s2) s2.style.display = 'none';
if (a1) a1.style.display = '';
if (a2) a2.style.display = '';
}
// 1. Same-origin check (works when MkDocs served from same origin as app)
try {
var stored = localStorage.getItem('cml-auth');
if (stored) {
var parsed = JSON.parse(stored);
if (parsed && parsed.state && parsed.state.accessToken) {
showAdminMenu();
}
}
} catch(e) {}
// 2. Cross-origin check via hidden iframe + postMessage
var iframe = document.createElement('iframe');
iframe.style.display = 'none';
iframe.src = base + '/auth-check.html?origin=' + encodeURIComponent(location.origin);
window.addEventListener('message', function(event) {
if (event.origin !== base) return;
if (event.data && event.data.type === 'cml-auth-status' && event.data.authenticated) {
showAdminMenu();
}
});
document.body.appendChild(iframe);
})();
</script>
<style>
.md-banner {
background: linear-gradient(135deg, #005a9c 0%, #007acc 100%) !important;
color: #ffffff !important;
padding: 0 !important;
overflow: visible !important;
border: none !important;
box-shadow: none !important;
}
.md-banner__inner {
overflow: visible !important;
margin: 0 !important;
padding: 0 !important;
max-width: 100% !important;
}
.md-banner__button {
display: none !important;
}
.cm-header-nav {
background: linear-gradient(135deg, #005a9c 0%, #007acc 100%);
height: 56px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
position: relative;
z-index: 100;
box-sizing: border-box;
}
.cm-header-nav a {
color: rgba(255, 255, 255, 0.85) !important;
}
.cm-header-nav__brand-link {
display: flex;
align-items: center;
gap: 10px;
text-decoration: none !important;
color: #fff !important;
}
.cm-header-nav__brand-text {
font-size: 18px;
font-weight: 600;
color: #fff !important;
}
.cm-header-nav__links {
display: flex;
align-items: center;
}
.cm-header-nav__links-inner {
display: flex;
align-items: center;
gap: 16px;
}
.cm-header-nav__link {
color: rgba(255, 255, 255, 0.85) !important;
text-decoration: none !important;
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 14px;
transition: color 0.2s, border-color 0.2s;
white-space: nowrap;
padding-bottom: 2px;
border-bottom: 2px solid transparent;
}
.cm-header-nav__link:hover {
color: #fff !important;
text-decoration: none !important;
}
.cm-header-nav__link--active,
.cm-header-nav__link--active:hover {
color: #fff !important;
font-weight: 600;
border-bottom-color: #fff;
}
.cm-header-nav__link .material-icons-outlined {
font-size: 16px;
}
.cm-header-nav__hamburger {
display: none;
background: none;
border: none;
cursor: pointer;
padding: 4px 8px;
color: #fff;
}
.cm-header-nav__hamburger .material-icons-outlined {
font-size: 24px;
}
/* Desktop dropdown menus */
.cm-header-nav__dropdown {
position: relative;
display: inline-flex;
align-items: center;
}
.cm-header-nav__dropdown-trigger {
cursor: pointer;
user-select: none;
}
.cm-header-nav__dropdown-trigger .cm-header-nav__chevron {
font-size: 14px;
transition: transform 0.2s;
}
.cm-header-nav__dropdown:hover .cm-header-nav__chevron {
transform: rotate(180deg);
}
.cm-header-nav__dropdown-menu {
display: none;
position: absolute;
top: 100%;
left: 0;
min-width: 180px;
background: #1b2838;
border-radius: 8px;
padding: 6px 0;
box-shadow: 0 6px 16px rgba(0,0,0,0.3);
z-index: 100;
margin-top: 4px;
}
.cm-header-nav__dropdown:hover .cm-header-nav__dropdown-menu {
display: block;
}
.cm-header-nav__dropdown-menu--right {
left: auto;
right: 0;
}
.cm-header-nav__dropdown-item {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 16px;
color: rgba(255, 255, 255, 0.85) !important;
text-decoration: none !important;
font-size: 14px;
white-space: nowrap;
transition: background 0.15s;
}
.cm-header-nav__dropdown-item:hover {
background: rgba(255,255,255,0.1);
color: #fff !important;
text-decoration: none !important;
}
.cm-header-nav__dropdown-item .material-icons-outlined {
font-size: 16px;
}
/* Mobile drawer */
.cm-header-nav__mobile-drawer {
position: fixed;
top: 0;
right: -280px;
width: 280px;
height: 100vh;
background: #0d1b2a;
z-index: 10001;
transition: right 0.3s ease;
display: flex;
flex-direction: column;
}
.cm-header-nav__mobile-drawer.open {
right: 0;
}
.cm-header-nav__mobile-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 24px;
border-bottom: 1px solid rgba(255,255,255,0.1);
background: #1b2838;
}
.cm-header-nav__mobile-close {
background: none;
border: none;
cursor: pointer;
color: rgba(255,255,255,0.85);
padding: 4px;
}
.cm-header-nav__mobile-links {
display: flex;
flex-direction: column;
gap: 4px;
padding: 16px 0;
}
.cm-header-nav__mobile-link {
display: flex;
align-items: center;
gap: 10px;
padding: 12px 24px;
color: rgba(255,255,255,0.85) !important;
text-decoration: none !important;
font-size: 15px;
border-radius: 4px;
}
.cm-header-nav__mobile-link:hover {
background: rgba(255,255,255,0.1);
color: #fff !important;
text-decoration: none !important;
}
.cm-header-nav__mobile-link--active {
color: #fff !important;
font-weight: 600;
background: rgba(255,255,255,0.1);
}
.cm-header-nav__mobile-link .material-icons-outlined {
font-size: 18px;
}
/* Mobile group expand/collapse */
.cm-header-nav__mobile-group-trigger {
cursor: pointer;
user-select: none;
}
.cm-header-nav__mobile-chevron {
font-size: 14px !important;
transition: transform 0.2s;
}
.cm-header-nav__mobile-group.expanded .cm-header-nav__mobile-chevron {
transform: rotate(180deg);
}
.cm-header-nav__mobile-group-children {
display: none;
}
.cm-header-nav__mobile-overlay {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.5);
z-index: 10000;
}
.cm-header-nav__mobile-overlay.open {
display: block;
}
@media (max-width: 768px) {
.cm-header-nav { padding: 0 16px; }
.cm-header-nav__links-inner { display: none; }
.cm-header-nav__hamburger { display: block; }
.cm-header-nav__dropdown-menu { display: none !important; }
}
</style>
</div>
<script>var el=document.querySelector("[data-md-component=announce]");if(el){var content=el.querySelector(".md-typeset");__md_hash(content.innerHTML)===__md_get("__announce")&&(el.hidden=!0)}</script>
</aside>
</div>
<header class="md-header md-header--shadow md-header--lifted" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="../../.." title="Changemaker Lite" class="md-header__button md-logo" aria-label="Changemaker Lite" data-md-component="logo">
<img src="../../../assets/logo.png" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Changemaker Lite
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Installation
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="" data-md-color-scheme="slate" data-md-color-primary="deep-purple" data-md-color-accent="amber" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m17.75 4.09-2.53 1.94.91 3.06-2.63-1.81-2.63 1.81.91-3.06-2.53-1.94L12.44 4l1.06-3 1.06 3zm3.5 6.91-1.64 1.25.59 1.98-1.7-1.17-1.7 1.17.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95zm-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14.4-.4.82-.76 1.27-1.08.75-.53 1.93.36 1.85 1.19-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82-2.81 3.14-2.7 7.96.31 10.98 3.02 3.01 7.84 3.12 10.98.31"/></svg>
</label>
<input class="md-option" data-md-color-media="" data-md-color-scheme="default" data-md-color-primary="deep-purple" data-md-color-accent="amber" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_0" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 7a5 5 0 0 1 5 5 5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0-7 2.39 3.42C13.65 5.15 12.84 5 12 5s-1.65.15-2.39.42zM3.34 7l4.16-.35A7.2 7.2 0 0 0 5.94 8.5c-.44.74-.69 1.5-.83 2.29zm.02 10 1.76-3.77a7.131 7.131 0 0 0 2.38 4.14zM20.65 7l-1.77 3.79a7.02 7.02 0 0 0-2.38-4.15zm-.01 10-4.14.36c.59-.51 1.12-1.14 1.54-1.86.42-.73.69-1.5.83-2.29zM12 22l-2.41-3.44c.74.27 1.55.44 2.41.44.82 0 1.63-.17 2.37-.44z"/></svg>
</label>
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<a href="javascript:void(0)" class="md-search__icon md-icon" title="Share" aria-label="Share" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"/></svg>
</a>
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
<div class="md-search__suggest" data-md-component="search-suggest"></div>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://gitea.bnkops.com/admin/changemaker.lite" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
changemaker.lite
</div>
</a>
</div>
</nav>
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
<div class="md-grid">
<ul class="md-tabs__list">
<li class="md-tabs__item">
<a href="../../.." class="md-tabs__link">
Home
</a>
</li>
<li class="md-tabs__item md-tabs__item--active">
<a href="../../" class="md-tabs__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 21.5c-1.35-.85-3.8-1.5-5.5-1.5-1.65 0-3.35.3-4.75 1.05-.1.05-.15.05-.25.05-.25 0-.5-.25-.5-.5V6c.6-.45 1.25-.75 2-1 1.11-.35 2.33-.5 3.5-.5 1.95 0 4.05.4 5.5 1.5 1.45-1.1 3.55-1.5 5.5-1.5 1.17 0 2.39.15 3.5.5.75.25 1.4.55 2 1v14.6c0 .25-.25.5-.5.5-.1 0-.15 0-.25-.05-1.4-.75-3.1-1.05-4.75-1.05-1.7 0-4.15.65-5.5 1.5M12 8v11.5c1.35-.85 3.8-1.5 5.5-1.5 1.2 0 2.4.15 3.5.5V7c-1.1-.35-2.3-.5-3.5-.5-1.7 0-4.15.65-5.5 1.5m1 3.5c1.11-.68 2.6-1 4.5-1 .91 0 1.76.09 2.5.28V9.23c-.87-.15-1.71-.23-2.5-.23q-2.655 0-4.5.84zm4.5.17c-1.71 0-3.21.26-4.5.79v1.69c1.11-.65 2.6-.99 4.5-.99 1.04 0 1.88.08 2.5.24v-1.5c-.87-.16-1.71-.23-2.5-.23m2.5 2.9c-.87-.16-1.71-.24-2.5-.24-1.83 0-3.33.27-4.5.8v1.69c1.11-.66 2.6-.99 4.5-.99 1.04 0 1.88.08 2.5.24z"/></svg>
Docs
</a>
</li>
<li class="md-tabs__item">
<a href="../../../blog/" class="md-tabs__link">
Blog
</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary md-nav--lifted" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../../.." title="Changemaker Lite" class="md-nav__button md-logo" aria-label="Changemaker Lite" data-md-component="logo">
<img src="../../../assets/logo.png" alt="logo">
</a>
Changemaker Lite
</label>
<div class="md-nav__source">
<a href="https://gitea.bnkops.com/admin/changemaker.lite" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
changemaker.lite
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../.." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" checked>
<div class="md-nav__link md-nav__container">
<a href="../../" class="md-nav__link ">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 21.5c-1.35-.85-3.8-1.5-5.5-1.5-1.65 0-3.35.3-4.75 1.05-.1.05-.15.05-.25.05-.25 0-.5-.25-.5-.5V6c.6-.45 1.25-.75 2-1 1.11-.35 2.33-.5 3.5-.5 1.95 0 4.05.4 5.5 1.5 1.45-1.1 3.55-1.5 5.5-1.5 1.17 0 2.39.15 3.5.5.75.25 1.4.55 2 1v14.6c0 .25-.25.5-.5.5-.1 0-.15 0-.25-.05-1.4-.75-3.1-1.05-4.75-1.05-1.7 0-4.15.65-5.5 1.5M12 8v11.5c1.35-.85 3.8-1.5 5.5-1.5 1.2 0 2.4.15 3.5.5V7c-1.1-.35-2.3-.5-3.5-.5-1.7 0-4.15.65-5.5 1.5m1 3.5c1.11-.68 2.6-1 4.5-1 .91 0 1.76.09 2.5.28V9.23c-.87-.15-1.71-.23-2.5-.23q-2.655 0-4.5.84zm4.5.17c-1.71 0-3.21.26-4.5.79v1.69c1.11-.65 2.6-.99 4.5-.99 1.04 0 1.88.08 2.5.24v-1.5c-.87-.16-1.71-.23-2.5-.23m2.5 2.9c-.87-.16-1.71-.24-2.5-.24-1.83 0-3.33.27-4.5.8v1.69c1.11-.66 2.6-.99 4.5-.99 1.04 0 1.88.08 2.5.24z"/></svg>
<span class="md-ellipsis">
Docs
</span>
</a>
<label class="md-nav__link " for="__nav_2" id="__nav_2_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_2">
<span class="md-nav__icon md-icon"></span>
Docs
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_2" checked>
<div class="md-nav__link md-nav__container">
<a href="../" class="md-nav__link ">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m13.13 22.19-1.63-3.83c1.57-.58 3.04-1.36 4.4-2.27zM5.64 12.5l-3.83-1.63 6.1-2.77C7 9.46 6.22 10.93 5.64 12.5M21.61 2.39S16.66.269 11 5.93c-2.19 2.19-3.5 4.6-4.35 6.71-.28.75-.09 1.57.46 2.13l2.13 2.12c.55.56 1.37.74 2.12.46A19.1 19.1 0 0 0 18.07 13c5.66-5.66 3.54-10.61 3.54-10.61m-7.07 7.07c-.78-.78-.78-2.05 0-2.83s2.05-.78 2.83 0c.77.78.78 2.05 0 2.83s-2.05.78-2.83 0m-5.66 7.07-1.41-1.41zM6.24 22l3.64-3.64c-.34-.09-.67-.24-.97-.45L4.83 22zM2 22h1.41l4.77-4.76-1.42-1.41L2 20.59zm0-2.83 4.09-4.08c-.21-.3-.36-.62-.45-.97L2 17.76z"/></svg>
<span class="md-ellipsis">
Getting Started
</span>
</a>
<label class="md-nav__link " for="__nav_2_2" id="__nav_2_2_label" tabindex="0">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_2_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_2_2">
<span class="md-nav__icon md-icon"></span>
Getting Started
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5 20h14v-2H5m14-9h-4V3H9v6H5l7 7z"/></svg>
<span class="md-ellipsis">
Installation
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5 20h14v-2H5m14-9h-4V3H9v6H5l7 7z"/></svg>
<span class="md-ellipsis">
Installation
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="On this page">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
On this page
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#prerequisites" class="md-nav__link">
<span class="md-ellipsis">
Prerequisites
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#quick-start" class="md-nav__link">
<span class="md-ellipsis">
Quick Start
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#configuration-wizard-configsh" class="md-nav__link">
<span class="md-ellipsis">
Configuration Wizard (config.sh)
</span>
</a>
<nav class="md-nav" aria-label="Configuration Wizard (config.sh)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#step-1-prerequisites-check" class="md-nav__link">
<span class="md-ellipsis">
Step 1: Prerequisites Check
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-2-environment-file-setup" class="md-nav__link">
<span class="md-ellipsis">
Step 2: Environment File Setup
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-3-domain-configuration" class="md-nav__link">
<span class="md-ellipsis">
Step 3: Domain Configuration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-4-admin-credentials" class="md-nav__link">
<span class="md-ellipsis">
Step 4: Admin Credentials
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-5-secret-generation" class="md-nav__link">
<span class="md-ellipsis">
Step 5: Secret Generation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-6-email-configuration" class="md-nav__link">
<span class="md-ellipsis">
Step 6: Email Configuration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-7-feature-flags" class="md-nav__link">
<span class="md-ellipsis">
Step 7: Feature Flags
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-8-tunnel-configuration-pangolin" class="md-nav__link">
<span class="md-ellipsis">
Step 8: Tunnel Configuration (Pangolin)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-9-cors-origins" class="md-nav__link">
<span class="md-ellipsis">
Step 9: CORS Origins
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-10-nginx-config-generation" class="md-nav__link">
<span class="md-ellipsis">
Step 10: Nginx Config Generation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-11-homepage-services-yaml" class="md-nav__link">
<span class="md-ellipsis">
Step 11: Homepage Services YAML
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-12-container-directory-permissions" class="md-nav__link">
<span class="md-ellipsis">
Step 12: Container Directory Permissions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-13-upgrade-watcher-optional" class="md-nav__link">
<span class="md-ellipsis">
Step 13: Upgrade Watcher (Optional)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-14-summary-next-steps" class="md-nav__link">
<span class="md-ellipsis">
Step 14: Summary &amp; Next Steps
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#what-gets-modified" class="md-nav__link">
<span class="md-ellipsis">
What Gets Modified
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#manual-setup-alternative" class="md-nav__link">
<span class="md-ellipsis">
Manual Setup (Alternative)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#full-stack-startup" class="md-nav__link">
<span class="md-ellipsis">
Full Stack Startup
</span>
</a>
<nav class="md-nav" aria-label="Full Stack Startup">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#include-monitoring" class="md-nav__link">
<span class="md-ellipsis">
Include Monitoring
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#start-only-core-services" class="md-nav__link">
<span class="md-ellipsis">
Start Only Core Services
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#verifying-installation" class="md-nav__link">
<span class="md-ellipsis">
Verifying Installation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#next-steps" class="md-nav__link">
<span class="md-ellipsis">
Next Steps
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../services/" class="md-nav__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M21.81 10.25c-.06-.04-.56-.43-1.64-.43-.28 0-.56.03-.84.08-.21-1.4-1.38-2.11-1.43-2.14l-.29-.17-.18.27c-.24.36-.43.77-.51 1.19-.2.8-.08 1.56.33 2.21-.49.28-1.29.35-1.46.35H2.62c-.34 0-.62.28-.62.63 0 1.15.18 2.3.58 3.38.45 1.19 1.13 2.07 2 2.61.98.6 2.59.94 4.42.94.79 0 1.61-.07 2.42-.22 1.12-.2 2.2-.59 3.19-1.16A8.3 8.3 0 0 0 16.78 16c1.05-1.17 1.67-2.5 2.12-3.65h.19c1.14 0 1.85-.46 2.24-.85.26-.24.45-.53.59-.87l.08-.24zm-17.96.99h1.76c.08 0 .16-.07.16-.16V9.5c0-.08-.07-.16-.16-.16H3.85c-.09 0-.16.07-.16.16v1.58c.01.09.07.16.16.16m2.43 0h1.76c.08 0 .16-.07.16-.16V9.5c0-.08-.07-.16-.16-.16H6.28c-.09 0-.16.07-.16.16v1.58c.01.09.07.16.16.16m2.47 0h1.75c.1 0 .17-.07.17-.16V9.5c0-.08-.06-.16-.17-.16H8.75c-.08 0-.15.07-.15.16v1.58c0 .09.06.16.15.16m2.44 0h1.77c.08 0 .15-.07.15-.16V9.5c0-.08-.06-.16-.15-.16h-1.77c-.08 0-.15.07-.15.16v1.58c0 .09.07.16.15.16M6.28 9h1.76c.08 0 .16-.09.16-.18V7.25c0-.09-.07-.16-.16-.16H6.28c-.09 0-.16.06-.16.16v1.57c.01.09.07.18.16.18m2.47 0h1.75c.1 0 .17-.09.17-.18V7.25c0-.09-.06-.16-.17-.16H8.75c-.08 0-.15.06-.15.16v1.57c0 .09.06.18.15.18m2.44 0h1.77c.08 0 .15-.09.15-.18V7.25c0-.09-.07-.16-.15-.16h-1.77c-.08 0-.15.06-.15.16v1.57c0 .09.07.18.15.18m0-2.28h1.77c.08 0 .15-.07.15-.16V5c0-.1-.07-.17-.15-.17h-1.77c-.08 0-.15.06-.15.17v1.56c0 .08.07.16.15.16m2.46 4.52h1.76c.09 0 .16-.07.16-.16V9.5c0-.08-.07-.16-.16-.16h-1.76c-.08 0-.15.07-.15.16v1.58c0 .09.07.16.15.16"/></svg>
<span class="md-ellipsis">
Services Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../environment-variables/" class="md-nav__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6 2c-1.11 0-2 .89-2 2v16a2 2 0 0 0 2 2h6.68a7 7 0 0 1-.68-3 7 7 0 0 1 7-7 7 7 0 0 1 1 .08V8l-6-6zm7 1.5L18.5 9H13zM18 14a.26.26 0 0 0-.26.21l-.19 1.32c-.3.13-.59.29-.85.47l-1.24-.5c-.11 0-.24 0-.31.13l-1 1.73c-.06.11-.04.24.06.32l1.06.82a4.2 4.2 0 0 0 0 1l-1.06.82a.26.26 0 0 0-.06.32l1 1.73c.06.13.19.13.31.13l1.24-.5c.26.18.54.35.85.47l.19 1.32c.02.12.12.21.26.21h2c.11 0 .22-.09.24-.21l.19-1.32c.3-.13.57-.29.84-.47l1.23.5c.13 0 .26 0 .33-.13l1-1.73a.26.26 0 0 0-.06-.32l-1.07-.82c.02-.17.04-.33.04-.5s-.01-.33-.04-.5l1.06-.82a.26.26 0 0 0 .06-.32l-1-1.73c-.06-.13-.19-.13-.32-.13l-1.23.5c-.27-.18-.54-.35-.85-.47l-.19-1.32A.236.236 0 0 0 20 14zm1 3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5c-.84 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5"/></svg>
<span class="md-ellipsis">
Environment Variables
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../first-steps/" class="md-nav__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10.74 11.72c.47 1.23.42 2.51-.99 3.02-2.9 1.07-3.55-1.74-3.59-1.88zm-5.03-.81 4.32-1.07c-.19-1.05.1-2.1.1-3.34 0-1.68-1.33-4.97-3.45-4.44-2.42.6-2.77 3.29-2.68 4.59.12 1.3 1.64 4.08 1.71 4.26m12.14 8.94c-.03.15-.69 2.95-3.59 1.89-1.4-.52-1.46-1.8-.99-3.03zm2.15-6.2c.1-1.3-.24-4-2.67-4.6-2.11-.55-3.44 2.76-3.44 4.45 0 1.23.28 2.28.11 3.33l4.3 1.07c.08-.18 1.59-2.96 1.7-4.25"/></svg>
<span class="md-ellipsis">
First Steps
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../upgrades/" class="md-nav__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M21 10.12h-6.78l2.74-2.82c-2.73-2.7-7.15-2.8-9.88-.1a6.887 6.887 0 0 0 0 9.8c2.73 2.7 7.15 2.7 9.88 0 1.36-1.35 2.04-2.92 2.04-4.9h2c0 1.98-.88 4.55-2.64 6.29-3.51 3.48-9.21 3.48-12.72 0-3.5-3.47-3.53-9.11-.02-12.58a8.987 8.987 0 0 1 12.65 0L21 3zM12.5 8v4.25l3.5 2.08-.72 1.21L11 13V8z"/></svg>
<span class="md-ellipsis">
Updates & Upgrades
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../control-panel/" class="md-nav__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 19V7H4v12zm0-16a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2zm-7 14v-2h5v2zm-3.42-4L5.57 9H8.4l3.3 3.3c.39.39.39 1.03 0 1.42L8.42 17H5.59z"/></svg>
<span class="md-ellipsis">
Control Panel (CCP)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../features/" class="md-nav__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m18.09 11.77 1.47 6.33L14 14.74 8.44 18.1l1.46-6.33L5 7.5l6.47-.54L14 1l2.53 5.96L23 7.5zM2 12.43c.19 0 .38-.06.55-.17l3.2-2.11-1.57-1.36-2.73 1.8c-.461.3-.589.91-.29 1.41.2.27.52.43.84.43m-.84 9.12c.2.29.52.45.84.45.19 0 .38-.05.55-.16l4.11-2.71.34-1.37.31-1.45-5.86 3.85c-.461.31-.589.93-.29 1.39m.29-6.17a1 1 0 0 0-.29 1.38c.2.3.52.45.84.45.19 0 .38-.05.55-.16l5.42-3.55.27-1.19-.92-.81z"/></svg>
<span class="md-ellipsis">
Features at a Glance
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../admin/" class="md-nav__link">
<span class="md-ellipsis">
Admin Guide
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../user-guide/" class="md-nav__link">
<span class="md-ellipsis">
User Guide
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../volunteer/" class="md-nav__link">
<span class="md-ellipsis">
Volunteer Guide
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../deployment/" class="md-nav__link">
<span class="md-ellipsis">
Deployment
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../architecture/" class="md-nav__link">
<span class="md-ellipsis">
Architecture
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../services/" class="md-nav__link">
<span class="md-ellipsis">
Services
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../api/" class="md-nav__link">
<span class="md-ellipsis">
API Reference
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../troubleshooting/" class="md-nav__link">
<span class="md-ellipsis">
Troubleshooting
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item">
<a href="../../phil/" class="md-nav__link">
<span class="md-ellipsis">
Philosophy
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../blog/" class="md-nav__link">
<span class="md-ellipsis">
Blog
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="On this page">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
On this page
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#prerequisites" class="md-nav__link">
<span class="md-ellipsis">
Prerequisites
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#quick-start" class="md-nav__link">
<span class="md-ellipsis">
Quick Start
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#configuration-wizard-configsh" class="md-nav__link">
<span class="md-ellipsis">
Configuration Wizard (config.sh)
</span>
</a>
<nav class="md-nav" aria-label="Configuration Wizard (config.sh)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#step-1-prerequisites-check" class="md-nav__link">
<span class="md-ellipsis">
Step 1: Prerequisites Check
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-2-environment-file-setup" class="md-nav__link">
<span class="md-ellipsis">
Step 2: Environment File Setup
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-3-domain-configuration" class="md-nav__link">
<span class="md-ellipsis">
Step 3: Domain Configuration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-4-admin-credentials" class="md-nav__link">
<span class="md-ellipsis">
Step 4: Admin Credentials
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-5-secret-generation" class="md-nav__link">
<span class="md-ellipsis">
Step 5: Secret Generation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-6-email-configuration" class="md-nav__link">
<span class="md-ellipsis">
Step 6: Email Configuration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-7-feature-flags" class="md-nav__link">
<span class="md-ellipsis">
Step 7: Feature Flags
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-8-tunnel-configuration-pangolin" class="md-nav__link">
<span class="md-ellipsis">
Step 8: Tunnel Configuration (Pangolin)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-9-cors-origins" class="md-nav__link">
<span class="md-ellipsis">
Step 9: CORS Origins
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-10-nginx-config-generation" class="md-nav__link">
<span class="md-ellipsis">
Step 10: Nginx Config Generation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-11-homepage-services-yaml" class="md-nav__link">
<span class="md-ellipsis">
Step 11: Homepage Services YAML
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-12-container-directory-permissions" class="md-nav__link">
<span class="md-ellipsis">
Step 12: Container Directory Permissions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-13-upgrade-watcher-optional" class="md-nav__link">
<span class="md-ellipsis">
Step 13: Upgrade Watcher (Optional)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#step-14-summary-next-steps" class="md-nav__link">
<span class="md-ellipsis">
Step 14: Summary &amp; Next Steps
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#what-gets-modified" class="md-nav__link">
<span class="md-ellipsis">
What Gets Modified
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#manual-setup-alternative" class="md-nav__link">
<span class="md-ellipsis">
Manual Setup (Alternative)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#full-stack-startup" class="md-nav__link">
<span class="md-ellipsis">
Full Stack Startup
</span>
</a>
<nav class="md-nav" aria-label="Full Stack Startup">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#include-monitoring" class="md-nav__link">
<span class="md-ellipsis">
Include Monitoring
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#start-only-core-services" class="md-nav__link">
<span class="md-ellipsis">
Start Only Core Services
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#verifying-installation" class="md-nav__link">
<span class="md-ellipsis">
Verifying Installation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#next-steps" class="md-nav__link">
<span class="md-ellipsis">
Next Steps
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<nav class="md-path" aria-label="Navigation" >
<ol class="md-path__list">
<li class="md-path__item">
<a href="../../.." class="md-path__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-path__item">
<a href="../../" class="md-path__link">
<span class="md-ellipsis">
Docs
</span>
</a>
</li>
<li class="md-path__item">
<a href="../" class="md-path__link">
<span class="md-ellipsis">
Getting Started
</span>
</a>
</li>
</ol>
</nav>
<article class="md-content__inner md-typeset">
<a href="https://gitea.bnkops.com/admin/changemaker.lite/src/branch/main/mkdocs/docs/docs/getting-started/installation.md" title="Edit this page" class="md-content__button md-icon" rel="edit">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 20H6V4h7v5h5v3.1l2-2V8l-6-6H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h4zm10.2-7c.1 0 .3.1.4.2l1.3 1.3c.2.2.2.6 0 .8l-1 1-2.1-2.1 1-1c.1-.1.2-.2.4-.2m0 3.9L14.1 23H12v-2.1l6.1-6.1z"/></svg>
</a>
<a href="https://gitea.bnkops.com/admin/changemaker.lite/src/branch/main/mkdocs/docs/docs/getting-started/installation.md" title="View source of this page" class="md-content__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 18c.56 0 1 .44 1 1s-.44 1-1 1-1-.44-1-1 .44-1 1-1m0-3c-2.73 0-5.06 1.66-6 4 .94 2.34 3.27 4 6 4s5.06-1.66 6-4c-.94-2.34-3.27-4-6-4m0 6.5a2.5 2.5 0 0 1-2.5-2.5 2.5 2.5 0 0 1 2.5-2.5 2.5 2.5 0 0 1 2.5 2.5 2.5 2.5 0 0 1-2.5 2.5M9.27 20H6V4h7v5h5v4.07c.7.08 1.36.25 2 .49V8l-6-6H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h4.5a8.2 8.2 0 0 1-1.23-2"/></svg>
</a>
<h1 id="installation">Installation<a class="headerlink" href="#installation" title="Permanent link">&para;</a></h1>
<p>Changemaker Lite runs as a set of Docker containers orchestrated by Docker Compose. The <code>config.sh</code> wizard handles all configuration — or you can set things up manually.</p>
<hr />
<h2 id="prerequisites">Prerequisites<a class="headerlink" href="#prerequisites" title="Permanent link">&para;</a></h2>
<ul>
<li><strong>Docker</strong> 24+ and <strong>Docker Compose</strong> v2</li>
<li><strong>OpenSSL</strong> (for secret generation)</li>
<li>A Linux server (Ubuntu 22.04+ recommended) or macOS for development</li>
<li>At least <strong>2 GB RAM</strong> for core services, <strong>4 GB</strong> for the full stack</li>
<li>A domain name (optional for development, recommended for production)</li>
</ul>
<hr />
<h2 id="quick-start">Quick Start<a class="headerlink" href="#quick-start" title="Permanent link">&para;</a></h2>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="c1"># Clone the repository</span>
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a>git<span class="w"> </span>clone<span class="w"> </span>https://gitea.bnkops.com/admin/changemaker.lite
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a><span class="nb">cd</span><span class="w"> </span>changemaker.lite
</span><span id="__span-0-4"><a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a>git<span class="w"> </span>checkout<span class="w"> </span>v2
</span><span id="__span-0-5"><a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a>
</span><span id="__span-0-6"><a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a><span class="c1"># Run the configuration wizard</span>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a>bash<span class="w"> </span>config.sh
</span><span id="__span-0-8"><a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a>
</span><span id="__span-0-9"><a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a><span class="c1"># Start all services</span>
</span><span id="__span-0-10"><a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a>docker<span class="w"> </span>compose<span class="w"> </span>up<span class="w"> </span>-d
</span></code></pre></div>
<p>Open <strong>http://localhost:3000</strong> and sign in with the admin credentials you configured. Database migrations and seeding run automatically on first startup.</p>
<div class="admonition warning">
<p class="admonition-title">Change your password</p>
<p>If you used the wizard's generated password, change it immediately from the admin dashboard.</p>
</div>
<hr />
<h2 id="configuration-wizard-configsh">Configuration Wizard (<code>config.sh</code>)<a class="headerlink" href="#configuration-wizard-configsh" title="Permanent link">&para;</a></h2>
<p>The wizard performs <strong>14 steps</strong> to produce a fully configured <code>.env</code> file and prepare the system for startup. Each step is interactive with sensible defaults.</p>
<h3 id="step-1-prerequisites-check">Step 1: Prerequisites Check<a class="headerlink" href="#step-1-prerequisites-check" title="Permanent link">&para;</a></h3>
<p>Verifies that Docker, Docker Compose v2, and OpenSSL are installed. Exits immediately if any are missing, with links to installation guides.</p>
<h3 id="step-2-environment-file-setup">Step 2: Environment File Setup<a class="headerlink" href="#step-2-environment-file-setup" title="Permanent link">&para;</a></h3>
<ul>
<li>If no <code>.env</code> exists, copies <code>.env.example</code> as the starting point</li>
<li>If <code>.env</code> already exists, offers to <strong>back it up</strong> (timestamped copy) and create a fresh one, or update values in place</li>
</ul>
<h3 id="step-3-domain-configuration">Step 3: Domain Configuration<a class="headerlink" href="#step-3-domain-configuration" title="Permanent link">&para;</a></h3>
<p>Prompts for your root domain (default: <code>cmlite.org</code>) and derives <strong>14 environment variables</strong> from it:</p>
<table>
<thead>
<tr>
<th>Variable</th>
<th>Example Value</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>DOMAIN</code></td>
<td><code>example.org</code></td>
</tr>
<tr>
<td><code>BASE_DOMAIN</code></td>
<td><code>https://example.org</code></td>
</tr>
<tr>
<td><code>GITEA_ROOT_URL</code></td>
<td><code>https://git.example.org</code></td>
</tr>
<tr>
<td><code>GITEA_DOMAIN</code></td>
<td><code>git.example.org</code></td>
</tr>
<tr>
<td><code>N8N_HOST</code></td>
<td><code>n8n.example.org</code></td>
</tr>
<tr>
<td><code>SMTP_FROM</code></td>
<td><code>noreply@example.org</code></td>
</tr>
<tr>
<td><code>INITIAL_ADMIN_EMAIL</code></td>
<td><code>admin@example.org</code></td>
</tr>
<tr>
<td><code>NC_ADMIN_EMAIL</code></td>
<td><code>admin@example.org</code></td>
</tr>
<tr>
<td><code>EXCALIDRAW_WS_URL</code></td>
<td><code>wss://draw.example.org</code></td>
</tr>
<tr>
<td><code>LISTMONK_SMTP_FROM</code></td>
<td><code>Changemaker Lite &lt;noreply@example.org&gt;</code></td>
</tr>
<tr>
<td><code>HOMEPAGE_VAR_BASE_URL</code></td>
<td><code>https://example.org</code></td>
</tr>
<tr>
<td><code>VAULTWARDEN_DOMAIN</code></td>
<td><code>https://vault.example.org</code></td>
</tr>
<tr>
<td><code>GANCIO_BASE_URL</code></td>
<td><code>https://events.example.org</code></td>
</tr>
<tr>
<td><code>TEST_EMAIL_RECIPIENT</code></td>
<td><code>admin@example.org</code></td>
</tr>
</tbody>
</table>
<p>Also updates <code>mkdocs/mkdocs.yml</code> with the new <code>site_url</code> and <code>repo_url</code>, and asks whether this is a <strong>production deployment</strong> (sets <code>NODE_ENV=production</code>).</p>
<h3 id="step-4-admin-credentials">Step 4: Admin Credentials<a class="headerlink" href="#step-4-admin-credentials" title="Permanent link">&para;</a></h3>
<p>Prompts for the initial super-admin email and password. The password is validated against the security policy:</p>
<ul>
<li>Minimum <strong>12 characters</strong></li>
<li>At least one <strong>uppercase</strong> letter</li>
<li>At least one <strong>lowercase</strong> letter</li>
<li>At least one <strong>digit</strong></li>
<li>Requires password confirmation</li>
</ul>
<h3 id="step-5-secret-generation">Step 5: Secret Generation<a class="headerlink" href="#step-5-secret-generation" title="Permanent link">&para;</a></h3>
<p>Auto-generates <strong>21 unique secrets</strong> — no placeholder passwords remain after this step:</p>
<table>
<thead>
<tr>
<th>Category</th>
<th>Count</th>
<th>Secrets</th>
</tr>
</thead>
<tbody>
<tr>
<td>JWT &amp; Encryption</td>
<td>3</td>
<td><code>JWT_ACCESS_SECRET</code>, <code>JWT_REFRESH_SECRET</code>, <code>ENCRYPTION_KEY</code> (64-char hex)</td>
</tr>
<tr>
<td>Database</td>
<td>2</td>
<td><code>V2_POSTGRES_PASSWORD</code>, <code>REDIS_PASSWORD</code> (24-char alphanumeric)</td>
</tr>
<tr>
<td>Listmonk</td>
<td>3</td>
<td><code>LISTMONK_DB_PASSWORD</code>, <code>LISTMONK_WEB_ADMIN_PASSWORD</code>, <code>LISTMONK_API_TOKEN</code></td>
</tr>
<tr>
<td>NocoDB</td>
<td>1</td>
<td><code>NC_ADMIN_PASSWORD</code></td>
</tr>
<tr>
<td>Gitea</td>
<td>2</td>
<td><code>GITEA_DB_PASSWD</code>, <code>GITEA_DB_ROOT_PASSWORD</code></td>
</tr>
<tr>
<td>n8n</td>
<td>2</td>
<td><code>N8N_ENCRYPTION_KEY</code>, <code>N8N_USER_PASSWORD</code></td>
</tr>
<tr>
<td>Monitoring</td>
<td>2</td>
<td><code>GRAFANA_ADMIN_PASSWORD</code>, <code>GOTIFY_ADMIN_PASSWORD</code></td>
</tr>
<tr>
<td>Vaultwarden</td>
<td>1</td>
<td><code>VAULTWARDEN_ADMIN_TOKEN</code> (64-char hex)</td>
</tr>
<tr>
<td>Rocket.Chat</td>
<td>1</td>
<td><code>ROCKETCHAT_ADMIN_PASSWORD</code></td>
</tr>
<tr>
<td>Gancio</td>
<td>1</td>
<td><code>GANCIO_ADMIN_PASSWORD</code></td>
</tr>
<tr>
<td>Jitsi Meet</td>
<td>3</td>
<td><code>JITSI_APP_SECRET</code> (64-char hex), <code>JITSI_JICOFO_AUTH_PASSWORD</code>, <code>JITSI_JVB_AUTH_PASSWORD</code></td>
</tr>
</tbody>
</table>
<h3 id="step-6-email-configuration">Step 6: Email Configuration<a class="headerlink" href="#step-6-email-configuration" title="Permanent link">&para;</a></h3>
<p>Choose between:</p>
<ul>
<li><strong>MailHog</strong> (default) — captures all outgoing emails at <code>http://localhost:8025</code> for development</li>
<li><strong>Production SMTP</strong> — configures host, port, user, and password. Optionally shares credentials with Listmonk for newsletter delivery</li>
</ul>
<h3 id="step-7-feature-flags">Step 7: Feature Flags<a class="headerlink" href="#step-7-feature-flags" title="Permanent link">&para;</a></h3>
<p>Enable or disable 9 optional platform features:</p>
<table>
<thead>
<tr>
<th>Flag</th>
<th>Environment Variable</th>
<th>What It Enables</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Media Manager</strong></td>
<td><code>ENABLE_MEDIA_FEATURES=true</code></td>
<td>Video library, analytics, scheduled publishing</td>
</tr>
<tr>
<td><strong>Listmonk Sync</strong></td>
<td><code>LISTMONK_SYNC_ENABLED=true</code></td>
<td>Newsletter subscriber sync from platform participants</td>
</tr>
<tr>
<td><strong>Payments</strong></td>
<td><code>ENABLE_PAYMENTS=true</code></td>
<td>Stripe-based products, donations, and plans</td>
</tr>
<tr>
<td><strong>Rocket.Chat</strong></td>
<td><code>ENABLE_CHAT=true</code></td>
<td>Team communication platform</td>
</tr>
<tr>
<td><strong>Gancio Events</strong></td>
<td><code>GANCIO_SYNC_ENABLED=true</code></td>
<td>Shift-to-event sync with Gancio</td>
</tr>
<tr>
<td><strong>Jitsi Meet</strong></td>
<td><code>ENABLE_MEET=true</code></td>
<td>Video conferencing (also prompts for server public IP)</td>
</tr>
<tr>
<td><strong>SMS Campaigns</strong></td>
<td><code>ENABLE_SMS=true</code></td>
<td>Termux Android bridge for SMS (also prompts for API URL)</td>
</tr>
<tr>
<td><strong>Docs Comments</strong></td>
<td><code>GITEA_COMMENTS_ENABLED=true</code></td>
<td>Gitea-backed page comments on documentation</td>
</tr>
<tr>
<td><strong>Bunker Ops</strong></td>
<td><code>BUNKER_OPS_ENABLED=true</code></td>
<td>Fleet metrics push to central server (also prompts for remote write URL)</td>
</tr>
</tbody>
</table>
<h3 id="step-8-tunnel-configuration-pangolin">Step 8: Tunnel Configuration (Pangolin)<a class="headerlink" href="#step-8-tunnel-configuration-pangolin" title="Permanent link">&para;</a></h3>
<p>Optionally configures Pangolin tunnel credentials for secure public access:</p>
<ul>
<li><code>PANGOLIN_API_URL</code> — API endpoint (default: <code>https://api.bnkserve.org/v1</code>)</li>
<li><code>PANGOLIN_API_KEY</code> — Authentication key</li>
<li><code>PANGOLIN_ORG_ID</code> — Organization identifier</li>
</ul>
<p>Complete tunnel setup is done from the admin GUI at <strong>Settings &gt; Tunnel</strong> after services are running.</p>
<h3 id="step-9-cors-origins">Step 9: CORS Origins<a class="headerlink" href="#step-9-cors-origins" title="Permanent link">&para;</a></h3>
<p>Automatically calculates allowed origins from your domain:</p>
<div class="language-text highlight"><pre><span></span><code><span id="__span-1-1"><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a>http://app.DOMAIN,https://app.DOMAIN,http://DOMAIN,https://DOMAIN,http://localhost:3000,http://localhost,http://localhost:4003
</span></code></pre></div>
<h3 id="step-10-nginx-config-generation">Step 10: Nginx Config Generation<a class="headerlink" href="#step-10-nginx-config-generation" title="Permanent link">&para;</a></h3>
<p>Renders all <code>.conf.template</code> files in <code>nginx/conf.d/</code> by substituting <code>${DOMAIN}</code> with your configured domain. This produces the nginx configuration files that handle subdomain routing.</p>
<h3 id="step-11-homepage-services-yaml">Step 11: Homepage Services YAML<a class="headerlink" href="#step-11-homepage-services-yaml" title="Permanent link">&para;</a></h3>
<p>Generates <code>configs/homepage/services.yaml</code> with <strong>27 service entries</strong> (both production and local development URLs) for the Homepage service dashboard.</p>
<h3 id="step-12-container-directory-permissions">Step 12: Container Directory Permissions<a class="headerlink" href="#step-12-container-directory-permissions" title="Permanent link">&para;</a></h3>
<p>Creates and sets permissions (775) on <strong>12 directories</strong> needed by containers:</p>
<table>
<thead>
<tr>
<th>Directory</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>configs/code-server/.config</code></td>
<td>Code Server configuration</td>
</tr>
<tr>
<td><code>configs/code-server/.local</code></td>
<td>Code Server local data</td>
</tr>
<tr>
<td><code>mkdocs/.cache</code></td>
<td>MkDocs build cache</td>
</tr>
<tr>
<td><code>mkdocs/site</code></td>
<td>MkDocs built site output</td>
</tr>
<tr>
<td><code>assets/uploads</code></td>
<td>Listmonk uploads</td>
</tr>
<tr>
<td><code>assets/images</code></td>
<td>Shared images</td>
</tr>
<tr>
<td><code>assets/icons</code></td>
<td>Homepage icons</td>
</tr>
<tr>
<td><code>media/local/inbox</code></td>
<td>Media upload inbox</td>
</tr>
<tr>
<td><code>media/local/thumbnails</code></td>
<td>Video thumbnails</td>
</tr>
<tr>
<td><code>media/public</code></td>
<td>Public media files</td>
</tr>
<tr>
<td><code>local-files</code></td>
<td>n8n local files</td>
</tr>
<tr>
<td><code>data</code></td>
<td>NAR import data</td>
</tr>
</tbody>
</table>
<h3 id="step-13-upgrade-watcher-optional">Step 13: Upgrade Watcher (Optional)<a class="headerlink" href="#step-13-upgrade-watcher-optional" title="Permanent link">&para;</a></h3>
<p>Installs a <strong>systemd path watcher</strong> that enables the admin GUI's "Check for Updates" and "Start Upgrade" buttons. This step requires <code>sudo</code> and is optional — you can install it later or use the CLI upgrade script directly.</p>
<p>The watcher installs two systemd units:</p>
<ul>
<li><code>changemaker-upgrade.path</code> — watches for <code>data/upgrade/trigger.json</code></li>
<li><code>changemaker-upgrade.service</code> — runs <code>scripts/upgrade-watcher.sh</code> when triggered</li>
</ul>
<h3 id="step-14-summary-next-steps">Step 14: Summary &amp; Next Steps<a class="headerlink" href="#step-14-summary-next-steps" title="Permanent link">&para;</a></h3>
<p>Displays a configuration summary showing all choices made, then prints startup commands.</p>
<hr />
<h2 id="what-gets-modified">What Gets Modified<a class="headerlink" href="#what-gets-modified" title="Permanent link">&para;</a></h2>
<p>After the wizard completes, the following files have been created or modified:</p>
<table>
<thead>
<tr>
<th>File</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>.env</code></td>
<td>Created (or updated) with all configuration values</td>
</tr>
<tr>
<td><code>mkdocs/mkdocs.yml</code></td>
<td>Updated <code>site_url</code> and <code>repo_url</code> with domain</td>
</tr>
<tr>
<td><code>nginx/conf.d/*.conf</code></td>
<td>Generated from <code>.conf.template</code> files</td>
</tr>
<tr>
<td><code>configs/homepage/services.yaml</code></td>
<td>Generated with all service URLs</td>
</tr>
<tr>
<td>12 directories</td>
<td>Created with container-friendly permissions</td>
</tr>
<tr>
<td>systemd units (optional)</td>
<td>Installed to <code>/etc/systemd/system/</code></td>
</tr>
</tbody>
</table>
<hr />
<h2 id="manual-setup-alternative">Manual Setup (Alternative)<a class="headerlink" href="#manual-setup-alternative" title="Permanent link">&para;</a></h2>
<p>If you prefer to configure by hand instead of using the wizard:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-2-1"><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a>cp<span class="w"> </span>.env.example<span class="w"> </span>.env
</span></code></pre></div>
<p>At minimum, set these required secrets:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-3-1"><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a><span class="c1"># Generate cryptographic secrets</span>
</span><span id="__span-3-2"><a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a><span class="nv">V2_POSTGRES_PASSWORD</span><span class="o">=</span><span class="k">$(</span>openssl<span class="w"> </span>rand<span class="w"> </span>-base64<span class="w"> </span><span class="m">48</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>tr<span class="w"> </span>-dc<span class="w"> </span><span class="s1">&#39;a-zA-Z0-9&#39;</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>head<span class="w"> </span>-c<span class="w"> </span><span class="m">24</span><span class="k">)</span>
</span><span id="__span-3-3"><a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a><span class="nv">REDIS_PASSWORD</span><span class="o">=</span><span class="k">$(</span>openssl<span class="w"> </span>rand<span class="w"> </span>-base64<span class="w"> </span><span class="m">48</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>tr<span class="w"> </span>-dc<span class="w"> </span><span class="s1">&#39;a-zA-Z0-9&#39;</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>head<span class="w"> </span>-c<span class="w"> </span><span class="m">24</span><span class="k">)</span>
</span><span id="__span-3-4"><a id="__codelineno-3-4" name="__codelineno-3-4" href="#__codelineno-3-4"></a><span class="nv">JWT_ACCESS_SECRET</span><span class="o">=</span><span class="k">$(</span>openssl<span class="w"> </span>rand<span class="w"> </span>-hex<span class="w"> </span><span class="m">32</span><span class="k">)</span>
</span><span id="__span-3-5"><a id="__codelineno-3-5" name="__codelineno-3-5" href="#__codelineno-3-5"></a><span class="nv">JWT_REFRESH_SECRET</span><span class="o">=</span><span class="k">$(</span>openssl<span class="w"> </span>rand<span class="w"> </span>-hex<span class="w"> </span><span class="m">32</span><span class="k">)</span>
</span><span id="__span-3-6"><a id="__codelineno-3-6" name="__codelineno-3-6" href="#__codelineno-3-6"></a><span class="nv">ENCRYPTION_KEY</span><span class="o">=</span><span class="k">$(</span>openssl<span class="w"> </span>rand<span class="w"> </span>-hex<span class="w"> </span><span class="m">32</span><span class="k">)</span>
</span></code></pre></div>
<p>Set your admin credentials (password must meet the 12+ char complexity requirement):</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-4-1"><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="nv">INITIAL_ADMIN_EMAIL</span><span class="o">=</span>admin@yourdomain.org
</span><span id="__span-4-2"><a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a><span class="nv">INITIAL_ADMIN_PASSWORD</span><span class="o">=</span>YourStrongPassword1
</span></code></pre></div>
<p>Then configure optional sections:</p>
<ul>
<li><strong>Domain</strong>: Set <code>DOMAIN</code> and all derived variables (see Step 3 table above)</li>
<li><strong>SMTP</strong>: Set <code>SMTP_HOST</code>, <code>SMTP_PORT</code>, <code>SMTP_USER</code>, <code>SMTP_PASS</code>, <code>EMAIL_TEST_MODE=false</code></li>
<li><strong>Feature flags</strong>: Enable features as needed (see Step 7 table above)</li>
<li><strong>Tunnel</strong>: Set <code>PANGOLIN_API_URL</code>, <code>PANGOLIN_API_KEY</code>, <code>PANGOLIN_ORG_ID</code></li>
</ul>
<p>See <a href="../environment-variables/">Environment Variables</a> for every available option.</p>
<hr />
<h2 id="full-stack-startup">Full Stack Startup<a class="headerlink" href="#full-stack-startup" title="Permanent link">&para;</a></h2>
<p>After configuration, start the entire platform:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-5-1"><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a>docker<span class="w"> </span>compose<span class="w"> </span>up<span class="w"> </span>-d
</span></code></pre></div>
<p>That's it. Docker handles the startup order automatically:</p>
<ol>
<li><strong>PostgreSQL</strong> and <strong>Redis</strong> start first (with healthchecks)</li>
<li><strong>API</strong> waits for both to be healthy, then auto-runs database migrations and seeding</li>
<li><strong>Admin GUI</strong> waits for the API</li>
<li><strong>Nginx</strong>, media, communication, and all other services start in parallel</li>
<li><strong>Init containers</strong> (nocodb-init, listmonk-init, etc.) run once and exit</li>
</ol>
<p>Watch the startup progress:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-6-1"><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a>docker<span class="w"> </span>compose<span class="w"> </span>logs<span class="w"> </span>-f<span class="w"> </span>api<span class="w"> </span>--tail<span class="w"> </span><span class="m">20</span>
</span></code></pre></div>
<p>Once you see <code>Starting server on port 4000</code>, open <strong>http://localhost:3000</strong> and log in.</p>
<h3 id="include-monitoring">Include Monitoring<a class="headerlink" href="#include-monitoring" title="Permanent link">&para;</a></h3>
<p>The monitoring stack (Prometheus, Grafana, Alertmanager) uses a Docker Compose profile and isn't included by default:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-7-1"><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a>docker<span class="w"> </span>compose<span class="w"> </span>--profile<span class="w"> </span>monitoring<span class="w"> </span>up<span class="w"> </span>-d
</span></code></pre></div>
<h3 id="start-only-core-services">Start Only Core Services<a class="headerlink" href="#start-only-core-services" title="Permanent link">&para;</a></h3>
<p>If you prefer a minimal startup (lower resource usage):</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-8-1"><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a>docker<span class="w"> </span>compose<span class="w"> </span>up<span class="w"> </span>-d<span class="w"> </span>v2-postgres<span class="w"> </span>redis<span class="w"> </span>api<span class="w"> </span>admin<span class="w"> </span>nginx
</span></code></pre></div>
<div class="admonition note">
<p class="admonition-title">Manual migrations</p>
<p>The API container runs migrations and seeding automatically on startup via its
entrypoint script. You only need to run them manually if you're developing
locally without Docker:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-9-1"><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="nb">cd</span><span class="w"> </span>api<span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span>npx<span class="w"> </span>prisma<span class="w"> </span>migrate<span class="w"> </span>deploy<span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span>npx<span class="w"> </span>prisma<span class="w"> </span>db<span class="w"> </span>seed
</span></code></pre></div>
</div>
<p>See <a href="../services/">Services Overview</a> for the complete service catalog.</p>
<hr />
<h2 id="verifying-installation">Verifying Installation<a class="headerlink" href="#verifying-installation" title="Permanent link">&para;</a></h2>
<p>After starting services, verify everything is healthy:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-10-1"><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="c1"># Check running containers</span>
</span><span id="__span-10-2"><a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a>docker<span class="w"> </span>compose<span class="w"> </span>ps
</span><span id="__span-10-3"><a id="__codelineno-10-3" name="__codelineno-10-3" href="#__codelineno-10-3"></a>
</span><span id="__span-10-4"><a id="__codelineno-10-4" name="__codelineno-10-4" href="#__codelineno-10-4"></a><span class="c1"># API health check</span>
</span><span id="__span-10-5"><a id="__codelineno-10-5" name="__codelineno-10-5" href="#__codelineno-10-5"></a>curl<span class="w"> </span>-s<span class="w"> </span>http://localhost:4000/api/health<span class="w"> </span><span class="p">|</span><span class="w"> </span>python3<span class="w"> </span>-m<span class="w"> </span>json.tool
</span><span id="__span-10-6"><a id="__codelineno-10-6" name="__codelineno-10-6" href="#__codelineno-10-6"></a>
</span><span id="__span-10-7"><a id="__codelineno-10-7" name="__codelineno-10-7" href="#__codelineno-10-7"></a><span class="c1"># View API logs</span>
</span><span id="__span-10-8"><a id="__codelineno-10-8" name="__codelineno-10-8" href="#__codelineno-10-8"></a>docker<span class="w"> </span>compose<span class="w"> </span>logs<span class="w"> </span>api<span class="w"> </span>--tail<span class="w"> </span><span class="m">20</span>
</span><span id="__span-10-9"><a id="__codelineno-10-9" name="__codelineno-10-9" href="#__codelineno-10-9"></a>
</span><span id="__span-10-10"><a id="__codelineno-10-10" name="__codelineno-10-10" href="#__codelineno-10-10"></a><span class="c1"># Check for containers in restart loops</span>
</span><span id="__span-10-11"><a id="__codelineno-10-11" name="__codelineno-10-11" href="#__codelineno-10-11"></a>docker<span class="w"> </span>compose<span class="w"> </span>ps<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>-i<span class="w"> </span>restarting
</span></code></pre></div>
<p>You should see the API return <code>{"status":"ok"}</code> and all started containers in a "running" state.</p>
<hr />
<h2 id="next-steps">Next Steps<a class="headerlink" href="#next-steps" title="Permanent link">&para;</a></h2>
<ul>
<li><a href="../services/">Services Overview</a> — complete service catalog with ports and startup commands</li>
<li><a href="../environment-variables/">Environment Variables</a> — complete <code>.env</code> reference</li>
<li><a href="../first-steps/">First Steps</a> — create your first campaign and add locations</li>
<li><a href="../upgrades/">Updates &amp; Upgrades</a> — keep your installation up to date</li>
</ul>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
Back to top
</button>
</main>
<footer class="md-footer">
<nav class="md-footer__inner md-grid" aria-label="Footer" >
<a href="../" class="md-footer__link md-footer__link--prev" aria-label="Previous: Getting Started">
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</div>
<div class="md-footer__title">
<span class="md-footer__direction">
Previous
</span>
<div class="md-ellipsis">
Getting Started
</div>
</div>
</a>
<a href="../services/" class="md-footer__link md-footer__link--next" aria-label="Next: Services Overview">
<div class="md-footer__title">
<span class="md-footer__direction">
Next
</span>
<div class="md-ellipsis">
Services Overview
</div>
</div>
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11z"/></svg>
</div>
</a>
</nav>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
<div class="md-copyright__highlight">
Copyright &copy; 2024 The Bunker Operations <a href="#__consent">Change cookie settings</a>
</div>
</div>
<div class="md-social">
<a href="https://gitea.bnkops.com/admin" target="_blank" rel="noopener" title="Gitea Repository" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
</a>
<a href="https://listmonk.bnkops.com/subscription/form" target="_blank" rel="noopener" title="Newsletter" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M536.4-26.3c9.8-3.5 20.6-1 28 6.3s9.8 18.2 6.3 28l-178 496.9c-5 13.9-18.1 23.1-32.8 23.1-14.2 0-27-8.6-32.3-21.7l-64.2-158c-4.5-11-2.5-23.6 5.2-32.6l94.5-112.4c5.1-6.1 4.7-15-.9-20.6s-14.6-6-20.6-.9l-112.4 94.3c-9.1 7.6-21.6 9.6-32.6 5.2L38.1 216.8c-13.1-5.3-21.7-18.1-21.7-32.3 0-14.7 9.2-27.8 23.1-32.8z"/></svg>
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"annotate": null, "base": "../../..", "features": ["announce.dismiss", "content.action.edit", "content.action.view", "content.code.annotate", "content.code.copy", "content.tooltips", "navigation.footer", "navigation.indexes", "navigation.path", "navigation.prune", "navigation.tabs", "navigation.tabs.sticky", "navigation.top", "navigation.tracking", "search.highlight", "search.share", "search.suggest", "toc.follow"], "search": "../../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../../../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../../../javascripts/home.js"></script>
<script src="../../../javascripts/github-widget.js"></script>
<script src="../../../javascripts/gitea-widget.js"></script>
<script src="../../../assets/js/env-config.js"></script>
<script src="../../../assets/js/video-player.js"></script>
<script src="../../../assets/js/image-gallery.js"></script>
<script src="../../../assets/js/gancio-events.js"></script>
<script src="../../../assets/js/payment-widgets.js"></script>
<script src="../../../assets/js/scheduling-poll.js"></script>
<script src="../../../javascripts/ad-widgets.js"></script>
<script src="../../../javascripts/docs-comments.js"></script>
</body>
</html>