From e9d5af3d248a5aae166f27f2cb4e75ad7a027270 Mon Sep 17 00:00:00 2001 From: admin Date: Fri, 4 Jul 2025 22:50:24 -0600 Subject: [PATCH] removed the cloudflare credentials and yml from up --- .gitignore | 4 +- configs/cloudflare/tunnel-config.yml | 32 +- configs/homepage/services.yaml | 16 +- mkdocs/docs/adv/vscode-ssh.md | 17 + .../repo-data/admin-changemaker.lite.json | 4 +- .../repo-data/anthropics-claude-code.json | 10 +- .../assets/repo-data/coder-code-server.json | 8 +- .../repo-data/gethomepage-homepage.json | 10 +- .../docs/assets/repo-data/go-gitea-gitea.json | 10 +- .../docs/assets/repo-data/knadh-listmonk.json | 8 +- .../docs/assets/repo-data/lyqht-mini-qr.json | 4 +- mkdocs/docs/assets/repo-data/n8n-io-n8n.json | 8 +- .../docs/assets/repo-data/nocodb-nocodb.json | 8 +- .../docs/assets/repo-data/ollama-ollama.json | 10 +- .../repo-data/squidfunk-mkdocs-material.json | 8 +- .../repo_widget_hook.cpython-311.pyc | Bin 0 -> 6952 bytes mkdocs/docs/overrides/main.html | 2 +- mkdocs/mkdocs.yml | 2 +- mkdocs/mkdocs.yml.backup_20250704_151429 | 183 +++++ mkdocs/site/adv/vscode-ssh/index.html | 190 +++-- mkdocs/site/assets/images/social/test.png | Bin 0 -> 24436 bytes .../repo-data/admin-changemaker.lite.json | 4 +- .../repo-data/anthropics-claude-code.json | 10 +- .../assets/repo-data/coder-code-server.json | 8 +- .../repo-data/gethomepage-homepage.json | 10 +- .../site/assets/repo-data/go-gitea-gitea.json | 10 +- .../site/assets/repo-data/knadh-listmonk.json | 8 +- .../site/assets/repo-data/lyqht-mini-qr.json | 4 +- mkdocs/site/assets/repo-data/n8n-io-n8n.json | 8 +- .../site/assets/repo-data/nocodb-nocodb.json | 8 +- .../site/assets/repo-data/ollama-ollama.json | 10 +- .../repo-data/squidfunk-mkdocs-material.json | 8 +- mkdocs/site/build/index.html | 11 + .../repo_widget_hook.cpython-311.pyc | Bin 6965 -> 6952 bytes mkdocs/site/phil/index.html | 4 +- mkdocs/site/search/search_index.json | 2 +- mkdocs/site/sitemap.xml | 62 +- mkdocs/site/sitemap.xml.gz | Bin 374 -> 378 bytes mkdocs/site/test/index.html | 744 ++++++++++++++++++ 39 files changed, 1220 insertions(+), 225 deletions(-) create mode 100644 mkdocs/docs/hooks/__pycache__/repo_widget_hook.cpython-311.pyc create mode 100644 mkdocs/mkdocs.yml.backup_20250704_151429 create mode 100644 mkdocs/site/assets/images/social/test.png create mode 100644 mkdocs/site/test/index.html diff --git a/.gitignore b/.gitignore index d401ab2..ccc905c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,6 @@ .env .env* -/configs/cloudflare/*.json \ No newline at end of file +/configs/cloudflare/*.json +/configs/cloudflare/*.yaml +/configs/cloudflare/*.yml \ No newline at end of file diff --git a/configs/cloudflare/tunnel-config.yml b/configs/cloudflare/tunnel-config.yml index aaa28b5..dcd556b 100644 --- a/configs/cloudflare/tunnel-config.yml +++ b/configs/cloudflare/tunnel-config.yml @@ -1,27 +1,27 @@ -# Cloudflare Tunnel Configuration for bnkserve.org -# Generated by Changemaker.lite start-production.sh on Thu 03 Jul 2025 07:24:57 AM MDT +# Cloudflare Tunnel Configuration for cmlite.org +# Generated by Changemaker.lite start-production.sh on Fri 04 Jul 2025 10:47:26 PM MDT -tunnel: 2fff7cb3-7dd8-407f-86fd-7a681c1e5630 -credentials-file: /home/bunker-mobile-lab/changemaker.lite/configs/cloudflare/2fff7cb3-7dd8-407f-86fd-7a681c1e5630.json +tunnel: 124583b0-85ef-41ab-b146-97112a4543de +credentials-file: /mnt/storagessd1tb/changemaker.lite.dev/changemaker.lite/configs/cloudflare/124583b0-85ef-41ab-b146-97112a4543de.json ingress: - - hostname: homepage.bnkserve.org + - hostname: homepage.cmlite.org service: http://localhost:3010 - - hostname: code.bnkserve.org + - hostname: code.cmlite.org service: http://localhost:8888 - - hostname: listmonk.bnkserve.org - service: http://localhost:9000 - - hostname: docs.bnkserve.org + - hostname: listmonk.cmlite.org + service: http://localhost:9001 + - hostname: docs.cmlite.org service: http://localhost:4000 - - hostname: bnkserve.org - service: http://localhost:4001 - - hostname: n8n.bnkserve.org + - hostname: cmlite.org + service: http://localhost:4002 + - hostname: n8n.cmlite.org service: http://localhost:5678 - - hostname: db.bnkserve.org + - hostname: db.cmlite.org service: http://localhost:8090 - - hostname: git.bnkserve.org + - hostname: git.cmlite.org service: http://localhost:3030 - - hostname: map.bnkserve.org + - hostname: map.cmlite.org service: http://localhost:3000 - - hostname: qr.bnkserve.org + - hostname: qr.cmlite.org service: http://localhost:8089 - service: http_status:404 diff --git a/configs/homepage/services.yaml b/configs/homepage/services.yaml index bf16bce..b7cb62c 100644 --- a/configs/homepage/services.yaml +++ b/configs/homepage/services.yaml @@ -5,25 +5,25 @@ - Code Server: icon: mdi-code-braces - href: "https://code.bnkserve.org" + href: "https://code.cmlite.org" description: VS Code in the browser - Platform Editor container: code-server-changemaker - Listmonk: icon: mdi-email-newsletter - href: "https://listmonk.bnkserve.org" + href: "https://listmonk.cmlite.org" description: Newsletter & mailing list manager container: listmonk_app - NocoDB: icon: mdi-database - href: "https://db.bnkserve.org" + href: "https://db.cmlite.org" description: No-code database platform container: changemakerlite-nocodb-1 - Map Server: icon: mdi-map - href: "https://map.bnkserve.org" + href: "https://map.cmlite.org" description: Map server for geospatial data container: nocodb-map-viewer @@ -37,13 +37,13 @@ - MkDocs (Live): icon: mdi-book-open-page-variant - href: "https://docs.bnkserve.org" + href: "https://docs.cmlite.org" description: Live documentation server with hot reload container: mkdocs-changemaker - Mini QR: icon: mdi-qrcode - href: "https://qr.bnkserve.org" + href: "https://qr.cmlite.org" description: QR code generator container: mini-qr @@ -51,7 +51,7 @@ - Automation & Infrastructure: - n8n: icon: mdi-robot-industrial - href: "https://n8n.bnkserve.org" + href: "https://n8n.cmlite.org" description: Workflow automation platform container: n8n-changemaker @@ -69,6 +69,6 @@ - Gitea: icon: mdi-git - href: "https://git.bnkserve.org" + href: "https://git.cmlite.org" description: Git repository hosting container: gitea_changemaker \ No newline at end of file diff --git a/mkdocs/docs/adv/vscode-ssh.md b/mkdocs/docs/adv/vscode-ssh.md index 3a78e2d..836bb0f 100644 --- a/mkdocs/docs/adv/vscode-ssh.md +++ b/mkdocs/docs/adv/vscode-ssh.md @@ -39,24 +39,28 @@ code --version ### 1. Install the Remote Development Extensions **Option A: Install Remote Development Pack (Recommended)** + 1. Open VSCode 2. Press **Ctrl+Shift+X** (or **Cmd+Shift+X** on Mac) 3. Search for **"Remote Development"** 4. Install the **Remote Development extension pack** by Microsoft This pack includes: + - Remote - SSH - Remote - SSH: Editing Configuration Files - Remote - Containers - Remote - WSL (Windows only) **Option B: Install Individual Extension** + 1. Search for **"Remote - SSH"** 2. Install **Remote - SSH** by Microsoft ### 2. Verify Installation After installation, the following should be visible: + - Remote Explorer icon in the Activity Bar (left sidebar) - "Remote-SSH" commands in Command Palette (Ctrl+Shift+P) @@ -65,6 +69,7 @@ After installation, the following should be visible: ### 1. Access SSH Configuration **Method A: Through VSCode** + 1. Press **Ctrl+Shift+P** to open Command Palette 2. Type **"Remote-SSH: Open SSH Configuration File..."** 3. Select the SSH config file (usually the first option) @@ -100,6 +105,7 @@ Host node2 ``` **Configuration Options Explained:** + - `Host`: Friendly name for the connection - `HostName`: Tailscale IP address - `User`: Username on the remote server @@ -143,6 +149,7 @@ chmod 644 ~/.ssh/id_rsa.pub ### 4. First Connection Process On first connection, VSCode will: + 1. **Verify the host key** (click "Continue" if prompted) 2. **Install VSCode Server** on the remote machine (automatic) 3. **Open a remote window** with access to the remote file system @@ -174,6 +181,7 @@ code /opt/myproject Extensions must be installed separately on the remote server: **Essential Development Extensions:** + 1. **Python** (Microsoft) - Python development 2. **GitLens** (GitKraken) - Enhanced Git capabilities 3. **Docker** (Microsoft) - Container development @@ -182,6 +190,7 @@ Extensions must be installed separately on the remote server: 6. **Auto Rename Tag** - HTML/XML tag editing **To Install:** + 1. Go to Extensions (Ctrl+Shift+X) 2. Find the desired extension 3. Click **"Install in SSH: node1"** (not local install) @@ -202,6 +211,7 @@ git clone https://github.com//.git ### 1. File Management **File Explorer:** + - Shows remote server's file system - Create, edit, delete files directly - Drag and drop between local and remote (limited) @@ -218,6 +228,7 @@ scp @:/remote/path/file.txt ./local/path/ ### 2. Terminal Usage **Integrated Terminal:** + - Press **Ctrl+`** to open terminal - Runs directly on remote server - Multiple terminals supported @@ -245,6 +256,7 @@ sudo docker-compose up -d VSCode automatically detects and forwards common development ports. **Manual Port Forwarding:** + 1. Open **Ports** tab in terminal panel 2. Click **"Forward a Port"** 3. Enter port number (e.g., 3000, 8080, 5000) @@ -316,11 +328,13 @@ Create remote-specific settings: ### 2. Multi-Server Management **Switch Between Servers:** + 1. Click remote indicator (bottom-left) 2. Select **"Connect to Host..."** 3. Choose a different server **Compare Files Across Servers:** + 1. Open file from server A 2. Connect to server B in new window 3. Open corresponding file @@ -329,6 +343,7 @@ Create remote-specific settings: ### 3. Sync Configuration **Settings Sync:** + 1. Enable Settings Sync in VSCode 2. Settings, extensions, and keybindings sync to remote 3. Consistent experience across all servers @@ -394,6 +409,7 @@ EOF ``` **VSCode Docker Integration:** + - Install Docker extension on remote - Right-click Dockerfile → "Build Image" - Manage containers from VSCode interface @@ -450,6 +466,7 @@ ssh-keygen -R **Problem: Extensions not working on remote** **Solutions:** + 1. Install extensions specifically for the remote server 2. Check extension compatibility with remote development 3. Reload VSCode window: Ctrl+Shift+P → "Developer: Reload Window" diff --git a/mkdocs/docs/assets/repo-data/admin-changemaker.lite.json b/mkdocs/docs/assets/repo-data/admin-changemaker.lite.json index 1c59173..890a556 100644 --- a/mkdocs/docs/assets/repo-data/admin-changemaker.lite.json +++ b/mkdocs/docs/assets/repo-data/admin-changemaker.lite.json @@ -7,10 +7,10 @@ "stars_count": 0, "forks_count": 0, "open_issues_count": 0, - "updated_at": "2025-07-02T11:49:44-06:00", + "updated_at": "2025-07-04T14:31:11-06:00", "created_at": "2025-05-28T14:54:59-06:00", "clone_url": "https://gitea.bnkops.com/admin/changemaker.lite.git", "ssh_url": "git@gitea.bnkops.com:admin/changemaker.lite.git", "default_branch": "main", - "last_build_update": "2025-07-02T11:49:44-06:00" + "last_build_update": "2025-07-04T14:31:11-06:00" } \ No newline at end of file diff --git a/mkdocs/docs/assets/repo-data/anthropics-claude-code.json b/mkdocs/docs/assets/repo-data/anthropics-claude-code.json index bd2f765..3cc5bfa 100644 --- a/mkdocs/docs/assets/repo-data/anthropics-claude-code.json +++ b/mkdocs/docs/assets/repo-data/anthropics-claude-code.json @@ -4,13 +4,13 @@ "description": "Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.", "html_url": "https://github.com/anthropics/claude-code", "language": "PowerShell", - "stars_count": 17031, - "forks_count": 941, - "open_issues_count": 1508, - "updated_at": "2025-07-03T05:19:19Z", + "stars_count": 17373, + "forks_count": 959, + "open_issues_count": 1578, + "updated_at": "2025-07-04T21:17:51Z", "created_at": "2025-02-22T17:41:21Z", "clone_url": "https://github.com/anthropics/claude-code.git", "ssh_url": "git@github.com:anthropics/claude-code.git", "default_branch": "main", - "last_build_update": "2025-07-03T03:54:14Z" + "last_build_update": "2025-07-03T21:09:58Z" } \ No newline at end of file diff --git a/mkdocs/docs/assets/repo-data/coder-code-server.json b/mkdocs/docs/assets/repo-data/coder-code-server.json index 3593dcf..af61bbe 100644 --- a/mkdocs/docs/assets/repo-data/coder-code-server.json +++ b/mkdocs/docs/assets/repo-data/coder-code-server.json @@ -4,10 +4,10 @@ "description": "VS Code in the browser", "html_url": "https://github.com/coder/code-server", "language": "TypeScript", - "stars_count": 72541, - "forks_count": 6067, - "open_issues_count": 141, - "updated_at": "2025-07-03T05:17:24Z", + "stars_count": 72668, + "forks_count": 6074, + "open_issues_count": 143, + "updated_at": "2025-07-04T18:33:06Z", "created_at": "2019-02-27T16:50:41Z", "clone_url": "https://github.com/coder/code-server.git", "ssh_url": "git@github.com:coder/code-server.git", diff --git a/mkdocs/docs/assets/repo-data/gethomepage-homepage.json b/mkdocs/docs/assets/repo-data/gethomepage-homepage.json index 70b9e60..5dd6dd4 100644 --- a/mkdocs/docs/assets/repo-data/gethomepage-homepage.json +++ b/mkdocs/docs/assets/repo-data/gethomepage-homepage.json @@ -4,13 +4,13 @@ "description": "A highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.", "html_url": "https://github.com/gethomepage/homepage", "language": "JavaScript", - "stars_count": 24619, - "forks_count": 1520, - "open_issues_count": 1, - "updated_at": "2025-07-03T03:29:15Z", + "stars_count": 24643, + "forks_count": 1522, + "open_issues_count": 2, + "updated_at": "2025-07-04T19:49:50Z", "created_at": "2022-08-24T07:29:42Z", "clone_url": "https://github.com/gethomepage/homepage.git", "ssh_url": "git@github.com:gethomepage/homepage.git", "default_branch": "dev", - "last_build_update": "2025-07-03T00:36:38Z" + "last_build_update": "2025-07-04T12:13:48Z" } \ No newline at end of file diff --git a/mkdocs/docs/assets/repo-data/go-gitea-gitea.json b/mkdocs/docs/assets/repo-data/go-gitea-gitea.json index a4e28c6..92fb96f 100644 --- a/mkdocs/docs/assets/repo-data/go-gitea-gitea.json +++ b/mkdocs/docs/assets/repo-data/go-gitea-gitea.json @@ -4,13 +4,13 @@ "description": "Git with a cup of tea! Painless self-hosted all-in-one software development service, including Git hosting, code review, team collaboration, package registry and CI/CD", "html_url": "https://github.com/go-gitea/gitea", "language": "Go", - "stars_count": 49349, - "forks_count": 5892, - "open_issues_count": 2702, - "updated_at": "2025-07-03T03:52:23Z", + "stars_count": 49370, + "forks_count": 5897, + "open_issues_count": 2711, + "updated_at": "2025-07-04T20:42:00Z", "created_at": "2016-11-01T02:13:26Z", "clone_url": "https://github.com/go-gitea/gitea.git", "ssh_url": "git@github.com:go-gitea/gitea.git", "default_branch": "main", - "last_build_update": "2025-07-03T03:02:38Z" + "last_build_update": "2025-07-04T15:41:19Z" } \ No newline at end of file diff --git a/mkdocs/docs/assets/repo-data/knadh-listmonk.json b/mkdocs/docs/assets/repo-data/knadh-listmonk.json index 8b473b8..ddb5784 100644 --- a/mkdocs/docs/assets/repo-data/knadh-listmonk.json +++ b/mkdocs/docs/assets/repo-data/knadh-listmonk.json @@ -4,10 +4,10 @@ "description": "High performance, self-hosted, newsletter and mailing list manager with a modern dashboard. Single binary app.", "html_url": "https://github.com/knadh/listmonk", "language": "Go", - "stars_count": 17250, - "forks_count": 1658, - "open_issues_count": 101, - "updated_at": "2025-07-03T01:26:41Z", + "stars_count": 17261, + "forks_count": 1659, + "open_issues_count": 103, + "updated_at": "2025-07-04T18:22:09Z", "created_at": "2019-06-26T05:08:39Z", "clone_url": "https://github.com/knadh/listmonk.git", "ssh_url": "git@github.com:knadh/listmonk.git", diff --git a/mkdocs/docs/assets/repo-data/lyqht-mini-qr.json b/mkdocs/docs/assets/repo-data/lyqht-mini-qr.json index 2b77d76..1d9ac9f 100644 --- a/mkdocs/docs/assets/repo-data/lyqht-mini-qr.json +++ b/mkdocs/docs/assets/repo-data/lyqht-mini-qr.json @@ -4,10 +4,10 @@ "description": "Create & scan cute qr codes easily \ud83d\udc7e", "html_url": "https://github.com/lyqht/mini-qr", "language": "Vue", - "stars_count": 1254, + "stars_count": 1258, "forks_count": 164, "open_issues_count": 13, - "updated_at": "2025-07-01T14:06:12Z", + "updated_at": "2025-07-04T21:12:26Z", "created_at": "2023-04-21T14:20:14Z", "clone_url": "https://github.com/lyqht/mini-qr.git", "ssh_url": "git@github.com:lyqht/mini-qr.git", diff --git a/mkdocs/docs/assets/repo-data/n8n-io-n8n.json b/mkdocs/docs/assets/repo-data/n8n-io-n8n.json index fb176f8..2a5008f 100644 --- a/mkdocs/docs/assets/repo-data/n8n-io-n8n.json +++ b/mkdocs/docs/assets/repo-data/n8n-io-n8n.json @@ -4,13 +4,13 @@ "description": "Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.", "html_url": "https://github.com/n8n-io/n8n", "language": "TypeScript", - "stars_count": 114419, - "forks_count": 33630, + "stars_count": 114980, + "forks_count": 33907, "open_issues_count": 1074, - "updated_at": "2025-07-03T05:21:36Z", + "updated_at": "2025-07-04T21:26:25Z", "created_at": "2019-06-22T09:24:21Z", "clone_url": "https://github.com/n8n-io/n8n.git", "ssh_url": "git@github.com:n8n-io/n8n.git", "default_branch": "master", - "last_build_update": "2025-07-03T04:31:44Z" + "last_build_update": "2025-07-04T18:53:03Z" } \ No newline at end of file diff --git a/mkdocs/docs/assets/repo-data/nocodb-nocodb.json b/mkdocs/docs/assets/repo-data/nocodb-nocodb.json index 166acf1..e9b250c 100644 --- a/mkdocs/docs/assets/repo-data/nocodb-nocodb.json +++ b/mkdocs/docs/assets/repo-data/nocodb-nocodb.json @@ -4,13 +4,13 @@ "description": "\ud83d\udd25 \ud83d\udd25 \ud83d\udd25 Open Source Airtable Alternative", "html_url": "https://github.com/nocodb/nocodb", "language": "TypeScript", - "stars_count": 55514, - "forks_count": 3994, + "stars_count": 55535, + "forks_count": 3997, "open_issues_count": 718, - "updated_at": "2025-07-03T04:26:22Z", + "updated_at": "2025-07-04T20:56:30Z", "created_at": "2017-10-29T18:51:48Z", "clone_url": "https://github.com/nocodb/nocodb.git", "ssh_url": "git@github.com:nocodb/nocodb.git", "default_branch": "develop", - "last_build_update": "2025-07-03T04:39:20Z" + "last_build_update": "2025-07-04T18:37:18Z" } \ No newline at end of file diff --git a/mkdocs/docs/assets/repo-data/ollama-ollama.json b/mkdocs/docs/assets/repo-data/ollama-ollama.json index b9bb106..da5ee56 100644 --- a/mkdocs/docs/assets/repo-data/ollama-ollama.json +++ b/mkdocs/docs/assets/repo-data/ollama-ollama.json @@ -4,13 +4,13 @@ "description": "Get up and running with Llama 3.3, DeepSeek-R1, Phi-4, Gemma 3, Mistral Small 3.1 and other large language models.", "html_url": "https://github.com/ollama/ollama", "language": "Go", - "stars_count": 145379, - "forks_count": 12279, - "open_issues_count": 1903, - "updated_at": "2025-07-03T05:22:04Z", + "stars_count": 145579, + "forks_count": 12297, + "open_issues_count": 1881, + "updated_at": "2025-07-04T20:55:45Z", "created_at": "2023-06-26T19:39:32Z", "clone_url": "https://github.com/ollama/ollama.git", "ssh_url": "git@github.com:ollama/ollama.git", "default_branch": "main", - "last_build_update": "2025-07-02T23:38:37Z" + "last_build_update": "2025-07-04T05:42:44Z" } \ No newline at end of file diff --git a/mkdocs/docs/assets/repo-data/squidfunk-mkdocs-material.json b/mkdocs/docs/assets/repo-data/squidfunk-mkdocs-material.json index 95a27d9..6639296 100644 --- a/mkdocs/docs/assets/repo-data/squidfunk-mkdocs-material.json +++ b/mkdocs/docs/assets/repo-data/squidfunk-mkdocs-material.json @@ -4,10 +4,10 @@ "description": "Documentation that simply works", "html_url": "https://github.com/squidfunk/mkdocs-material", "language": "Python", - "stars_count": 23786, - "forks_count": 3787, - "open_issues_count": 5, - "updated_at": "2025-07-03T00:57:11Z", + "stars_count": 23801, + "forks_count": 3792, + "open_issues_count": 6, + "updated_at": "2025-07-04T20:37:34Z", "created_at": "2016-01-28T22:09:23Z", "clone_url": "https://github.com/squidfunk/mkdocs-material.git", "ssh_url": "git@github.com:squidfunk/mkdocs-material.git", diff --git a/mkdocs/docs/hooks/__pycache__/repo_widget_hook.cpython-311.pyc b/mkdocs/docs/hooks/__pycache__/repo_widget_hook.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fc15fbaed2b84eb8b01cbdde993068971e8da501 GIT binary patch literal 6952 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 + Changemaker Archive. Learn more {% endblock %} diff --git a/mkdocs/mkdocs.yml b/mkdocs/mkdocs.yml index a45ff65..ee09f40 100644 --- a/mkdocs/mkdocs.yml +++ b/mkdocs/mkdocs.yml @@ -1,6 +1,6 @@ site_name: Changemaker Lite site_description: Build Power. Not Rent It. Own your digital infrastructure. -site_url: https://bnkserve.org +site_url: https://cmlite.org site_author: Bunker Operations docs_dir: docs site_dir: site diff --git a/mkdocs/mkdocs.yml.backup_20250704_151429 b/mkdocs/mkdocs.yml.backup_20250704_151429 new file mode 100644 index 0000000..a45ff65 --- /dev/null +++ b/mkdocs/mkdocs.yml.backup_20250704_151429 @@ -0,0 +1,183 @@ +site_name: Changemaker Lite +site_description: Build Power. Not Rent It. Own your digital infrastructure. +site_url: https://bnkserve.org +site_author: Bunker Operations +docs_dir: docs +site_dir: site + +# Repository +repo_url: https://gitea.bnkops.com/admin/changemaker.lite +repo_name: changemaker.lite +edit_uri: "" + +# Theme +theme: + name: material + custom_dir: docs/overrides + logo: assets/logo.png # Commented out until logo exists + favicon: assets/favicon.png # Commented out until favicon exists + palette: + - scheme: slate + primary: deep purple + accent: amber + toggle: + icon: material/weather-night + name: Switch to light mode + - scheme: default + primary: deep purple + accent: amber + toggle: + icon: material/weather-sunny + name: Switch to dark mode + font: + text: Inter + code: JetBrains Mono + features: + - announce.dismiss + - content.action.edit + - content.action.view + - content.code.annotate + - content.code.copy + - content.tooltips + - navigation.expand + - navigation.footer + - navigation.indexes + - navigation.instant + - navigation.instant.prefetch + - navigation.instant.progress + - navigation.path + - navigation.prune + - navigation.sections + - navigation.tabs + - navigation.tabs.sticky + - navigation.top + - navigation.tracking + - search.highlight + - search.share + - search.suggest + - toc.follow + +# Plugins +plugins: + - search: + separator: '[\s\u200b\-_,:!=\[\]()"`/]+|\.(?!\d)|&[lg]t;|(?!\b)(?=[A-Z][a-z])' + - social: + cards_layout_options: + background_color: "#5BCEFA" + color: "#FFFFFF" + - blog: + blog_dir: blog + post_date_format: medium + archive_name: Archive + categories_name: Categories + - tags + +# Extra CSS and JS +extra_css: + - stylesheets/extra.css + - stylesheets/home.css + +extra_javascript: + - javascripts/home.js + - javascripts/github-widget.js + - javascripts/gitea-widget.js + +hooks: + - docs/hooks/repo_widget_hook.py + +# Markdown Extensions +markdown_extensions: + - abbr + - admonition + - attr_list + - def_list + - footnotes + - md_in_html + - toc: + permalink: true + title: On this page + - pymdownx.arithmatex: + generic: true + - pymdownx.betterem: + smart_enable: all + - pymdownx.caret + - pymdownx.details + - pymdownx.emoji: + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg + - pymdownx.highlight: + anchor_linenums: true + line_spans: __span + pygments_lang_class: true + - pymdownx.inlinehilite + - pymdownx.keys + - pymdownx.mark + - pymdownx.smartsymbols + - pymdownx.snippets + - pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format + - pymdownx.tabbed: + alternate_style: true + combine_header_slug: true + - pymdownx.tasklist: + custom_checkbox: true + - pymdownx.tilde + +# Extra configuration +extra: + generator: false + social: + - icon: fontawesome/brands/github + link: https://gitea.bnkops.com/admin + name: Gitea Repository + - icon: fontawesome/solid/paper-plane + link: https://listmonk.bnkops.com/subscription/form + name: Newsletter + +# Copyright +copyright: > + Copyright © 2024 The Bunker Operations – + Change cookie settings + +# Navigation - Updated to match existing files +nav: + - Home: index.md + - Philosophy: + - phil/index.md + - Who Reads Your Secrets: https://docs.bnkops.com/archive/repo.archive/thatreallyblondehuman/Thoughts%20%F0%9F%A4%94/If%20you%20do%20politics%20who%20is%20reading%20your%20secrets%20-%20why%20you%20should%20de-corp%20your%20software%20stack/ + - How To Not Get Got Making Content: https://docs.bnkops.com/archive/repo.archive/thatreallyblondehuman/Thoughts%20%F0%9F%A4%94/How%20not%20to%20get%20got%20making%20content%20v2/ + - Digital Organizing: https://docs.bnkops.com/archive/repo.archive/thatreallyblondehuman/Thoughts%20%F0%9F%A4%94/Distributed%20Digital%20Organizing%20is%20The%20Way%20Out/ + - What is Security Culture: https://docs.bnkops.com/archive/repo.archive/Zines%20We%20Like%20%F0%9F%98%8E/What%20Is%20Security%20Culture%20%E2%98%A0/#what-is-security-culture + - Cost Comparison: phil/cost-comparison.md + - Getting Started: + - build/index.md + - Build Server: build/server.md + - Build Map: build/map.md + - Build Site: build/site.md + - Services: + - services/index.md + - Homepage: services/homepage.md + - Code Server: services/code-server.md + - MKDocs: services/mkdocs.md + - Static Server: services/static-server.md + - Listmonk: services/listmonk.md + - PostgreSQL: services/postgresql.md + - n8n: services/n8n.md + - NocoDB: services/nocodb.md + - Gitea: services/gitea.md + - Map Viewer: services/map.md + - Mini QR: services/mini-qr.md + - Configuration: + - config/index.md + - Cloudflare: config/cloudflare-config.md + - MKdocs: config/mkdocs.md + - Code Server: config/coder.md + - Advanced Configuration: + - adv/index.md + - SSH + Tailscale + Ansible: adv/ansible.md + - SSH + VScode: adv/vscode-ssh.md + - Blog: + - blog/index.md diff --git a/mkdocs/site/adv/vscode-ssh/index.html b/mkdocs/site/adv/vscode-ssh/index.html index b1e6930..2860c3a 100644 --- a/mkdocs/site/adv/vscode-ssh/index.html +++ b/mkdocs/site/adv/vscode-ssh/index.html @@ -2472,29 +2472,39 @@ Changemaker Archive. Learn more

Part 1: Install and Configure Remote-SSH Extension

1. Install the Remote Development Extensions

-

Option A: Install Remote Development Pack (Recommended) -1. Open VSCode -2. Press Ctrl+Shift+X (or Cmd+Shift+X on Mac) -3. Search for "Remote Development" -4. Install the Remote Development extension pack by Microsoft

-

This pack includes: -- Remote - SSH -- Remote - SSH: Editing Configuration Files -- Remote - Containers -- Remote - WSL (Windows only)

-

Option B: Install Individual Extension -1. Search for "Remote - SSH" -2. Install Remote - SSH by Microsoft

+

Option A: Install Remote Development Pack (Recommended)

+
    +
  1. Open VSCode
  2. +
  3. Press Ctrl+Shift+X (or Cmd+Shift+X on Mac)
  4. +
  5. Search for "Remote Development"
  6. +
  7. Install the Remote Development extension pack by Microsoft
  8. +
+

This pack includes:

+
    +
  • Remote - SSH
  • +
  • Remote - SSH: Editing Configuration Files
  • +
  • Remote - Containers
  • +
  • Remote - WSL (Windows only)
  • +
+

Option B: Install Individual Extension

+
    +
  1. Search for "Remote - SSH"
  2. +
  3. Install Remote - SSH by Microsoft
  4. +

2. Verify Installation

-

After installation, the following should be visible: -- Remote Explorer icon in the Activity Bar (left sidebar) -- "Remote-SSH" commands in Command Palette (Ctrl+Shift+P)

+

After installation, the following should be visible:

+
    +
  • Remote Explorer icon in the Activity Bar (left sidebar)
  • +
  • "Remote-SSH" commands in Command Palette (Ctrl+Shift+P)
  • +

Part 2: Configure SSH Connections

1. Access SSH Configuration

-

Method A: Through VSCode -1. Press Ctrl+Shift+P to open Command Palette -2. Type "Remote-SSH: Open SSH Configuration File..." -3. Select the SSH config file (usually the first option)

+

Method A: Through VSCode

+
    +
  1. Press Ctrl+Shift+P to open Command Palette
  2. +
  3. Type "Remote-SSH: Open SSH Configuration File..."
  4. +
  5. Select the SSH config file (usually the first option)
  6. +

Method B: Direct File Editing

# Edit SSH config file directly
 nano ~/.ssh/config
@@ -2519,14 +2529,16 @@ Changemaker Archive. Learn more
     ServerAliveInterval 60
     ServerAliveCountMax 3
 
-

Configuration Options Explained: -- Host: Friendly name for the connection -- HostName: Tailscale IP address -- User: Username on the remote server -- IdentityFile: Path to the SSH private key -- ForwardAgent: Enables SSH agent forwarding for Git operations -- ServerAliveInterval: Keeps connection alive (prevents timeouts) -- ServerAliveCountMax: Number of keepalive attempts

+

Configuration Options Explained:

+
    +
  • Host: Friendly name for the connection
  • +
  • HostName: Tailscale IP address
  • +
  • User: Username on the remote server
  • +
  • IdentityFile: Path to the SSH private key
  • +
  • ForwardAgent: Enables SSH agent forwarding for Git operations
  • +
  • ServerAliveInterval: Keeps connection alive (prevents timeouts)
  • +
  • ServerAliveCountMax: Number of keepalive attempts
  • +

3. Set Proper SSH Key Permissions

# Ensure SSH config has correct permissions
 chmod 600 ~/.ssh/config
@@ -2556,10 +2568,12 @@ Changemaker Archive. Learn more
 
  • Choose the server from the list
  • 4. First Connection Process

    -

    On first connection, VSCode will: -1. Verify the host key (click "Continue" if prompted) -2. Install VSCode Server on the remote machine (automatic) -3. Open a remote window with access to the remote file system

    +

    On first connection, VSCode will:

    +
      +
    1. Verify the host key (click "Continue" if prompted)
    2. +
    3. Install VSCode Server on the remote machine (automatic)
    4. +
    5. Open a remote window with access to the remote file system
    6. +

    Expected Timeline: - First connection: 1-3 minutes (installs VSCode Server) - Subsequent connections: 10-30 seconds

    @@ -2578,17 +2592,21 @@ Changemaker Archive. Learn more

    2. Install Extensions on Remote Server

    Extensions must be installed separately on the remote server:

    -

    Essential Development Extensions: -1. Python (Microsoft) - Python development -2. GitLens (GitKraken) - Enhanced Git capabilities -3. Docker (Microsoft) - Container development -4. Prettier - Code formatting -5. ESLint - JavaScript linting -6. Auto Rename Tag - HTML/XML tag editing

    -

    To Install: -1. Go to Extensions (Ctrl+Shift+X) -2. Find the desired extension -3. Click "Install in SSH: node1" (not local install)

    +

    Essential Development Extensions:

    +
      +
    1. Python (Microsoft) - Python development
    2. +
    3. GitLens (GitKraken) - Enhanced Git capabilities
    4. +
    5. Docker (Microsoft) - Container development
    6. +
    7. Prettier - Code formatting
    8. +
    9. ESLint - JavaScript linting
    10. +
    11. Auto Rename Tag - HTML/XML tag editing
    12. +
    +

    To Install:

    +
      +
    1. Go to Extensions (Ctrl+Shift+X)
    2. +
    3. Find the desired extension
    4. +
    5. Click "Install in SSH: node1" (not local install)
    6. +

    3. Configure Git on Remote Server

    # In VSCode terminal (remote)
     git config --global user.name "<Full Name>"
    @@ -2599,10 +2617,12 @@ Changemaker Archive. Learn more
     

    Part 5: Remote Development Workflows

    1. File Management

    -

    File Explorer: -- Shows remote server's file system -- Create, edit, delete files directly -- Drag and drop between local and remote (limited)

    +

    File Explorer:

    +
      +
    • Shows remote server's file system
    • +
    • Create, edit, delete files directly
    • +
    • Drag and drop between local and remote (limited)
    • +

    File Transfer:

    # Upload files to remote (from local terminal)
     scp localfile.txt <username>@<tailscale-ip>:/home/<username>/
    @@ -2611,11 +2631,13 @@ Changemaker Archive. Learn more
     scp <username>@<tailscale-ip>:/remote/path/file.txt ./local/path/
     

    2. Terminal Usage

    -

    Integrated Terminal: -- Press Ctrl+` to open terminal -- Runs directly on remote server -- Multiple terminals supported -- Full shell access (bash, zsh, etc.)

    +

    Integrated Terminal:

    +
      +
    • Press Ctrl+` to open terminal
    • +
    • Runs directly on remote server
    • +
    • Multiple terminals supported
    • +
    • Full shell access (bash, zsh, etc.)
    • +

    Common Remote Terminal Commands:

    # Check system resources
     htop
    @@ -2633,11 +2655,13 @@ Changemaker Archive. Learn more
     

    3. Port Forwarding

    Automatic Port Forwarding: VSCode automatically detects and forwards common development ports.

    -

    Manual Port Forwarding: -1. Open Ports tab in terminal panel -2. Click "Forward a Port" -3. Enter port number (e.g., 3000, 8080, 5000) -4. Access via http://localhost:port on the local machine

    +

    Manual Port Forwarding:

    +
      +
    1. Open Ports tab in terminal panel
    2. +
    3. Click "Forward a Port"
    4. +
    5. Enter port number (e.g., 3000, 8080, 5000)
    6. +
    7. Access via http://localhost:port on the local machine
    8. +

    Example: Web Development

    # Start a web server on remote (port 3000)
     npm start
    @@ -2690,20 +2714,26 @@ VSCode automatically detects and forwards common development ports.

    }

    2. Multi-Server Management

    -

    Switch Between Servers: -1. Click remote indicator (bottom-left) -2. Select "Connect to Host..." -3. Choose a different server

    -

    Compare Files Across Servers: -1. Open file from server A -2. Connect to server B in new window -3. Open corresponding file -4. Use "Compare with..." command

    +

    Switch Between Servers:

    +
      +
    1. Click remote indicator (bottom-left)
    2. +
    3. Select "Connect to Host..."
    4. +
    5. Choose a different server
    6. +
    +

    Compare Files Across Servers:

    +
      +
    1. Open file from server A
    2. +
    3. Connect to server B in new window
    4. +
    5. Open corresponding file
    6. +
    7. Use "Compare with..." command
    8. +

    3. Sync Configuration

    -

    Settings Sync: -1. Enable Settings Sync in VSCode -2. Settings, extensions, and keybindings sync to remote -3. Consistent experience across all servers

    +

    Settings Sync:

    +
      +
    1. Enable Settings Sync in VSCode
    2. +
    3. Settings, extensions, and keybindings sync to remote
    4. +
    5. Consistent experience across all servers
    6. +

    Part 7: Project-Specific Setups

    1. Python Development

    # On remote server
    @@ -2752,10 +2782,12 @@ VSCode automatically detects and forwards common development ports.

    CMD ["npm", "start"] EOF
    -

    VSCode Docker Integration: -- Install Docker extension on remote -- Right-click Dockerfile → "Build Image" -- Manage containers from VSCode interface

    +

    VSCode Docker Integration:

    +
      +
    • Install Docker extension on remote
    • +
    • Right-click Dockerfile → "Build Image"
    • +
    • Manage containers from VSCode interface
    • +

    Part 8: Troubleshooting Guide

    Common Connection Issues

    Problem: "Could not establish connection to remote host"

    @@ -2794,10 +2826,12 @@ VSCode automatically detects and forwards common development ports.

    VSCode-Specific Issues

    Problem: Extensions not working on remote

    -

    Solutions: -1. Install extensions specifically for the remote server -2. Check extension compatibility with remote development -3. Reload VSCode window: Ctrl+Shift+P → "Developer: Reload Window"

    +

    Solutions:

    +
      +
    1. Install extensions specifically for the remote server
    2. +
    3. Check extension compatibility with remote development
    4. +
    5. Reload VSCode window: Ctrl+Shift+P → "Developer: Reload Window"
    6. +

    Problem: Slow performance

    Solutions: - Use .vscode/settings.json to exclude large directories: diff --git a/mkdocs/site/assets/images/social/test.png b/mkdocs/site/assets/images/social/test.png new file mode 100644 index 0000000000000000000000000000000000000000..d605523fb6897040748b27bb9c69ea03877a18a5 GIT binary patch literal 24436 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 JG7q2m=?}87!s`G4 literal 0 HcmV?d00001 diff --git a/mkdocs/site/assets/repo-data/admin-changemaker.lite.json b/mkdocs/site/assets/repo-data/admin-changemaker.lite.json index 1c59173..890a556 100644 --- a/mkdocs/site/assets/repo-data/admin-changemaker.lite.json +++ b/mkdocs/site/assets/repo-data/admin-changemaker.lite.json @@ -7,10 +7,10 @@ "stars_count": 0, "forks_count": 0, "open_issues_count": 0, - "updated_at": "2025-07-02T11:49:44-06:00", + "updated_at": "2025-07-04T14:31:11-06:00", "created_at": "2025-05-28T14:54:59-06:00", "clone_url": "https://gitea.bnkops.com/admin/changemaker.lite.git", "ssh_url": "git@gitea.bnkops.com:admin/changemaker.lite.git", "default_branch": "main", - "last_build_update": "2025-07-02T11:49:44-06:00" + "last_build_update": "2025-07-04T14:31:11-06:00" } \ No newline at end of file diff --git a/mkdocs/site/assets/repo-data/anthropics-claude-code.json b/mkdocs/site/assets/repo-data/anthropics-claude-code.json index bd2f765..3cc5bfa 100644 --- a/mkdocs/site/assets/repo-data/anthropics-claude-code.json +++ b/mkdocs/site/assets/repo-data/anthropics-claude-code.json @@ -4,13 +4,13 @@ "description": "Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.", "html_url": "https://github.com/anthropics/claude-code", "language": "PowerShell", - "stars_count": 17031, - "forks_count": 941, - "open_issues_count": 1508, - "updated_at": "2025-07-03T05:19:19Z", + "stars_count": 17373, + "forks_count": 959, + "open_issues_count": 1578, + "updated_at": "2025-07-04T21:17:51Z", "created_at": "2025-02-22T17:41:21Z", "clone_url": "https://github.com/anthropics/claude-code.git", "ssh_url": "git@github.com:anthropics/claude-code.git", "default_branch": "main", - "last_build_update": "2025-07-03T03:54:14Z" + "last_build_update": "2025-07-03T21:09:58Z" } \ No newline at end of file diff --git a/mkdocs/site/assets/repo-data/coder-code-server.json b/mkdocs/site/assets/repo-data/coder-code-server.json index 3593dcf..af61bbe 100644 --- a/mkdocs/site/assets/repo-data/coder-code-server.json +++ b/mkdocs/site/assets/repo-data/coder-code-server.json @@ -4,10 +4,10 @@ "description": "VS Code in the browser", "html_url": "https://github.com/coder/code-server", "language": "TypeScript", - "stars_count": 72541, - "forks_count": 6067, - "open_issues_count": 141, - "updated_at": "2025-07-03T05:17:24Z", + "stars_count": 72668, + "forks_count": 6074, + "open_issues_count": 143, + "updated_at": "2025-07-04T18:33:06Z", "created_at": "2019-02-27T16:50:41Z", "clone_url": "https://github.com/coder/code-server.git", "ssh_url": "git@github.com:coder/code-server.git", diff --git a/mkdocs/site/assets/repo-data/gethomepage-homepage.json b/mkdocs/site/assets/repo-data/gethomepage-homepage.json index 70b9e60..5dd6dd4 100644 --- a/mkdocs/site/assets/repo-data/gethomepage-homepage.json +++ b/mkdocs/site/assets/repo-data/gethomepage-homepage.json @@ -4,13 +4,13 @@ "description": "A highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.", "html_url": "https://github.com/gethomepage/homepage", "language": "JavaScript", - "stars_count": 24619, - "forks_count": 1520, - "open_issues_count": 1, - "updated_at": "2025-07-03T03:29:15Z", + "stars_count": 24643, + "forks_count": 1522, + "open_issues_count": 2, + "updated_at": "2025-07-04T19:49:50Z", "created_at": "2022-08-24T07:29:42Z", "clone_url": "https://github.com/gethomepage/homepage.git", "ssh_url": "git@github.com:gethomepage/homepage.git", "default_branch": "dev", - "last_build_update": "2025-07-03T00:36:38Z" + "last_build_update": "2025-07-04T12:13:48Z" } \ No newline at end of file diff --git a/mkdocs/site/assets/repo-data/go-gitea-gitea.json b/mkdocs/site/assets/repo-data/go-gitea-gitea.json index a4e28c6..92fb96f 100644 --- a/mkdocs/site/assets/repo-data/go-gitea-gitea.json +++ b/mkdocs/site/assets/repo-data/go-gitea-gitea.json @@ -4,13 +4,13 @@ "description": "Git with a cup of tea! Painless self-hosted all-in-one software development service, including Git hosting, code review, team collaboration, package registry and CI/CD", "html_url": "https://github.com/go-gitea/gitea", "language": "Go", - "stars_count": 49349, - "forks_count": 5892, - "open_issues_count": 2702, - "updated_at": "2025-07-03T03:52:23Z", + "stars_count": 49370, + "forks_count": 5897, + "open_issues_count": 2711, + "updated_at": "2025-07-04T20:42:00Z", "created_at": "2016-11-01T02:13:26Z", "clone_url": "https://github.com/go-gitea/gitea.git", "ssh_url": "git@github.com:go-gitea/gitea.git", "default_branch": "main", - "last_build_update": "2025-07-03T03:02:38Z" + "last_build_update": "2025-07-04T15:41:19Z" } \ No newline at end of file diff --git a/mkdocs/site/assets/repo-data/knadh-listmonk.json b/mkdocs/site/assets/repo-data/knadh-listmonk.json index 8b473b8..ddb5784 100644 --- a/mkdocs/site/assets/repo-data/knadh-listmonk.json +++ b/mkdocs/site/assets/repo-data/knadh-listmonk.json @@ -4,10 +4,10 @@ "description": "High performance, self-hosted, newsletter and mailing list manager with a modern dashboard. Single binary app.", "html_url": "https://github.com/knadh/listmonk", "language": "Go", - "stars_count": 17250, - "forks_count": 1658, - "open_issues_count": 101, - "updated_at": "2025-07-03T01:26:41Z", + "stars_count": 17261, + "forks_count": 1659, + "open_issues_count": 103, + "updated_at": "2025-07-04T18:22:09Z", "created_at": "2019-06-26T05:08:39Z", "clone_url": "https://github.com/knadh/listmonk.git", "ssh_url": "git@github.com:knadh/listmonk.git", diff --git a/mkdocs/site/assets/repo-data/lyqht-mini-qr.json b/mkdocs/site/assets/repo-data/lyqht-mini-qr.json index 2b77d76..1d9ac9f 100644 --- a/mkdocs/site/assets/repo-data/lyqht-mini-qr.json +++ b/mkdocs/site/assets/repo-data/lyqht-mini-qr.json @@ -4,10 +4,10 @@ "description": "Create & scan cute qr codes easily \ud83d\udc7e", "html_url": "https://github.com/lyqht/mini-qr", "language": "Vue", - "stars_count": 1254, + "stars_count": 1258, "forks_count": 164, "open_issues_count": 13, - "updated_at": "2025-07-01T14:06:12Z", + "updated_at": "2025-07-04T21:12:26Z", "created_at": "2023-04-21T14:20:14Z", "clone_url": "https://github.com/lyqht/mini-qr.git", "ssh_url": "git@github.com:lyqht/mini-qr.git", diff --git a/mkdocs/site/assets/repo-data/n8n-io-n8n.json b/mkdocs/site/assets/repo-data/n8n-io-n8n.json index fb176f8..2a5008f 100644 --- a/mkdocs/site/assets/repo-data/n8n-io-n8n.json +++ b/mkdocs/site/assets/repo-data/n8n-io-n8n.json @@ -4,13 +4,13 @@ "description": "Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.", "html_url": "https://github.com/n8n-io/n8n", "language": "TypeScript", - "stars_count": 114419, - "forks_count": 33630, + "stars_count": 114980, + "forks_count": 33907, "open_issues_count": 1074, - "updated_at": "2025-07-03T05:21:36Z", + "updated_at": "2025-07-04T21:26:25Z", "created_at": "2019-06-22T09:24:21Z", "clone_url": "https://github.com/n8n-io/n8n.git", "ssh_url": "git@github.com:n8n-io/n8n.git", "default_branch": "master", - "last_build_update": "2025-07-03T04:31:44Z" + "last_build_update": "2025-07-04T18:53:03Z" } \ No newline at end of file diff --git a/mkdocs/site/assets/repo-data/nocodb-nocodb.json b/mkdocs/site/assets/repo-data/nocodb-nocodb.json index 166acf1..e9b250c 100644 --- a/mkdocs/site/assets/repo-data/nocodb-nocodb.json +++ b/mkdocs/site/assets/repo-data/nocodb-nocodb.json @@ -4,13 +4,13 @@ "description": "\ud83d\udd25 \ud83d\udd25 \ud83d\udd25 Open Source Airtable Alternative", "html_url": "https://github.com/nocodb/nocodb", "language": "TypeScript", - "stars_count": 55514, - "forks_count": 3994, + "stars_count": 55535, + "forks_count": 3997, "open_issues_count": 718, - "updated_at": "2025-07-03T04:26:22Z", + "updated_at": "2025-07-04T20:56:30Z", "created_at": "2017-10-29T18:51:48Z", "clone_url": "https://github.com/nocodb/nocodb.git", "ssh_url": "git@github.com:nocodb/nocodb.git", "default_branch": "develop", - "last_build_update": "2025-07-03T04:39:20Z" + "last_build_update": "2025-07-04T18:37:18Z" } \ No newline at end of file diff --git a/mkdocs/site/assets/repo-data/ollama-ollama.json b/mkdocs/site/assets/repo-data/ollama-ollama.json index b9bb106..da5ee56 100644 --- a/mkdocs/site/assets/repo-data/ollama-ollama.json +++ b/mkdocs/site/assets/repo-data/ollama-ollama.json @@ -4,13 +4,13 @@ "description": "Get up and running with Llama 3.3, DeepSeek-R1, Phi-4, Gemma 3, Mistral Small 3.1 and other large language models.", "html_url": "https://github.com/ollama/ollama", "language": "Go", - "stars_count": 145379, - "forks_count": 12279, - "open_issues_count": 1903, - "updated_at": "2025-07-03T05:22:04Z", + "stars_count": 145579, + "forks_count": 12297, + "open_issues_count": 1881, + "updated_at": "2025-07-04T20:55:45Z", "created_at": "2023-06-26T19:39:32Z", "clone_url": "https://github.com/ollama/ollama.git", "ssh_url": "git@github.com:ollama/ollama.git", "default_branch": "main", - "last_build_update": "2025-07-02T23:38:37Z" + "last_build_update": "2025-07-04T05:42:44Z" } \ No newline at end of file diff --git a/mkdocs/site/assets/repo-data/squidfunk-mkdocs-material.json b/mkdocs/site/assets/repo-data/squidfunk-mkdocs-material.json index 95a27d9..6639296 100644 --- a/mkdocs/site/assets/repo-data/squidfunk-mkdocs-material.json +++ b/mkdocs/site/assets/repo-data/squidfunk-mkdocs-material.json @@ -4,10 +4,10 @@ "description": "Documentation that simply works", "html_url": "https://github.com/squidfunk/mkdocs-material", "language": "Python", - "stars_count": 23786, - "forks_count": 3787, - "open_issues_count": 5, - "updated_at": "2025-07-03T00:57:11Z", + "stars_count": 23801, + "forks_count": 3792, + "open_issues_count": 6, + "updated_at": "2025-07-04T20:37:34Z", "created_at": "2016-01-28T22:09:23Z", "clone_url": "https://github.com/squidfunk/mkdocs-material.git", "ssh_url": "git@github.com:squidfunk/mkdocs-material.git", diff --git a/mkdocs/site/build/index.html b/mkdocs/site/build/index.html index 975bcbc..ecedbc0 100644 --- a/mkdocs/site/build/index.html +++ b/mkdocs/site/build/index.html @@ -1366,6 +1366,15 @@ Changemaker Archive. Learn more + + +

  • + + + Optional - Site Builld + + +
  • @@ -1827,6 +1836,8 @@ Changemaker Archive. Learn more
    # Start all services
     docker compose up -d
     
    +

    Optional - Site Builld

    +

    If you want to have your site prepared for launch, you can now proceed with reseting the site build. See Build Site for more detials.

    Deploy

    Cloudflare

    diff --git a/mkdocs/site/hooks/__pycache__/repo_widget_hook.cpython-311.pyc b/mkdocs/site/hooks/__pycache__/repo_widget_hook.cpython-311.pyc index 481db4755389d040005a83521cbeb847183ae324..fc15fbaed2b84eb8b01cbdde993068971e8da501 100644 GIT binary patch delta 28 icmdmLw!(~iIWI340}v=%WNhRXW@l2-->l2dAp!thsRfY$ delta 41 vcmZ2sw$+S#IWI340}zPSq;BLEX6HB5&&bbB)lbe(NiEXP&EBlQ&LIK-+k^_f diff --git a/mkdocs/site/phil/index.html b/mkdocs/site/phil/index.html index 59725fc..0ff2e98 100644 --- a/mkdocs/site/phil/index.html +++ b/mkdocs/site/phil/index.html @@ -779,7 +779,7 @@ Changemaker Archive. Learn more
  • - The Question That Changes Everything + The Question That Changes Everything! @@ -1171,7 +1171,7 @@ Changemaker Archive. Learn more

    Philosophy: Your Secrets, Your Power, Your Movement

    -

    The Question That Changes Everything

    +

    The Question That Changes Everything!

    If you are a political actor, who do you trust with your secrets?

    This isn't just a technical question—it's the core political question of our time. Every email you send, every document you create, every contact list you build, every strategy you develop: where does it live? Who owns the servers? Who has the keys?

    The Corporate Extraction Machine

    diff --git a/mkdocs/site/search/search_index.json b/mkdocs/site/search/search_index.json index f0b8504..bc6888a 100644 --- a/mkdocs/site/search/search_index.json +++ b/mkdocs/site/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\u200b\\-_,:!=\\[\\]()\"`/]+|\\.(?!\\d)|&[lg]t;|(?!\\b)(?=[A-Z][a-z])","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Welcome to Changemaker Lite","text":"

    Stop feeding your secrets to corporations. Own your political infrastructure.

    "},{"location":"#quick-start","title":"Quick Start","text":"

    Get up and running in minutes:

    # Clone the repository\ngit clone https://gitea.bnkops.com/admin/changemaker.lite\ncd changemaker.lite\n\n# Configure environment\n./config.sh\n\n# Start all services\ndocker compose up -d\n\n# For production deployment with Cloudflare tunnels\n./start-production.sh\n
    "},{"location":"#services","title":"Services","text":"

    Changemaker Lite includes these essential services:

    "},{"location":"#core-services","title":"Core Services","text":"
    • Homepage (Port 3010) - Central dashboard and service monitoring
    • Code Server (Port 8888) - VS Code in your browser
    • MkDocs (Port 4000) - Documentation with live preview
    • Static Server (Port 4001) - Production documentation site
    "},{"location":"#communication-automation","title":"Communication & Automation","text":"
    • Listmonk (Port 9000) - Newsletter and email campaign management
    • n8n (Port 5678) - Workflow automation platform
    "},{"location":"#data-development","title":"Data & Development","text":"
    • NocoDB (Port 8090) - No-code database platform
    • PostgreSQL (Port 5432) - Database backend for Listmonk
    • Gitea (Port 3030) - Self-hosted Git service
    "},{"location":"#interactive-tools","title":"Interactive Tools","text":"
    • Map Viewer (Port 3000) - Interactive map with NocoDB integration
    • Mini QR (Port 8089) - QR code generator
    "},{"location":"#getting-started","title":"Getting Started","text":"
    1. Setup: Run ./config.sh to configure your environment
    2. Launch: Start services with docker compose up -d
    3. Dashboard: Access the Homepage at http://localhost:3010
    4. Production: Deploy with Cloudflare tunnels using ./start-production.sh
    "},{"location":"#project-structure","title":"Project Structure","text":"
    changemaker.lite/\n\u251c\u2500\u2500 docker-compose.yml    # Service definitions\n\u251c\u2500\u2500 config.sh            # Configuration wizard\n\u251c\u2500\u2500 start-production.sh  # Production deployment script\n\u251c\u2500\u2500 mkdocs/              # Documentation source\n\u2502   \u251c\u2500\u2500 docs/            # Markdown files\n\u2502   \u2514\u2500\u2500 mkdocs.yml       # MkDocs configuration\n\u251c\u2500\u2500 configs/             # Service configurations\n\u2502   \u251c\u2500\u2500 homepage/        # Homepage dashboard config\n\u2502   \u251c\u2500\u2500 code-server/     # VS Code settings\n\u2502   \u2514\u2500\u2500 cloudflare/      # Tunnel configurations\n\u251c\u2500\u2500 map/                 # Map application\n\u2502   \u251c\u2500\u2500 app/             # Node.js application\n\u2502   \u251c\u2500\u2500 Dockerfile       # Container definition\n\u2502   \u2514\u2500\u2500 .env             # Map configuration\n\u2514\u2500\u2500 assets/              # Shared assets\n    \u251c\u2500\u2500 images/          # Image files\n    \u251c\u2500\u2500 icons/           # Service icons\n    \u2514\u2500\u2500 uploads/         # Listmonk uploads\n
    "},{"location":"#key-features","title":"Key Features","text":"
    • \ud83d\udc33 Fully Containerized - All services run in Docker containers
    • \ud83d\udd12 Production Ready - Built-in Cloudflare tunnel support for secure access
    • \ud83d\udce6 All-in-One - Everything you need for documentation, development, and campaigns
    • \ud83d\uddfa\ufe0f Geographic Data - Interactive maps with real-time location tracking
    • \ud83d\udce7 Email Campaigns - Professional newsletter management
    • \ud83d\udd04 Automation - Connect services and automate workflows
    • \ud83d\udcbe Version Control - Self-hosted Git repository
    • \ud83c\udfaf No-Code Database - Build applications without programming
    "},{"location":"#system-requirements","title":"System Requirements","text":"
    • OS: Ubuntu 24.04 LTS (Noble Numbat) or compatible Linux distribution
    • Docker: Version 24.0+ with Docker Compose v2
    • Memory: Minimum 4GB RAM (8GB recommended)
    • Storage: 20GB+ available disk space
    • Network: Internet connection for initial setup
    "},{"location":"#learn-more","title":"Learn More","text":"
    • Getting Started - Detailed installation guide
    • Services Overview - Deep dive into each service
    • Blog - Updates and tutorials
    • GitHub Repository - Source code
    "},{"location":"adv/","title":"Advanced Configurations","text":"

    We are also publishing how BNKops does several advanced workflows. These include things like assembling hardware, how to manage a network, how to manage several changemakers simultaneously, and integrating AI.

    "},{"location":"adv/ansible/","title":"Setting Up Ansible with Tailscale for Remote Server Management","text":""},{"location":"adv/ansible/#overview","title":"Overview","text":"

    This guide walks you through setting up Ansible to manage remote servers (like ThinkCentre units) using Tailscale for secure networking. This approach provides reliable remote access without complex port forwarding or VPN configurations.

    In plainer language; this allows you to manage several Changemaker nodes remotely. If you are a full time campaigner, this can enable you to manage several campaigns infrastructure from a central location while each user gets their own Changemaker box.

    "},{"location":"adv/ansible/#what-youll-learn","title":"What You'll Learn","text":"
    • How to set up Ansible for infrastructure automation
    • How to configure secure remote access using Tailscale
    • How to troubleshoot common SSH and networking issues
    • Why this approach is better than alternatives like Cloudflare Tunnels for simple SSH access
    "},{"location":"adv/ansible/#prerequisites","title":"Prerequisites","text":"
    • Master Node: Your main computer running Ubuntu/Linux (control machine)
    • Target Nodes: Remote servers/ThinkCentres running Ubuntu/Linux
    • Both machines: Must have internet access
    • User Account: Same username on all machines (recommended)
    "},{"location":"adv/ansible/#part-1-initial-setup-on-master-node","title":"Part 1: Initial Setup on Master Node","text":""},{"location":"adv/ansible/#1-create-ansible-directory-structure","title":"1. Create Ansible Directory Structure","text":"
    # Create project directory\nmkdir ~/ansible_quickstart\ncd ~/ansible_quickstart\n\n# Create directory structure\nmkdir -p group_vars host_vars roles playbooks\n
    "},{"location":"adv/ansible/#2-install-ansible","title":"2. Install Ansible","text":"
    sudo apt update\nsudo apt install ansible\n
    "},{"location":"adv/ansible/#3-generate-ssh-keys-if-not-already-done","title":"3. Generate SSH Keys (if not already done)","text":"
    # Generate SSH key pair\nssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa\n\n# Display public key (save this for later)\ncat ~/.ssh/id_rsa.pub\n
    "},{"location":"adv/ansible/#part-2-target-node-setup-physical-access-required-initially","title":"Part 2: Target Node Setup (Physical Access Required Initially)","text":""},{"location":"adv/ansible/#1-enable-ssh-on-target-node","title":"1. Enable SSH on Target Node","text":"

    Access each target node physically (monitor + keyboard):

    # Update system\nsudo apt update && sudo apt upgrade -y\n\n# Install and enable SSH\nsudo apt install openssh-server\nsudo systemctl enable ssh\nsudo systemctl start ssh\n\n# Check SSH status\nsudo systemctl status ssh\n
    "},{"location":"adv/ansible/#2-configure-ssh-key-authentication","title":"2. Configure SSH Key Authentication","text":"
    # Create .ssh directory\nmkdir -p ~/.ssh\nchmod 700 ~/.ssh\n\n# Create authorized_keys file\nnano ~/.ssh/authorized_keys\n

    Paste your public key from the master node, then:

    # Set proper permissions\nchmod 600 ~/.ssh/authorized_keys\n
    "},{"location":"adv/ansible/#3-configure-ssh-security","title":"3. Configure SSH Security","text":"
    # Edit SSH config\nsudo nano /etc/ssh/sshd_config\n

    Ensure these lines are uncommented:

    PubkeyAuthentication yes\nAuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2\n
    # Restart SSH service\nsudo systemctl restart ssh\n
    "},{"location":"adv/ansible/#4-configure-firewall","title":"4. Configure Firewall","text":"
    # Check firewall status\nsudo ufw status\n\n# Allow SSH through firewall\nsudo ufw allow ssh\n\n# Fix home directory permissions (required for SSH keys)\nchmod 755 ~/\n
    "},{"location":"adv/ansible/#part-3-test-local-ssh-connection","title":"Part 3: Test Local SSH Connection","text":"

    Before proceeding with remote access, test SSH connectivity locally:

    # From master node, test SSH to target\nssh username@<target-local-ip>\n

    Common Issues and Solutions:

    • Connection hangs: Check firewall rules (sudo ufw allow ssh)
    • Permission denied: Verify SSH keys and file permissions
    • SSH config errors: Ensure PubkeyAuthentication yes is set
    "},{"location":"adv/ansible/#part-4-set-up-tailscale-for-remote-access","title":"Part 4: Set Up Tailscale for Remote Access","text":""},{"location":"adv/ansible/#why-tailscale-over-alternatives","title":"Why Tailscale Over Alternatives","text":"

    We initially tried Cloudflare Tunnels but encountered complexity with:

    • DNS routing issues
    • Complex configuration for SSH
    • Same-network testing problems
    • Multiple configuration approaches with varying success

    Tailscale is superior because:

    • Zero configuration mesh networking
    • Works from any network
    • Persistent IP addresses
    • No port forwarding needed
    • Free for personal use
    "},{"location":"adv/ansible/#1-install-tailscale-on-master-node","title":"1. Install Tailscale on Master Node","text":"
    # Install Tailscale\ncurl -fsSL https://tailscale.com/install.sh | sh\n\n# Connect to Tailscale network\nsudo tailscale up\n

    Follow the authentication URL to connect with your Google/Microsoft/GitHub account.

    "},{"location":"adv/ansible/#2-install-tailscale-on-target-nodes","title":"2. Install Tailscale on Target Nodes","text":"

    On each target node:

    # Install Tailscale\ncurl -fsSL https://tailscale.com/install.sh | sh\n\n# Connect to Tailscale network\nsudo tailscale up\n

    Authenticate each device through the provided URL.

    "},{"location":"adv/ansible/#3-get-tailscale-ip-addresses","title":"3. Get Tailscale IP Addresses","text":"

    On each machine:

    # Get your Tailscale IP\ntailscale ip -4\n

    Each device receives a persistent IP like 100.x.x.x.

    "},{"location":"adv/ansible/#part-5-configure-ansible","title":"Part 5: Configure Ansible","text":""},{"location":"adv/ansible/#1-create-inventory-file","title":"1. Create Inventory File","text":"
    # Create inventory.ini\ncd ~/ansible_quickstart\nnano inventory.ini\n

    Content:

    [thinkcenter]\ntc-node1 ansible_host=100.x.x.x ansible_user=your-username\ntc-node2 ansible_host=100.x.x.x ansible_user=your-username\n\n[all:vars]\nansible_ssh_private_key_file=~/.ssh/id_rsa\nansible_host_key_checking=False\n

    Replace:

    • 100.x.x.x with actual Tailscale IPs
    • your-username with your actual username
    "},{"location":"adv/ansible/#2-test-ansible-connectivity","title":"2. Test Ansible Connectivity","text":"
    # Test connection to all nodes\nansible all -i inventory.ini -m ping\n

    Expected output:

    tc-node1 | SUCCESS => {\n    \"changed\": false,\n    \"ping\": \"pong\"\n}\n
    "},{"location":"adv/ansible/#part-6-create-and-run-playbooks","title":"Part 6: Create and Run Playbooks","text":""},{"location":"adv/ansible/#1-simple-information-gathering-playbook","title":"1. Simple Information Gathering Playbook","text":"
    mkdir -p playbooks\nnano playbooks/info-playbook.yml\n

    Content:

    ---\n- name: Gather Node Information\n  hosts: all\n  tasks:\n    - name: Get system information\n      setup:\n\n    - name: Display basic system info\n      debug:\n        msg: |\n          Hostname: {{ ansible_hostname }}\n          Operating System: {{ ansible_distribution }} {{ ansible_distribution_version }}\n          Architecture: {{ ansible_architecture }}\n          Memory: {{ ansible_memtotal_mb }}MB\n          CPU Cores: {{ ansible_processor_vcpus }}\n\n    - name: Show disk usage\n      command: df -h /\n      register: disk_info\n\n    - name: Display disk usage\n      debug:\n        msg: \"Root filesystem usage: {{ disk_info.stdout_lines[1] }}\"\n\n    - name: Check uptime\n      command: uptime\n      register: uptime_info\n\n    - name: Display uptime\n      debug:\n        msg: \"System uptime: {{ uptime_info.stdout }}\"\n
    "},{"location":"adv/ansible/#2-run-the-playbook","title":"2. Run the Playbook","text":"
    ansible-playbook -i inventory.ini playbooks/info-playbook.yml\n
    "},{"location":"adv/ansible/#part-7-advanced-playbook-example","title":"Part 7: Advanced Playbook Example","text":""},{"location":"adv/ansible/#system-setup-playbook","title":"System Setup Playbook","text":"
    nano playbooks/setup-node.yml\n

    Content:

    ---\n- name: Setup ThinkCentre Node\n  hosts: all\n  become: yes\n  tasks:\n    - name: Update package cache\n      apt:\n        update_cache: yes\n\n    - name: Install essential packages\n      package:\n        name:\n          - htop\n          - vim\n          - curl\n          - git\n          - docker.io\n        state: present\n\n    - name: Add user to docker group\n      user:\n        name: \"{{ ansible_user }}\"\n        groups: docker\n        append: yes\n\n    - name: Create management directory\n      file:\n        path: /opt/management\n        state: directory\n        owner: \"{{ ansible_user }}\"\n        group: \"{{ ansible_user }}\"\n
    "},{"location":"adv/ansible/#troubleshooting-guide","title":"Troubleshooting Guide","text":""},{"location":"adv/ansible/#ssh-issues","title":"SSH Issues","text":"

    Problem: SSH connection hangs

    • Check firewall: sudo ufw status and sudo ufw allow ssh
    • Verify SSH service: sudo systemctl status ssh
    • Test local connectivity first

    Problem: Permission denied (publickey)

    • Check SSH key permissions: chmod 600 ~/.ssh/authorized_keys
    • Verify home directory permissions: chmod 755 ~/
    • Ensure SSH config allows key auth: PubkeyAuthentication yes

    Problem: Bad owner or permissions on SSH config

    chmod 600 ~/.ssh/config\n
    "},{"location":"adv/ansible/#ansible-issues","title":"Ansible Issues","text":"

    Problem: Host key verification failed

    • Add to inventory: ansible_host_key_checking=False

    Problem: Ansible command not found

    sudo apt install ansible\n

    Problem: Connection timeouts

    • Verify Tailscale connectivity: ping <tailscale-ip>
    • Check if both nodes are connected: tailscale status
    "},{"location":"adv/ansible/#tailscale-issues","title":"Tailscale Issues","text":"

    Problem: Can't connect to Tailscale IP

    • Verify both devices are authenticated: tailscale status
    • Check Tailscale is running: sudo systemctl status tailscaled
    • Restart Tailscale: sudo tailscale up
    "},{"location":"adv/ansible/#scaling-to-multiple-nodes","title":"Scaling to Multiple Nodes","text":""},{"location":"adv/ansible/#adding-new-nodes","title":"Adding New Nodes","text":"
    1. Install Tailscale on new node
    2. Set up SSH access (repeat Part 2)
    3. Add to inventory.ini:
    [thinkcenter]\ntc-node1 ansible_host=100.125.148.60 ansible_user=bunker-admin\ntc-node2 ansible_host=100.x.x.x ansible_user=bunker-admin\ntc-node3 ansible_host=100.x.x.x ansible_user=bunker-admin\n
    "},{"location":"adv/ansible/#group-management","title":"Group Management","text":"
    [webservers]\ntc-node1 ansible_host=100.x.x.x ansible_user=bunker-admin\ntc-node2 ansible_host=100.x.x.x ansible_user=bunker-admin\n\n[databases]\ntc-node3 ansible_host=100.x.x.x ansible_user=bunker-admin\n\n[all:vars]\nansible_ssh_private_key_file=~/.ssh/id_rsa\nansible_host_key_checking=False\n

    Run playbooks on specific groups:

    ansible-playbook -i inventory.ini -l webservers playbook.yml\n
    "},{"location":"adv/ansible/#best-practices","title":"Best Practices","text":""},{"location":"adv/ansible/#security","title":"Security","text":"
    • Use SSH keys, not passwords
    • Keep Tailscale client updated
    • Regular security updates via Ansible
    • Use become: yes only when necessary
    "},{"location":"adv/ansible/#organization","title":"Organization","text":"
    ansible_quickstart/\n\u251c\u2500\u2500 inventory.ini\n\u251c\u2500\u2500 group_vars/\n\u251c\u2500\u2500 host_vars/\n\u251c\u2500\u2500 roles/\n\u2514\u2500\u2500 playbooks/\n    \u251c\u2500\u2500 info-playbook.yml\n    \u251c\u2500\u2500 setup-node.yml\n    \u2514\u2500\u2500 maintenance.yml\n
    "},{"location":"adv/ansible/#monitoring-and-maintenance","title":"Monitoring and Maintenance","text":"

    Create regular maintenance playbooks:

    - name: System maintenance\n  hosts: all\n  become: yes\n  tasks:\n    - name: Update all packages\n      apt:\n        upgrade: dist\n        update_cache: yes\n\n    - name: Clean package cache\n      apt:\n        autoclean: yes\n        autoremove: yes\n
    "},{"location":"adv/ansible/#alternative-approaches-we-considered","title":"Alternative Approaches We Considered","text":""},{"location":"adv/ansible/#cloudflare-tunnels","title":"Cloudflare Tunnels","text":"
    • Pros: Good for web services, handles NAT traversal
    • Cons: Complex SSH setup, DNS routing issues, same-network problems
    • Use case: Better for web applications than SSH access
    "},{"location":"adv/ansible/#traditional-vpn","title":"Traditional VPN","text":"
    • Pros: Full network access
    • Cons: Complex setup, port forwarding required, router configuration
    • Use case: When you control the network infrastructure
    "},{"location":"adv/ansible/#ssh-reverse-tunnels","title":"SSH Reverse Tunnels","text":"
    • Pros: Simple concept
    • Cons: Requires VPS, single point of failure, manual setup
    • Use case: Temporary access or when other methods fail
    "},{"location":"adv/ansible/#conclusion","title":"Conclusion","text":"

    This setup provides:

    • Reliable remote access from anywhere
    • Secure mesh networking with Tailscale
    • Infrastructure automation with Ansible
    • Easy scaling to multiple nodes
    • No complex networking required

    The combination of Ansible + Tailscale is ideal for managing distributed infrastructure without the complexity of traditional VPN setups or the limitations of cloud-specific solutions.

    "},{"location":"adv/ansible/#quick-reference-commands","title":"Quick Reference Commands","text":"
    # Check Tailscale status\ntailscale status\n\n# Test Ansible connectivity\nansible all -i inventory.ini -m ping\n\n# Run playbook on all hosts\nansible-playbook -i inventory.ini playbook.yml\n\n# Run playbook on specific group\nansible-playbook -i inventory.ini -l groupname playbook.yml\n\n# Run single command on all hosts\nansible all -i inventory.ini -m command -a \"uptime\"\n\n# SSH to node via Tailscale\nssh username@100.x.x.x\n
    "},{"location":"adv/vscode-ssh/","title":"Remote Development with VSCode over Tailscale","text":""},{"location":"adv/vscode-ssh/#overview","title":"Overview","text":"

    This guide describes how to set up Visual Studio Code for remote development on servers using the Tailscale network. This enables development directly on remote machines as if they were local, with full access to files, terminals, and debugging capabilities.

    "},{"location":"adv/vscode-ssh/#what-youll-learn","title":"What You'll Learn","text":"
    • How to configure VSCode for remote SSH connections
    • How to set up remote development environments
    • How to manage multiple remote servers efficiently
    • How to troubleshoot common remote development issues
    • Best practices for remote development workflows
    "},{"location":"adv/vscode-ssh/#prerequisites","title":"Prerequisites","text":"
    • Ansible + Tailscale setup completed (see previous guide)
    • VSCode installed on the local machine (master node)
    • Working SSH access to remote servers via Tailscale
    • Tailscale running on both local and remote machines
    "},{"location":"adv/vscode-ssh/#verify-prerequisites","title":"Verify Prerequisites","text":"

    Before starting, verify the setup:

    # Check Tailscale connectivity\ntailscale status\n\n# Test SSH access\nssh <username>@<tailscale-ip>\n\n# Check VSCode is installed\ncode --version\n
    "},{"location":"adv/vscode-ssh/#part-1-install-and-configure-remote-ssh-extension","title":"Part 1: Install and Configure Remote-SSH Extension","text":""},{"location":"adv/vscode-ssh/#1-install-the-remote-development-extensions","title":"1. Install the Remote Development Extensions","text":"

    Option A: Install Remote Development Pack (Recommended) 1. Open VSCode 2. Press Ctrl+Shift+X (or Cmd+Shift+X on Mac) 3. Search for \"Remote Development\" 4. Install the Remote Development extension pack by Microsoft

    This pack includes: - Remote - SSH - Remote - SSH: Editing Configuration Files - Remote - Containers - Remote - WSL (Windows only)

    Option B: Install Individual Extension 1. Search for \"Remote - SSH\" 2. Install Remote - SSH by Microsoft

    "},{"location":"adv/vscode-ssh/#2-verify-installation","title":"2. Verify Installation","text":"

    After installation, the following should be visible: - Remote Explorer icon in the Activity Bar (left sidebar) - \"Remote-SSH\" commands in Command Palette (Ctrl+Shift+P)

    "},{"location":"adv/vscode-ssh/#part-2-configure-ssh-connections","title":"Part 2: Configure SSH Connections","text":""},{"location":"adv/vscode-ssh/#1-access-ssh-configuration","title":"1. Access SSH Configuration","text":"

    Method A: Through VSCode 1. Press Ctrl+Shift+P to open Command Palette 2. Type \"Remote-SSH: Open SSH Configuration File...\" 3. Select the SSH config file (usually the first option)

    Method B: Direct File Editing

    # Edit SSH config file directly\nnano ~/.ssh/config\n

    "},{"location":"adv/vscode-ssh/#2-add-server-configurations","title":"2. Add Server Configurations","text":"

    Add servers to the SSH config file:

    # Example Node\nHost node1\n    HostName <tailscale-ip>\n    User <username>\n    IdentityFile ~/.ssh/id_rsa\n    ForwardAgent yes\n    ServerAliveInterval 60\n    ServerAliveCountMax 3\n\n# Additional nodes (add as needed)\nHost node2\n    HostName <tailscale-ip>\n    User <username>\n    IdentityFile ~/.ssh/id_rsa\n    ForwardAgent yes\n    ServerAliveInterval 60\n    ServerAliveCountMax 3\n

    Configuration Options Explained: - Host: Friendly name for the connection - HostName: Tailscale IP address - User: Username on the remote server - IdentityFile: Path to the SSH private key - ForwardAgent: Enables SSH agent forwarding for Git operations - ServerAliveInterval: Keeps connection alive (prevents timeouts) - ServerAliveCountMax: Number of keepalive attempts

    "},{"location":"adv/vscode-ssh/#3-set-proper-ssh-key-permissions","title":"3. Set Proper SSH Key Permissions","text":"
    # Ensure SSH config has correct permissions\nchmod 600 ~/.ssh/config\n\n# Verify SSH key permissions\nchmod 600 ~/.ssh/id_rsa\nchmod 644 ~/.ssh/id_rsa.pub\n
    "},{"location":"adv/vscode-ssh/#part-3-connect-to-remote-servers","title":"Part 3: Connect to Remote Servers","text":""},{"location":"adv/vscode-ssh/#1-connect-via-command-palette","title":"1. Connect via Command Palette","text":"
    1. Press Ctrl+Shift+P
    2. Type \"Remote-SSH: Connect to Host...\"
    3. Select the server (e.g., node1)
    4. VSCode will open a new window connected to the remote server
    "},{"location":"adv/vscode-ssh/#2-connect-via-remote-explorer","title":"2. Connect via Remote Explorer","text":"
    1. Click the Remote Explorer icon in Activity Bar
    2. Expand SSH Targets
    3. Click the connect icon next to the server name
    "},{"location":"adv/vscode-ssh/#3-connect-via-quick-menu","title":"3. Connect via Quick Menu","text":"
    1. Click the remote indicator in bottom-left corner (looks like ><)
    2. Select \"Connect to Host...\"
    3. Choose the server from the list
    "},{"location":"adv/vscode-ssh/#4-first-connection-process","title":"4. First Connection Process","text":"

    On first connection, VSCode will: 1. Verify the host key (click \"Continue\" if prompted) 2. Install VSCode Server on the remote machine (automatic) 3. Open a remote window with access to the remote file system

    Expected Timeline: - First connection: 1-3 minutes (installs VSCode Server) - Subsequent connections: 10-30 seconds

    "},{"location":"adv/vscode-ssh/#part-4-remote-development-environment-setup","title":"Part 4: Remote Development Environment Setup","text":""},{"location":"adv/vscode-ssh/#1-open-remote-workspace","title":"1. Open Remote Workspace","text":"

    Once connected:

    # In the VSCode terminal (now running on remote server)\n# Navigate to the project directory\ncd /home/<username>/projects\n\n# Open current directory in VSCode\ncode .\n\n# Or open a specific project\ncode /opt/myproject\n
    "},{"location":"adv/vscode-ssh/#2-install-extensions-on-remote-server","title":"2. Install Extensions on Remote Server","text":"

    Extensions must be installed separately on the remote server:

    Essential Development Extensions: 1. Python (Microsoft) - Python development 2. GitLens (GitKraken) - Enhanced Git capabilities 3. Docker (Microsoft) - Container development 4. Prettier - Code formatting 5. ESLint - JavaScript linting 6. Auto Rename Tag - HTML/XML tag editing

    To Install: 1. Go to Extensions (Ctrl+Shift+X) 2. Find the desired extension 3. Click \"Install in SSH: node1\" (not local install)

    "},{"location":"adv/vscode-ssh/#3-configure-git-on-remote-server","title":"3. Configure Git on Remote Server","text":"
    # In VSCode terminal (remote)\ngit config --global user.name \"<Full Name>\"\ngit config --global user.email \"<email@example.com>\"\n\n# Test Git connectivity\ngit clone https://github.com/<username>/<repo>.git\n
    "},{"location":"adv/vscode-ssh/#part-5-remote-development-workflows","title":"Part 5: Remote Development Workflows","text":""},{"location":"adv/vscode-ssh/#1-file-management","title":"1. File Management","text":"

    File Explorer: - Shows remote server's file system - Create, edit, delete files directly - Drag and drop between local and remote (limited)

    File Transfer:

    # Upload files to remote (from local terminal)\nscp localfile.txt <username>@<tailscale-ip>:/home/<username>/\n\n# Download files from remote\nscp <username>@<tailscale-ip>:/remote/path/file.txt ./local/path/\n

    "},{"location":"adv/vscode-ssh/#2-terminal-usage","title":"2. Terminal Usage","text":"

    Integrated Terminal: - Press Ctrl+` to open terminal - Runs directly on remote server - Multiple terminals supported - Full shell access (bash, zsh, etc.)

    Common Remote Terminal Commands:

    # Check system resources\nhtop\ndf -h\nfree -h\n\n# Install packages\nsudo apt update\nsudo apt install nodejs npm\n\n# Start services\nsudo systemctl start nginx\nsudo docker-compose up -d\n

    "},{"location":"adv/vscode-ssh/#3-port-forwarding","title":"3. Port Forwarding","text":"

    Automatic Port Forwarding: VSCode automatically detects and forwards common development ports.

    Manual Port Forwarding: 1. Open Ports tab in terminal panel 2. Click \"Forward a Port\" 3. Enter port number (e.g., 3000, 8080, 5000) 4. Access via http://localhost:port on the local machine

    Example: Web Development

    # Start a web server on remote (port 3000)\nnpm start\n\n# VSCode automatically suggests forwarding port 3000\n# Access at http://localhost:3000 on the local machine\n

    "},{"location":"adv/vscode-ssh/#4-debugging-remote-applications","title":"4. Debugging Remote Applications","text":"

    Python Debugging:

    // .vscode/launch.json on remote server\n{\n    \"version\": \"0.2.0\",\n    \"configurations\": [\n        {\n            \"name\": \"Python: Current File\",\n            \"type\": \"python\",\n            \"request\": \"launch\",\n            \"program\": \"${file}\",\n            \"console\": \"integratedTerminal\"\n        }\n    ]\n}\n

    Node.js Debugging:

    // .vscode/launch.json\n{\n    \"version\": \"0.2.0\",\n    \"configurations\": [\n        {\n            \"name\": \"Launch Program\",\n            \"type\": \"node\",\n            \"request\": \"launch\",\n            \"program\": \"${workspaceFolder}/app.js\"\n        }\n    ]\n}\n

    "},{"location":"adv/vscode-ssh/#part-6-advanced-configuration","title":"Part 6: Advanced Configuration","text":""},{"location":"adv/vscode-ssh/#1-workspace-settings","title":"1. Workspace Settings","text":"

    Create remote-specific settings:

    // .vscode/settings.json (on remote server)\n{\n    \"python.defaultInterpreterPath\": \"/usr/bin/python3\",\n    \"terminal.integrated.shell.linux\": \"/bin/bash\",\n    \"files.autoSave\": \"afterDelay\",\n    \"editor.formatOnSave\": true,\n    \"remote.SSH.remotePlatform\": {\n        \"node1\": \"linux\"\n    }\n}\n
    "},{"location":"adv/vscode-ssh/#2-multi-server-management","title":"2. Multi-Server Management","text":"

    Switch Between Servers: 1. Click remote indicator (bottom-left) 2. Select \"Connect to Host...\" 3. Choose a different server

    Compare Files Across Servers: 1. Open file from server A 2. Connect to server B in new window 3. Open corresponding file 4. Use \"Compare with...\" command

    "},{"location":"adv/vscode-ssh/#3-sync-configuration","title":"3. Sync Configuration","text":"

    Settings Sync: 1. Enable Settings Sync in VSCode 2. Settings, extensions, and keybindings sync to remote 3. Consistent experience across all servers

    "},{"location":"adv/vscode-ssh/#part-7-project-specific-setups","title":"Part 7: Project-Specific Setups","text":""},{"location":"adv/vscode-ssh/#1-python-development","title":"1. Python Development","text":"
    # On remote server\n# Create virtual environment\npython3 -m venv venv\nsource venv/bin/activate\n\n# Install packages\npip install flask django requests\n\n# VSCode automatically detects Python interpreter\n

    VSCode Python Configuration:

    // .vscode/settings.json\n{\n    \"python.defaultInterpreterPath\": \"./venv/bin/python\",\n    \"python.linting.enabled\": true,\n    \"python.linting.pylintEnabled\": true\n}\n

    "},{"location":"adv/vscode-ssh/#2-nodejs-development","title":"2. Node.js Development","text":"
    # On remote server\n# Install Node.js\ncurl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -\nsudo apt-get install -y nodejs\n\n# Create project\nmkdir myapp && cd myapp\nnpm init -y\nnpm install express\n
    "},{"location":"adv/vscode-ssh/#3-docker-development","title":"3. Docker Development","text":"
    # On remote server\n# Install Docker (if not already done via Ansible)\nsudo apt install docker.io docker-compose\nsudo usermod -aG docker $USER\n\n# Create Dockerfile\ncat > Dockerfile << EOF\nFROM node:18\nWORKDIR /app\nCOPY package*.json ./\nRUN npm install\nCOPY . .\nEXPOSE 3000\nCMD [\"npm\", \"start\"]\nEOF\n

    VSCode Docker Integration: - Install Docker extension on remote - Right-click Dockerfile \u2192 \"Build Image\" - Manage containers from VSCode interface

    "},{"location":"adv/vscode-ssh/#part-8-troubleshooting-guide","title":"Part 8: Troubleshooting Guide","text":""},{"location":"adv/vscode-ssh/#common-connection-issues","title":"Common Connection Issues","text":"

    Problem: \"Could not establish connection to remote host\"

    Solutions:

    # Check Tailscale connectivity\ntailscale status\nping <tailscale-ip>\n\n# Test SSH manually\nssh <username>@<tailscale-ip>\n\n# Check SSH config syntax\nssh -T node1\n

    Problem: \"Permission denied (publickey)\"

    Solutions:

    # Check SSH key permissions\nchmod 600 ~/.ssh/id_rsa\nchmod 600 ~/.ssh/config\n\n# Verify SSH agent\nssh-add ~/.ssh/id_rsa\nssh-add -l\n\n# Test SSH connection verbosely\nssh -v <username>@<tailscale-ip>\n

    Problem: \"Host key verification failed\"

    Solutions:

    # Remove old host key\nssh-keygen -R <tailscale-ip>\n\n# Or disable host key checking (less secure)\n# Add to SSH config:\n# StrictHostKeyChecking no\n

    "},{"location":"adv/vscode-ssh/#vscode-specific-issues","title":"VSCode-Specific Issues","text":"

    Problem: Extensions not working on remote

    Solutions: 1. Install extensions specifically for the remote server 2. Check extension compatibility with remote development 3. Reload VSCode window: Ctrl+Shift+P \u2192 \"Developer: Reload Window\"

    Problem: Slow performance

    Solutions: - Use .vscode/settings.json to exclude large directories:

    {\n    \"files.watcherExclude\": {\n        \"**/node_modules/**\": true,\n        \"**/.git/objects/**\": true,\n        \"**/dist/**\": true\n    }\n}\n

    Problem: Terminal not starting

    Solutions:

    # Check shell path in remote settings\n\"terminal.integrated.shell.linux\": \"/bin/bash\"\n\n# Or let VSCode auto-detect\n\"terminal.integrated.defaultProfile.linux\": \"bash\"\n

    "},{"location":"adv/vscode-ssh/#network-and-performance-issues","title":"Network and Performance Issues","text":"

    Problem: Connection timeouts

    Solutions: Add to SSH config:

    ServerAliveInterval 60\nServerAliveCountMax 3\nTCPKeepAlive yes\n

    Problem: File transfer slow

    Solutions: - Use .vscodeignore to exclude unnecessary files - Compress large files before transfer - Use rsync for large file operations:

    rsync -avz --progress localdir/ <username>@<tailscale-ip>:remotedir/\n

    "},{"location":"adv/vscode-ssh/#part-9-best-practices","title":"Part 9: Best Practices","text":""},{"location":"adv/vscode-ssh/#security-best-practices","title":"Security Best Practices","text":"
    1. Use SSH keys, never passwords
    2. Keep SSH agent secure
    3. Regular security updates on remote servers
    4. Use VSCode's secure connection verification
    "},{"location":"adv/vscode-ssh/#performance-optimization","title":"Performance Optimization","text":"
    1. Exclude unnecessary files:

      // .vscode/settings.json\n{\n    \"files.watcherExclude\": {\n        \"**/node_modules/**\": true,\n        \"**/.git/**\": true,\n        \"**/dist/**\": true,\n        \"**/build/**\": true\n    },\n    \"search.exclude\": {\n        \"**/node_modules\": true,\n        \"**/bower_components\": true,\n        \"**/*.code-search\": true\n    }\n}\n

    2. Use remote workspace for large projects

    3. Close unnecessary windows and extensions
    4. Use efficient development workflows
    "},{"location":"adv/vscode-ssh/#development-workflow","title":"Development Workflow","text":"
    1. Use version control effectively:

      # Always work in Git repositories\ngit status\ngit add .\ngit commit -m \"feature: add new functionality\"\ngit push origin main\n

    2. Environment separation:

      # Development\nssh node1\ncd /home/<username>/dev-projects\n\n# Production\nssh node2\ncd /opt/production-apps\n

    3. Backup important work:

      # Regular backups via Git\ngit push origin main\n\n# Or manual backup\nscp -r <username>@<tailscale-ip>:/important/project ./backup/\n

    "},{"location":"adv/vscode-ssh/#part-10-team-collaboration","title":"Part 10: Team Collaboration","text":""},{"location":"adv/vscode-ssh/#shared-development-servers","title":"Shared Development Servers","text":"

    SSH Config for Team:

    # Shared development server\nHost team-dev\n    HostName <tailscale-ip>\n    User <team-user>\n    IdentityFile ~/.ssh/team_dev_key\n    ForwardAgent yes\n\n# Personal development\nHost my-dev\n    HostName <tailscale-ip>\n    User <username>\n    IdentityFile ~/.ssh/id_rsa\n

    "},{"location":"adv/vscode-ssh/#project-structure","title":"Project Structure","text":"
    /opt/projects/\n\u251c\u2500\u2500 project-a/\n\u2502   \u251c\u2500\u2500 dev/          # Development branch\n\u2502   \u251c\u2500\u2500 staging/      # Staging environment\n\u2502   \u2514\u2500\u2500 docs/         # Documentation\n\u251c\u2500\u2500 project-b/\n\u2514\u2500\u2500 shared-tools/     # Common utilities\n
    "},{"location":"adv/vscode-ssh/#access-management","title":"Access Management","text":"
    # Create shared project directory\nsudo mkdir -p /opt/projects\nsudo chown -R :developers /opt/projects\nsudo chmod -R g+w /opt/projects\n\n# Add users to developers group\nsudo usermod -a -G developers <username>\n
    "},{"location":"adv/vscode-ssh/#quick-reference","title":"Quick Reference","text":""},{"location":"adv/vscode-ssh/#essential-vscode-remote-commands","title":"Essential VSCode Remote Commands","text":"
    # Command Palette shortcuts\nCtrl+Shift+P \u2192 \"Remote-SSH: Connect to Host...\"\nCtrl+Shift+P \u2192 \"Remote-SSH: Open SSH Configuration File...\"\nCtrl+Shift+P \u2192 \"Remote-SSH: Kill VS Code Server on Host...\"\n\n# Terminal\nCtrl+` \u2192 Open integrated terminal\nCtrl+Shift+` \u2192 Create new terminal\n\n# File operations\nCtrl+O \u2192 Open file\nCtrl+S \u2192 Save file\nCtrl+Shift+E \u2192 Focus file explorer\n
    "},{"location":"adv/vscode-ssh/#ssh-connection-quick-test","title":"SSH Connection Quick Test","text":"
    # Test connectivity\nssh -T node1\n\n# Connect with verbose output\nssh -v <username>@<tailscale-ip>\n\n# Check SSH config\nssh -F ~/.ssh/config node1\n
    "},{"location":"adv/vscode-ssh/#port-forwarding-commands","title":"Port Forwarding Commands","text":"
    # Manual port forwarding\nssh -L 3000:localhost:3000 <username>@<tailscale-ip>\n\n# Background tunnel\nssh -f -N -L 8080:localhost:80 <username>@<tailscale-ip>\n
    "},{"location":"adv/vscode-ssh/#conclusion","title":"Conclusion","text":"

    This remote development setup provides:

    • Full development environment on remote servers
    • Seamless file access and editing capabilities
    • Integrated debugging and terminal access
    • Port forwarding for web development
    • Extension ecosystem available remotely
    • Secure connections through Tailscale network

    The combination of VSCode Remote Development with Tailscale networking creates a powerful, flexible development environment that works from anywhere while maintaining security and performance.

    Whether developing Python applications, Node.js services, or managing Docker containers, this setup provides a professional remote development experience that rivals local development while leveraging the power and resources of remote servers.

    "},{"location":"blog/2025/07/03/blog-1/","title":"Blog 1","text":"

    Hello! Just putting something up here because, well, gosh darn, feels like the right thing to do.

    Making swift progress. Can now write things fast as heck lad.

    "},{"location":"build/","title":"Getting Started with Digital Liberation","text":"

    Welcome to Changemaker-Lite! You're about to reclaim your digital sovereignty and stop feeding your secrets to corporations. This guide will help you set up your own political infrastructure that you actually own and control.

    "},{"location":"build/#quick-start","title":"Quick Start","text":""},{"location":"build/#build-changemkaer-lite","title":"Build Changemkaer-Lite","text":"
    # Clone the repository\ngit clone https://gitea.bnkops.com/admin/changemaker.lite\ncd changemaker.lite\n

    Cloudflare Credentials

    The config.sh script will ask you for your Cloudflare credentials to get started. You can find more information on how to find this in the Cloudlflare Configuration

    # Configure environment (creates .env file)\n./config.sh\n
    # Start all services\ndocker compose up -d\n
    "},{"location":"build/#deploy","title":"Deploy","text":"

    Cloudflare

    Right now, we suggest deploying using Cloudflare for simplicity and protections against 99% of surface level attacks to digital infrastructure. If you want to avoid using this service, we recommend checking out Pagolin as a drop in replacement.

    For secure public access, use the production deployment script:

    ./start-production.sh\n
    "},{"location":"build/#why-changemaker-lite","title":"Why Changemaker Lite?","text":"

    Before we dive into the technical setup, let's be clear about what you're doing here:

    The Reality

    If you do politics, who is reading your secrets? Every corporate platform you use is extracting your power, selling your data, and building profiles on your community. It's time to break free.

    "},{"location":"build/#what-youre-getting","title":"What You're Getting","text":"
    • Data Sovereignty: Your data stays on your servers
    • Cost Savings: $50/month instead of $2,000+/month for corporate solutions
    • Community Control: Technology that serves movements, not shareholders
    • Trans Liberation: Tools built with radical politics and care
    "},{"location":"build/#what-youre-leaving-behind","title":"What You're Leaving Behind","text":"
    • \u274c Corporate surveillance and data extraction
    • \u274c Escalating subscription fees and vendor lock-in
    • \u274c Algorithmic manipulation of your community
    • \u274c Terms of service that can silence you anytime
    "},{"location":"build/#system-requirements","title":"System Requirements","text":""},{"location":"build/#operating-system","title":"Operating System","text":"
    • Ubuntu 24.04 LTS (Noble Numbat) - Recommended and tested

    Getting Started on Ubunut

    Want some help getting started with a baseline buildout for a Ubunut server? You can use our BNKops Server Build Script

    • Other Linux distributions with systemd support
    • WSL2 on Windows (limited functionality)
    • Mac OS

    New to Linux?

    Consider Linux Mint - it looks like Windows but opens the door to true digital freedom.

    "},{"location":"build/#hardware-requirements","title":"Hardware Requirements","text":"
    • CPU: 2+ cores (4+ recommended)
    • RAM: 4GB minimum (8GB recommended)
    • Storage: 20GB+ available disk space
    • Network: Stable internet connection

    Cloud Hosting

    You can run this on a VPS from providers like Hetzner, DigitalOcean, or Linode for ~$20/month.

    "},{"location":"build/#software-prerequisites","title":"Software Prerequisites","text":"

    Getting Started on Docker

    Want some help getting started with a baseline buildout for a Ubunutu server? You can use our BNKops Server Build Script to roll out a configured server in about 20 mins!

    1. Docker Engine (24.0+)
    # Install Docker\ncurl -fsSL https://get.docker.com | sudo sh\n\n# Add your user to docker group\nsudo usermod -aG docker $USER\n\n# Log out and back in for group changes to take effect\n
    1. Docker Compose (v2.20+)
    # Verify Docker Compose v2 is installed\ndocker compose version\n
    1. Essential Tools
    # Install required packages\nsudo apt update\nsudo apt install -y git curl jq openssl\n
    "},{"location":"build/#installation","title":"Installation","text":""},{"location":"build/#1-clone-repository","title":"1. Clone Repository","text":"
    git clone https://gitea.bnkops.com/admin/changemaker.lite\ncd changemaker.lite\n
    "},{"location":"build/#2-run-configuration-wizard","title":"2. Run Configuration Wizard","text":"

    The config.sh script will guide you through the initial setup:

    ./config.sh\n

    This wizard will:

    • \u2705 Create a .env file with secure defaults
    • \u2705 Scan for available ports to avoid conflicts
    • \u2705 Set up your domain configuration
    • \u2705 Generate secure passwords for databases
    • \u2705 Configure Cloudflare credentials (optional)
    • \u2705 Update all configuration files with your settings
    "},{"location":"build/#configuration-options","title":"Configuration Options","text":"

    During setup, you'll be prompted for:

    1. Domain Name: Your primary domain (e.g., example.com)
    2. Cloudflare Settings (optional):
    3. API Token
    4. Zone ID
    5. Account ID
    6. Admin Credentials:
    7. Listmonk admin email and password
    8. n8n admin email and password
    "},{"location":"build/#3-start-services","title":"3. Start Services","text":"

    Launch all services with Docker Compose:

    docker compose up -d\n

    Wait for services to initialize (first run may take 5-10 minutes):

    # Watch container status\ndocker compose ps\n\n# View logs\ndocker compose logs -f\n
    "},{"location":"build/#4-verify-installation","title":"4. Verify Installation","text":"

    Check that all services are running:

    docker compose ps\n

    Expected output should show all services as \"Up\":

    • code-server-changemaker
    • listmonk_app
    • listmonk_db
    • mkdocs-changemaker
    • mkdocs-site-server-changemaker
    • n8n-changemaker
    • nocodb
    • root_db
    • homepage-changemaker
    • gitea_changemaker
    • gitea_mysql_changemaker
    • mini-qr
    "},{"location":"build/#local-access","title":"Local Access","text":"

    Once services are running, access them locally:

    "},{"location":"build/#homepage-dashboard","title":"\ud83c\udfe0 Homepage Dashboard","text":"
    • URL: http://localhost:3010
    • Purpose: Central hub for all services
    • Features: Service status, quick links, monitoring
    "},{"location":"build/#development-tools","title":"\ud83d\udcbb Development Tools","text":"
    • Code Server: http://localhost:8888 \u2014 VS Code in browser
    • Gitea: http://localhost:3030 \u2014 Git repository management
    • MkDocs Dev: http://localhost:4000 \u2014 Live documentation preview
    • MkDocs Prod: http://localhost:4001 \u2014 Built documentation
    "},{"location":"build/#communication","title":"\ud83d\udce7 Communication","text":"
    • Listmonk: http://localhost:9000 \u2014 Email campaigns Login with credentials set during configuration
    "},{"location":"build/#automation-data","title":"\ud83d\udd04 Automation & Data","text":"
    • n8n: http://localhost:5678 \u2014 Workflow automation Login with credentials set during configuration
    • NocoDB: http://localhost:8090 \u2014 No-code database
    "},{"location":"build/#interactive-tools","title":"\ud83d\udee0\ufe0f Interactive Tools","text":"
    • Mini QR: http://localhost:8089 \u2014 QR code generator
    "},{"location":"build/#map","title":"Map","text":"

    Map

    Map is the canvassing application that is custom view of nocodb data. Map is best built after production deployment to reduce duplicate build efforts.

    "},{"location":"build/#map-manual","title":"Map Manual","text":""},{"location":"build/#production-deployment","title":"Production Deployment","text":""},{"location":"build/#deploy-with-cloudflare-tunnels","title":"Deploy with Cloudflare Tunnels","text":"

    For secure public access, use the production deployment script:

    ./start-production.sh\n

    This script will:

    1. Install and configure cloudflared
    2. Create a Cloudflare tunnel
    3. Set up DNS records automatically
    4. Configure access policies
    5. Create a systemd service for persistence
    "},{"location":"build/#what-happens-during-production-setup","title":"What Happens During Production Setup","text":"
    1. Cloudflare Authentication: Browser-based login to Cloudflare
    2. Tunnel Creation: Secure tunnel named changemaker-lite
    3. DNS Configuration: Automatic CNAME records for all services
    4. Access Policies: Email-based authentication for sensitive services
    5. Service Installation: Systemd service for automatic startup
    "},{"location":"build/#production-urls","title":"Production URLs","text":"

    After successful deployment, services will be available at:

    Public Services:

    • https://yourdomain.com - Main documentation site
    • https://listmonk.yourdomain.com - Email campaigns
    • https://docs.yourdomain.com - Documentation preview
    • https://n8n.yourdomain.com - Automation platform
    • https://db.yourdomain.com - NocoDB
    • https://git.yourdomain.com - Gitea
    • https://map.yourdomain.com - Map viewer
    • https://qr.yourdomain.com - QR generator

    Protected Services (require authentication):

    • https://homepage.yourdomain.com - Dashboard
    • https://code.yourdomain.com - Code Server
    "},{"location":"build/#configuration-management","title":"Configuration Management","text":""},{"location":"build/#environment-variables","title":"Environment Variables","text":"

    Key settings in .env file:

    # Domain Configuration\nDOMAIN=yourdomain.com\nBASE_DOMAIN=https://yourdomain.com\n\n# Service Ports (automatically assigned to avoid conflicts)\nHOMEPAGE_PORT=3010\nCODE_SERVER_PORT=8888\nLISTMONK_PORT=9000\nMKDOCS_PORT=4000\nMKDOCS_SITE_SERVER_PORT=4001\nN8N_PORT=5678\nNOCODB_PORT=8090\nGITEA_WEB_PORT=3030\nGITEA_SSH_PORT=2222\nMAP_PORT=3000\nMINI_QR_PORT=8089\n\n# Cloudflare (for production)\nCF_API_TOKEN=your_token\nCF_ZONE_ID=your_zone_id\nCF_ACCOUNT_ID=your_account_id\n
    "},{"location":"build/#reconfigure-services","title":"Reconfigure Services","text":"

    To update configuration:

    # Re-run configuration wizard\n./config.sh\n\n# Restart services\ndocker compose down && docker compose up -d\n
    "},{"location":"build/#common-tasks","title":"Common Tasks","text":""},{"location":"build/#service-management","title":"Service Management","text":"
    # View all services\ndocker compose ps\n\n# View logs for specific service\ndocker compose logs -f [service-name]\n\n# Restart a service\ndocker compose restart [service-name]\n\n# Stop all services\ndocker compose down\n\n# Stop and remove all data (CAUTION!)\ndocker compose down -v\n
    "},{"location":"build/#backup-data","title":"Backup Data","text":"
    # Backup all volumes\ndocker run --rm -v changemaker_listmonk-data:/data -v $(pwd):/backup alpine tar czf /backup/listmonk-backup.tar.gz -C /data .\n\n# Backup configuration\ntar czf configs-backup.tar.gz configs/\n\n# Backup documentation\ntar czf docs-backup.tar.gz mkdocs/docs/\n
    "},{"location":"build/#update-services","title":"Update Services","text":"
    # Pull latest images\ndocker compose pull\n\n# Recreate containers with new images\ndocker compose up -d\n
    "},{"location":"build/#troubleshooting","title":"Troubleshooting","text":""},{"location":"build/#port-conflicts","title":"Port Conflicts","text":"

    If services fail to start due to port conflicts:

    1. Check which ports are in use:
    sudo ss -tulpn | grep LISTEN\n
    1. Re-run configuration to get new ports:
    ./config.sh\n
    1. Or manually edit .env file and change conflicting ports
    "},{"location":"build/#permission-issues","title":"Permission Issues","text":"

    Fix permission problems:

    # Get your user and group IDs\nid -u  # User ID\nid -g  # Group ID\n\n# Update .env file with correct IDs\nUSER_ID=1000\nGROUP_ID=1000\n\n# Restart services\ndocker compose down && docker compose up -d\n
    "},{"location":"build/#service-wont-start","title":"Service Won't Start","text":"

    Debug service issues:

    # Check detailed logs\ndocker compose logs [service-name] --tail 50\n\n# Check container status\ndocker ps -a\n\n# Inspect container\ndocker inspect [container-name]\n
    "},{"location":"build/#cloudflare-tunnel-issues","title":"Cloudflare Tunnel Issues","text":"
    # Check tunnel service status\nsudo systemctl status cloudflared-changemaker\n\n# View tunnel logs\nsudo journalctl -u cloudflared-changemaker -f\n\n# Restart tunnel\nsudo systemctl restart cloudflared-changemaker\n
    "},{"location":"build/#next-steps","title":"Next Steps","text":"

    Now that your Changemaker Lite instance is running:

    1. Set up Listmonk - Configure SMTP and create your first campaign
    2. Create workflows - Build automations in n8n
    3. Import data - Set up your NocoDB databases
    4. Configure map - Add location data for the map viewer
    5. Write documentation - Start creating content in MkDocs
    6. Set up Git - Initialize repositories in Gitea
    "},{"location":"build/#getting-help","title":"Getting Help","text":"
    • Check the Services documentation for detailed guides
    • Review container logs for specific error messages
    • Ensure all prerequisites are properly installed
    • Verify your domain DNS settings for production deployment
    "},{"location":"build/map/","title":"Map","text":"

    Map is BNKops canvassing application. It is built from the ground up to serve our community (Edmonton).

    "},{"location":"build/map/#prerequisites","title":"Prerequisites","text":"
    • Docker and Docker Compose installed
    • NocoDB instance with API access
    • Domain name (optional but recommended for production)
    "},{"location":"build/map/#nocodb-table-setup","title":"NocoDB Table Setup","text":""},{"location":"build/map/#required-columns","title":"Required Columns","text":"

    Case Sensitive

    When entering in the required columns, make sure that you enter in exact information. Case sensitivity matters for mapping the values to the map itself.

    Create a table in NocoDB with these required columns. The format here is the Name of the column - column type - details:

    1. Geo-Location (geo-data) - Format: \"latitude;longitude\"
    2. latitude (Decimal) - Precision: 10, Scale: 8
    3. longitude (Decimal) - Precision: 11, Scale: 8
    "},{"location":"build/map/#recommended-columns","title":"Recommended Columns","text":"
    • First Name (Text)
    • Last Name (Text)
    • Email (Email)
    • Phone (Phone)
    • Unit Number (Text)
    • Address (LongText)
    • Support Level (Single Select) - Values (only enter numbers):
    • 1 Strong Support (Green)
    • 2 Moderate Support (Yellow)
    • 3 Low Support (Orange)
    • 4 No Support (Red)
    • Sign (Checkbox)
    • Sign Size (Single Select) - Values: Small, Medium, Large
    • Notes (LongText)
    "},{"location":"build/map/#login-sheet-setup","title":"Login Sheet Setup","text":"

    Create a separate table for authorized users with: - Email (Email) - Primary column - Name (Text) - Optional

    "},{"location":"build/map/#api-token-setup","title":"API Token Setup","text":"
    1. In NocoDB, click user icon \u2192 Account Settings
    2. Go to \"API Tokens\" tab
    3. Create new token with read/write permissions for both tables
    "},{"location":"build/map/#6-finding-nocodb-ids","title":"6. Finding NocoDB IDs","text":"
    • Project and Table IDs: Use the full NocoDB view URL in NOCODB_VIEW_URL
    • Login Sheet ID: Use the full URL to your login sheet in NOCODB_LOGIN_SHEET
    "},{"location":"build/map/#environment-configuration","title":"Environment Configuration","text":"

    Config

    The ./config.sh should have created a new .env file. If .env file is present, and it has properly defined domain, skip to step 2

    1. Copy the example env file:
    cp .env.example .env\n
    1. Edit .env with your NocoDB details:
      NOCODB_API_URL=https://your-nocodb-instance.com/api/v1\nNOCODB_API_TOKEN=your-api-token-here\nNOCODB_VIEW_URL=https://your-nocodb-instance.com/dashboard/#/nc/project-id/table-id\nNOCODB_LOGIN_SHEET=https://your-nocodb-instance.com/dashboard/#/nc/project-id/login-sheet-id\n\n# Server Configuration\nPORT=3000\nNODE_ENV=production\n\n# Session Secret (generate with: openssl rand -hex 32)\nSESSION_SECRET=your-secure-random-string\n\n# Map Defaults\nDEFAULT_LAT=53.5461\nDEFAULT_LNG=-113.4938\nDEFAULT_ZOOM=11\n\n# Optional: Map Boundaries\n# BOUND_NORTH=53.7\n# BOUND_SOUTH=53.4\n# BOUND_EAST=-113.3\n# BOUND_WEST=-113.7\n\n# Domain Settings (for cookies)\nCOOKIE_DOMAIN=.yourdomain.com\nALLOWED_ORIGINS=https://map.yourdomain.com,http://localhost:3000\n
    "},{"location":"build/map/#running-the-application","title":"Running the Application","text":""},{"location":"build/map/#development-mode","title":"Development Mode","text":"
    cd app\nnpm install\nnpm run dev\n
    "},{"location":"build/map/#production-with-docker","title":"Production with Docker","text":"
    docker-compose up -d\n
    "},{"location":"build/map/#first-run","title":"First Run","text":"
    1. Access the application at http://localhost:3000 (or your domain)
    2. Login with an email from your authorized users list
    3. Verify locations appear on the map
    "},{"location":"build/map/#maintenance","title":"Maintenance","text":"
    • To clear the geocoding cache, restart the application
    • To update the application:
      docker-compose down\ngit pull origin main\ndocker-compose up -d --build\n
    "},{"location":"build/map/#troubleshooting","title":"Troubleshooting","text":"
    • Locations not showing: Verify table has required columns and API token has read permissions
    • Cannot add locations: Check API token has write permissions
    • Authentication issues: Verify login sheet is properly configured
    "},{"location":"build/map/#security-recommendations","title":"Security Recommendations","text":"
    1. Use HTTPS in production
    2. Regularly rotate API tokens
    3. Restrict API token permissions to only what's needed
    4. Set appropriate CORS and cookie domains
    5. Keep dependencies updated

    The application will automatically:

    • Parse project/table IDs from view URLs
    • Sync geo fields between different formats
    • Cache geocoding results for performance
    • Rate limit API endpoints
    • Validate all inputs
    "},{"location":"build/server/","title":"BNKops Server Build","text":"

    Purpose: a Ubuntu server build-out for general application

    This documentation is a overview of the full build out for a server OS and baseline for running Changemaker-lite. It is a manual to re-install this server on any machine.

    All of the following systems are free and the majority are open source.

    "},{"location":"build/server/#ubuntu-os","title":"Ubuntu OS","text":"

    Ubuntu is a Linux distribution derived from Debian and composed mostly of free and open-source software.

    "},{"location":"build/server/#install-ubuntu","title":"Install Ubuntu","text":""},{"location":"build/server/#post-install","title":"Post Install","text":"

    Post installation, run update:

    sudo apt update\n

    sudo apt upgrade\n
    "},{"location":"build/server/#configuration","title":"Configuration","text":"

    Further configurations:

    • User profile was updated to Automatically Login
    • Remote Desktop, Sharing, and Login have all been enabled.
    • Default system settings have been set to dark mode.
    "},{"location":"build/server/#vscode-insiders","title":"VSCode Insiders","text":"

    Visual Studio Code is a new choice of tool that combines the simplicity of a code editor with what developers need for the core edit-build-debug cycle.

    "},{"location":"build/server/#install-using-app-centre","title":"Install Using App Centre","text":""},{"location":"build/server/#obsidian","title":"Obsidian","text":"

    The free and flexible app for your private\u00a0thoughts.

    "},{"location":"build/server/#install-using-app-center","title":"Install Using App Center","text":""},{"location":"build/server/#curl","title":"Curl","text":"

    command line tool and library for transferring data with URLs (since 1998)

    "},{"location":"build/server/#install","title":"Install","text":"
    sudo apt install curl \n
    "},{"location":"build/server/#glances","title":"Glances","text":"

    Glances an Eye on your system. A top/htop alternative for GNU/Linux, BSD, Mac OS and Windows operating systems.

    "},{"location":"build/server/#install_1","title":"Install","text":"
    sudo snap install glances \n
    "},{"location":"build/server/#syncthing","title":"Syncthing","text":"

    Syncthing is a continuous file synchronization program. It synchronizes files between two or more computers in real time, safely protected from prying eyes. Your data is your data alone and you deserve to choose where it is stored, whether it is shared with some third party, and how it\u2019s transmitted over the internet.

    "},{"location":"build/server/#install_2","title":"Install","text":"
    # Add the release PGP keys:\nsudo mkdir -p /etc/apt/keyrings\nsudo curl -L -o /etc/apt/keyrings/syncthing-archive-keyring.gpg https://syncthing.net/release-key.gpg\n
    # Add the \"stable\" channel to your APT sources:\necho \"deb [signed-by=/etc/apt/keyrings/syncthing-archive-keyring.gpg] https://apt.syncthing.net/ syncthing stable\" | sudo tee /etc/apt/sources.list.d/syncthing.list\n
    # Update and install syncthing:\nsudo apt-get update\nsudo apt-get install syncthing\n
    "},{"location":"build/server/#post-install_1","title":"Post Install","text":"

    Run syncthing as a system service.

    sudo systemctl start syncthing@yourusername\n

    sudo systemctl enable syncthing@yourusername\n
    "},{"location":"build/server/#docker","title":"Docker","text":"

    Docker helps developers build, share, run, and verify applications anywhere \u2014 without tedious environment configuration or management.

    # Add Docker's official GPG key:\nsudo apt-get update\nsudo apt-get install ca-certificates curl\nsudo install -m 0755 -d /etc/apt/keyrings\nsudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc\nsudo chmod a+r /etc/apt/keyrings/docker.asc\n\n# Add the repository to Apt sources:\necho \\\n  \"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \\\n  $(. /etc/os-release && echo \"${UBUNTU_CODENAME:-$VERSION_CODENAME}\") stable\" | \\\n  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null\nsudo apt-get update\n

    sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin\n
    "},{"location":"build/server/#update-users","title":"Update Users","text":"
    sudo groupadd docker\n
    sudo usermod -aG docker $USER\n
    newgrp docker\n
    "},{"location":"build/server/#enable-on-boot","title":"Enable on Boot","text":"
    sudo systemctl enable docker.service\nsudo systemctl enable containerd.service\n
    "},{"location":"build/server/#cloudflared","title":"Cloudflared","text":"

    Connect, protect, and build everywhere. We make websites, apps, and networks faster and more secure. Our developer platform is the best place to build modern apps and deliver AI initiatives.

    sudo mkdir -p --mode=0755 /usr/share/keyrings\ncurl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null\n
    echo \"deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared any main\" | sudo tee /etc/apt/sources.list.d/cloudflared.list\n
    sudo apt-get update && sudo apt-get install cloudflared\n
    "},{"location":"build/server/#post-install_2","title":"Post Install","text":"

    Login to Cloudflare

    cloudflared login\n

    "},{"location":"build/server/#configuration_1","title":"Configuration","text":"

    The ./config.sh and ./start-production.sh scripts will properly configure a Cloudflare tunnel and service to put your system online. More info in the Cloudflare Configuration.

    "},{"location":"build/server/#pandoc","title":"Pandoc","text":"

    If you need to convert files from one markup format into another, pandoc is your swiss-army knife.

    sudo apt install pandoc\n
    "},{"location":"build/site/","title":"Building the Site with MkDocs Material","text":"

    Welcome! This guide will help you get started building and customizing your site using MkDocs Material.

    "},{"location":"build/site/#how-to-build-your-site-step-by-step","title":"\ud83d\ude80 How to Build Your Site (Step by Step)","text":"
    1. Open your Coder instance. For example: coder.yourdomain.com
    2. Go to the mkdocs folder: In the terminal (for a new terminal press Crtl - Shift - ~), type:
      cd mkdocs\n
    3. Build the site: Type:
      mkdocs build\n
      This creates the static website from your documents and places them in the mkdocs/site directory.

    Preview your site locally: Visit localhost:4000 for local development or live.youdomain.com to see a public live load.

    • All documentation in the mkdocs/docs folder is included automatically.
    • The site uses the beautiful and easy-to-use Material for MkDocs theme.

    Material for MkDocs Documentation

    Build vs Serve

    Your website is built in stages. Any edits to documents in the mkdocs directory are instantly served and visible at localhost:4000 or if in production mode live.yourdomain.com. The live site is not meant as a public access point and will crash if too many requests are made to it.

    Running mkdocs build pushes any changes to the site directory, which then a ngnix server pushes them to the production server for public access at your root domain (yourdomain.com).

    You can think of it as serve/live = draft for personal review and build = save/push to production for the public.

    This combination allows for rapid development of documentation while ensuring your live site does not get updated until your content is ready.

    "},{"location":"build/site/#resetting-the-site","title":"\ud83e\uddf9 Resetting the Site","text":"

    If you want to start fresh:

    1. Delete all folders EXCEPT these folders:

      • /blog
      • /javascripts
      • /hooks
      • /assets
      • /stylesheets
      • /overrides
    2. Reset the landing page:

      • Open the main index.md file and remove everything at the very top (the \"front matter\").
      • Or edit /overrides/home.html to change the landing page.
    3. Reset the mkdocs.yml

      • Open mkdocs.yml and delete the nav section entirely.
      • This action will enable mkdocs to build your site navigation based on file names in the root directory.
    "},{"location":"build/site/#using-ai-to-help-build-your-site","title":"\ud83e\udd16 Using AI to Help Build Your Site","text":"
    • If you have a claude.ai subscription, you can use powerful AI in your Coder terminal to write or rewrite pages, including a new home.html.
    • All you need to do is open the terminal and type:
      claude\n
    • You can also try local AI tools like Ollama for on-demand help.
    "},{"location":"build/site/#first-time-setup-tips","title":"\ud83d\udee0\ufe0f First-Time Setup Tips","text":"
    • Navigation: Open mkdocs.yml and remove the nav section to start with a blank menu. Add your own pages as you go.
    • Customize the look: Check out the Material for MkDocs customization guide.
    • Live preview: Use mkdocs serve (see above) to see changes instantly as you edit.
    • Custom files: Put your own CSS, JavaScript, or HTML in /assets, /stylesheets, /javascripts, or /overrides.

    Quick Start Guide

    "},{"location":"build/site/#more-resources","title":"\ud83d\udcda More Resources","text":"
    • MkDocs User Guide
    • Material for MkDocs Features
    • BNKops MKdocs Configuration & Customization

    Happy building!

    "},{"location":"config/","title":"Configuration","text":"

    There are several configuration steps to building a production ready Changemaker-Lite.

    In the order we suggest doing them:

    "},{"location":"config/cloudflare-config/","title":"Configure Cloudflare","text":"

    Cloudflare is the largest DNS routing service on the planet. We use their free service tier to provide Changemaker users with a fast, secure, and reliable way to get online that blocks 99% of surface level attacks and has built in user authenticaion (if you so choose to use it)

    "},{"location":"config/cloudflare-config/#credentials","title":"Credentials","text":"

    The config.sh and start-production.sh scripts require the following Cloudflare credentials to function properly:

    "},{"location":"config/cloudflare-config/#1-cloudflare-api-token","title":"1. Cloudflare API Token","text":"
    • Purpose: Used to authenticate API requests to Cloudflare for managing DNS records, tunnels, and access policies.
    • Required Permissions:
      • Zone.DNS (Read/Write)
      • Account.Cloudflare Tunnel (Read/Write)
    • How to Obtain:
      • Log in to your Cloudflare account.
      • Go to My Profile > API Tokens > Create Token.
      • Use the Edit zone DNS template and add Cloudflare Tunnel permissions.
    "},{"location":"config/cloudflare-config/#2-cloudflare-zone-id","title":"2. Cloudflare Zone ID","text":"
    • Purpose: Identifies the specific DNS zone (domain) in Cloudflare where DNS records will be created.
    • How to Obtain:
      • Log in to your Cloudflare account.
      • Select the domain you want to use.
      • The Zone ID is displayed in the Overview section under API.
    "},{"location":"config/cloudflare-config/#3-cloudflare-account-id","title":"3. Cloudflare Account ID","text":"
    • Purpose: Identifies your Cloudflare account for tunnel creation and management.
    • How to Obtain:
      • Log in to your Cloudflare account.
      • Go to My Profile > API Tokens.
      • The Account ID is displayed at the top of the page.
    "},{"location":"config/cloudflare-config/#4-cloudflare-tunnel-id-optional-in-configsh-required-in-start-productionsh","title":"4. Cloudflare Tunnel ID (Optional in config.sh, Required in start-production.sh)","text":"
    • Purpose: Identifies the specific Cloudflare Tunnel that will be used to route traffic to your services.
    • How to Obtain:
      • This is automatically generated when you create a tunnel using cloudflared tunnel create or via the Cloudflare dashboard.
      • The start-production.sh script will create this for you if it doesn't exist.
    "},{"location":"config/cloudflare-config/#summary-of-required-credentials","title":"Summary of Required Credentials:","text":"
    # In .env file\nCF_API_TOKEN=your_cloudflare_api_token\nCF_ZONE_ID=your_cloudflare_zone_id\nCF_ACCOUNT_ID=your_cloudflare_account_id\nCF_TUNNEL_ID=will_be_set_by_start_production  # This will be set by start-production.sh\n
    "},{"location":"config/cloudflare-config/#notes","title":"Notes:","text":"
    • The config.sh script will prompt you for these credentials during setup.
    • The start-production.sh script will verify these credentials and use them to configure DNS records, create tunnels, and set up access policies.
    • Ensure that the API token has the correct permissions, or the scripts will fail to configure Cloudflare services.
    "},{"location":"config/coder/","title":"Coder Server Configuration","text":"

    This section describes the configuration and features of the code-server environment.

    "},{"location":"config/coder/#accessing-code-server","title":"Accessing Code Server","text":"
    • URL: http://localhost:8080
    • Authentication: Password-based (see below for password retrieval)
    "},{"location":"config/coder/#retrieving-the-code-server-password","title":"Retrieving the Code Server Password","text":"

    After the first build, the code-server password is stored in:

    configs/code-server/.config/code-server/config.yaml\n

    Look for the password: field in that file. For example:

    password: 0c0dca951a2d12eff1665817\n

    Note: It is recommended not to change this password manually, as it is securely generated.

    "},{"location":"config/coder/#main-configuration-options","title":"Main Configuration Options","text":"
    • bind-addr: The address and port code-server listens on (default: 127.0.0.1:8080)
    • auth: Authentication method (default: password)
    • password: The login password (see above)
    • cert: Whether to use HTTPS (default: false)
    "},{"location":"config/coder/#installed-tools-and-features","title":"Installed Tools and Features","text":"

    The code-server environment includes:

    • Node.js 18+ and npm
    • Claude Code (@anthropic-ai/claude-code) globally installed
    • Python 3 and tools:
    • python3-pip, python3-venv, python3-full, pipx
    • Image and PDF processing libraries:
    • CairoSVG, Pillow, libcairo2-dev, libfreetype6-dev, libjpeg-dev, libpng-dev, libwebp-dev, libtiff5-dev, libopenjp2-7-dev, liblcms2-dev
    • weasyprint, fonts-roboto
    • Git for version control and plugin management
    • Build tools: build-essential, pkg-config, python3-dev, zlib1g-dev
    • MkDocs Material and a wide range of MkDocs plugins, installed in a dedicated Python virtual environment at /home/coder/.venv/mkdocs
    • Convenience script: run-mkdocs for running MkDocs commands easily
    "},{"location":"config/coder/#using-mkdocs","title":"Using MkDocs","text":"

    The virtual environment for MkDocs is automatically added to your PATH. You can run MkDocs commands directly, or use the provided script. For example, to build the site, from a clean terminal we would rung:

    cd mkdocs \nmkdocs build\n
    "},{"location":"config/coder/#claude-code-integration","title":"Claude Code Integration","text":"

    The code-server environment comes with Claude Code (@anthropic-ai/claude-code) globally installed via npm.

    "},{"location":"config/coder/#what-is-claude-code","title":"What is Claude Code?","text":"

    Claude Code is an AI-powered coding assistant by Anthropic, designed to help you write, refactor, and understand code directly within your development environment.

    "},{"location":"config/coder/#usage","title":"Usage","text":"
    • Access Claude Code features through the command palette or sidebar in code-server.
    • Use Claude Code to generate code, explain code snippets, or assist with documentation and refactoring tasks.
    • For more information, refer to the Claude Code documentation.

    Note: Claude Code requires an API key or account with Anthropic for full functionality. Refer to the extension settings for configuration.

    "},{"location":"config/coder/#call-claude","title":"Call Claude","text":"

    To use claude simply type claude into the terminal and follow instructions.

    claude\n
    "},{"location":"config/coder/#shell-environment","title":"Shell Environment","text":"

    The .bashrc is configured to include the MkDocs virtual environment and user-local binaries in your PATH for convenience.

    "},{"location":"config/coder/#code-navigation-and-editing-features","title":"Code Navigation and Editing Features","text":"

    The code-server environment provides robust code navigation and editing features, including:

    • IntelliSense: Smart code completions based on variable types, function definitions, and imported modules.
    • Code Navigation: Easily navigate to definitions, references, and symbol searches within your codebase.
    • Debugging Support: Integrated debugging support for Node.js and Python, with breakpoints, call stacks, and interactive consoles.
    • Terminal Access: Built-in terminal access to run commands, scripts, and version control operations.
    "},{"location":"config/coder/#collaboration-features","title":"Collaboration Features","text":"

    Code-server includes features to support collaboration:

    • Live Share: Collaborate in real-time with others, sharing your code and terminal sessions.
    • ChatGPT Integration: AI-powered code assistance and chat-based collaboration.
    "},{"location":"config/coder/#security-considerations","title":"Security Considerations","text":"

    When using code-server, consider the following security aspects:

    • Password Management: The default password is securely generated. Do not share it or expose it in public repositories.
    • Network Security: Ensure that your firewall settings allow access to the code-server port (default: 8080) only from trusted networks.
    • Data Privacy: Be cautious when uploading sensitive data or code to the server. Use environment variables or secure vaults for sensitive information.
    "},{"location":"config/coder/#ollama-integration","title":"Ollama Integration","text":"

    The code-server environment includes Ollama, a tool for running large language models locally on your machine.

    "},{"location":"config/coder/#what-is-ollama","title":"What is Ollama?","text":"

    Ollama is a lightweight, extensible framework for building and running language models locally. It provides a simple API for creating, running, and managing models, making it easy to integrate AI capabilities into your development workflow without relying on external services.

    "},{"location":"config/coder/#getting-started-with-ollama","title":"Getting Started with Ollama","text":""},{"location":"config/coder/#staring-ollama","title":"Staring Ollama","text":"

    For ollama to be available, you need to open a terminal and run:

    ollama serve\n

    This will start the ollama server and you can then proceed to pulling a model and chatting.

    "},{"location":"config/coder/#pulling-a-model","title":"Pulling a Model","text":"

    To get started, you'll need to pull a model. For development and testing, we recommend starting with a smaller model like Gemma 2B:

    ollama pull gemma2:2b\n

    For even lighter resource usage, you can use the 1B parameter version:

    ollama pull gemma2:1b\n
    "},{"location":"config/coder/#running-a-model","title":"Running a Model","text":"

    Once you've pulled a model, you can start an interactive session:

    ollama run gemma2:2b\n
    "},{"location":"config/coder/#available-models","title":"Available Models","text":"

    Popular models available through Ollama include:

    • Gemma 2 (1B, 2B, 9B, 27B): Google's efficient language models
    • Llama 3.2 (1B, 3B, 11B, 90B): Meta's latest language models
    • Qwen 2.5 (0.5B, 1.5B, 3B, 7B, 14B, 32B, 72B): Alibaba's multilingual models
    • Phi 3.5 (3.8B): Microsoft's compact language model
    • Code Llama (7B, 13B, 34B): Specialized for code generation
    "},{"location":"config/coder/#using-ollama-in-your-development-workflow","title":"Using Ollama in Your Development Workflow","text":""},{"location":"config/coder/#api-access","title":"API Access","text":"

    Ollama provides a REST API that runs on http://localhost:11434 by default. You can integrate this into your applications:

    curl http://localhost:11434/api/generate -d '{\n  \"model\": \"gemma2:2b\",\n  \"prompt\": \"Write a Python function to calculate fibonacci numbers\",\n  \"stream\": false\n}'\n
    "},{"location":"config/coder/#model-management","title":"Model Management","text":"

    List installed models:

    ollama list\n

    Remove a model:

    ollama rm gemma2:2b\n

    Show model information:

    ollama show gemma2:2b\n

    "},{"location":"config/coder/#resource-considerations","title":"Resource Considerations","text":"
    • 1B models: Require ~1GB RAM, suitable for basic tasks and resource-constrained environments
    • 2B models: Require ~2GB RAM, good balance of capability and resource usage
    • Larger models: Provide better performance but require significantly more resources
    "},{"location":"config/coder/#integration-with-development-tools","title":"Integration with Development Tools","text":"

    Ollama can be integrated with various development tools and editors through its API, enabling features like:

    • Code completion and generation
    • Documentation writing assistance
    • Code review and explanation
    • Automated testing suggestions

    For more information, visit the Ollama documentation.

    For more detailed information on configuring and using code-server, refer to the official code-server documentation.

    "},{"location":"config/mkdocs/","title":"MkDocs Customization & Features Overview","text":"

    BNKops has been building our own features, widgets, and css styles for MKdocs material theme.

    This document explains the custom styling, repository widgets, and key features enabled in this MkDocs site.

    For more info on how to build your site see Site Build

    "},{"location":"config/mkdocs/#using-the-repository-widget-in-documentation","title":"Using the Repository Widget in Documentation","text":"

    You can embed repository widgets directly in your Markdown documentation to display live repository stats and metadata. To do this, add a div with the appropriate class and data-repo attribute for the repository you want to display.

    Example (for a Gitea repository):

    <div class=\"gitea-widget\" data-repo=\"admin/changemaker.lite\"></div>\n

    This will render a styled card with information about the admin/changemaker.lite repository:

    Options: You can control the widget display with additional data attributes: - data-show-description=\"false\" \u2014 Hide the description - data-show-language=\"false\" \u2014 Hide the language - data-show-last-update=\"false\" \u2014 Hide the last update date

    Example with options:

    <div class=\"gitea-widget\" data-repo=\"admin/changemaker.lite\" data-show-description=\"false\"></div>\n

    For GitHub repositories, use the github-widget class:

    <div class=\"github-widget\" data-repo=\"lyqht/mini-qr\"></div>\n

    "},{"location":"config/mkdocs/#custom-css-styling-stylesheetsextracss","title":"Custom CSS Styling (stylesheets/extra.css)","text":"

    The extra.css file provides extensive custom styling for the site, including:

    • Login and Git Code Buttons: Custom styles for .login-button and .git-code-button to create visually distinct, modern buttons with hover effects.

    • Code Block Improvements: Forces code blocks to wrap text (white-space: pre-wrap) and ensures inline code and tables with code display correctly on all devices.

    • GitHub Widget Styles: Styles for .github-widget and its subcomponents, including:

    • Card-like container with gradient backgrounds and subtle box-shadows.
    • Header with icon, repo link, and stats (stars, forks, issues).
    • Description area with accent border.
    • Footer with language, last update, and license info.
    • Loading and error states with spinners and error messages.
    • Responsive grid layout for multiple widgets.
    • Compact variant for smaller displays.
    • Dark mode adjustments.

    • Gitea Widget Styles: Similar to GitHub widget, but with Gitea branding (green accents). Includes .gitea-widget, .gitea-widget-container, and related classes for header, stats, description, footer, loading, and error states.

    • Responsive Design: Media queries ensure widgets and tables look good on mobile devices.

    "},{"location":"config/mkdocs/#repository-widgets","title":"Repository Widgets","text":""},{"location":"config/mkdocs/#data-generation-hooksrepo_widget_hookpy","title":"Data Generation (hooks/repo_widget_hook.py)","text":"
    • Purpose: During the MkDocs build, this hook fetches metadata for a list of GitHub and Gitea repositories and writes JSON files to docs/assets/repo-data/.
    • How it works:
    • Runs before build (unless in serve mode).
    • Fetches repo data (stars, forks, issues, language, etc.) via GitHub/Gitea APIs.
    • Outputs a JSON file per repo (e.g., lyqht-mini-qr.json).
    • Used by frontend widgets for fast, client-side rendering.
    "},{"location":"config/mkdocs/#github-widget-javascriptsgithub-widgetjs","title":"GitHub Widget (javascripts/github-widget.js)","text":"
    • Purpose: Renders a card for each GitHub repository using the pre-generated JSON data.
    • Features:
    • Displays repo name, link, stars, forks, open issues, language, last update, and license.
    • Shows loading spinner while fetching data.
    • Handles errors gracefully.
    • Supports dynamic content (re-initializes on DOM changes).
    • Language color coding for popular languages.
    "},{"location":"config/mkdocs/#gitea-widget-javascriptsgitea-widgetjs","title":"Gitea Widget (javascripts/gitea-widget.js)","text":"
    • Purpose: Renders a card for each Gitea repository using the pre-generated JSON data.
    • Features:
    • Similar to GitHub widget, but styled for Gitea.
    • Shows repo name, link, stars, forks, open issues, language, last update.
    • Loading and error states.
    • Language color coding.
    "},{"location":"config/mkdocs/#mkdocs-features-mkdocsyml","title":"MkDocs Features (mkdocs.yml)","text":"

    Key features and plugins enabled:

    • Material Theme: Modern, responsive UI with dark/light mode toggle, custom fonts, and accent colors.

    • Navigation Enhancements:

    • Tabs, sticky navigation, instant loading, breadcrumbs, and sectioned navigation.
    • Table of contents with permalinks.

    • Content Features:

    • Code annotation, copy buttons, tooltips, and improved code highlighting.
    • Admonitions, tabbed content, task lists, and emoji support.

    • Plugins:

    • Search: Advanced search with custom tokenization.
    • Social: OpenGraph/social card generation.
    • Blog: Blogging support with archives and categories.
    • Tags: Tagging for content organization.

    • Custom Hooks:

    • repo_widget_hook.py for repository widget data.

    • Extra CSS/JS:

    • Custom styles and scripts for widgets and homepage.

    • Extra Configuration:

    • Social links, copyright.
    "},{"location":"config/mkdocs/#summary","title":"Summary","text":"

    This MkDocs site is highly customized for developer documentation, with visually rich repository widgets, improved code and table rendering, and a modern, responsive UI. All repository stats are fetched at build time for performance and reliability.

    "},{"location":"phil/","title":"Philosophy: Your Secrets, Your Power, Your Movement","text":""},{"location":"phil/#the-question-that-changes-everything","title":"The Question That Changes Everything","text":"

    If you are a political actor, who do you trust with your secrets?

    This isn't just a technical question\u2014it's the core political question of our time. Every email you send, every document you create, every contact list you build, every strategy you develop: where does it live? Who owns the servers? Who has the keys?

    "},{"location":"phil/#the-corporate-extraction-machine","title":"The Corporate Extraction Machine","text":""},{"location":"phil/#how-they-hook-you","title":"How They Hook You","text":"

    Corporate software companies have perfected the art of digital snake oil sales:

    1. Free Trials - They lure you in with \"free\" accounts
    2. Feature Creep - Essential features require paid tiers
    3. Data Lock-In - Your data becomes harder to export
    4. Price Escalation - $40/month becomes $750/month as you grow
    5. Surveillance Integration - Your organizing becomes their intelligence
    "},{"location":"phil/#the-real-product","title":"The Real Product","text":"

    You Are Not the Customer

    If you're not paying for the product, you ARE the product. But even when you are paying, you're often still the product.

    Corporate platforms don't make money from your subscription fees\u2014they make money from:

    • Data Sales to third parties
    • Algorithmic Manipulation for corporate and political interests
    • Surveillance Contracts with governments and corporations
    • Predictive Analytics about your community and movement
    "},{"location":"phil/#the-bnkops-alternative","title":"The BNKops Alternative","text":""},{"location":"phil/#who-we-are","title":"Who We Are","text":"

    BNKops is a cooperative based in amiskwaciy-w\u00e2skahikan (Edmonton, Alberta) on Treaty 6 territory. We're not a corporation\u2014we're a collective of skilled organizers, developers, and community builders who believe technology should serve liberation, not oppression.

    "},{"location":"phil/#our-principles","title":"Our Principles","text":""},{"location":"phil/#liberation-first","title":"\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f \ud83c\udff3\ufe0f\u200d\ud83c\udf08 \ud83c\uddf5\ud83c\uddf8 Liberation First","text":"

    Technology that centers the most marginalized voices and fights for collective liberation. We believe strongly that the medium is the message; if you the use the medium of fascists, what does that say about your movement?

    "},{"location":"phil/#community-over-profit","title":"\ud83e\udd1d Community Over Profit","text":"

    We operate as a cooperative because we believe in shared ownership and democratic decision-making. No venture capitalists, no shareholders, no extraction.

    "},{"location":"phil/#data-sovereignty","title":"\u26a1 Data Sovereignty","text":"

    Your data belongs to you and your community. We build tools that let you own your digital infrastructure completely.

    "},{"location":"phil/#security-culture","title":"\ud83d\udd12 Security Culture","text":"

    Real security comes from community control, not corporate promises. We integrate security culture practices into our technology design.

    "},{"location":"phil/#the-changemaker-difference","title":"The Changemaker Difference","text":""},{"location":"phil/#traditional-corporate-flow","title":"Traditional Corporate Flow","text":"
    Your Data \u2192 Corporate Server \u2192 Surveillance \u2192 Profit \u2192 Your Oppression\n
    "},{"location":"phil/#changemaker-flow","title":"Changemaker Flow","text":"
    Your Data \u2192 Your Server \u2192 Your Community \u2192 Your Power \u2192 Liberation\n
    "},{"location":"phil/#why-this-matters","title":"Why This Matters","text":"

    When you control your technology infrastructure:

    • Your secrets stay secret - No corporate access to sensitive organizing data
    • Your community stays connected - No algorithmic manipulation of your reach
    • Your costs stay low - No extraction-based pricing as you grow
    • Your future stays yours - No vendor lock-in or platform dependency
    "},{"location":"phil/#the-philosophy-in-practice","title":"The Philosophy in Practice","text":""},{"location":"phil/#security-culture-meets-technology","title":"Security Culture Meets Technology","text":"

    Traditional security culture asks: \"Who needs to know this information?\"

    Digital security culture asks: \"Who controls the infrastructure where this information lives?\"

    "},{"location":"phil/#community-technology","title":"Community Technology","text":"

    We believe in community technology - tools that:

    • Are owned and controlled by the communities that use them
    • Are designed with liberation politics from the ground up
    • Prioritize care, consent, and collective power
    • Can be understood, modified, and improved by community members
    "},{"location":"phil/#prefigurative-politics","title":"Prefigurative Politics","text":"

    The tools we use shape the movements we build. Corporate tools create corporate movements\u2014hierarchical, surveilled, and dependent. Community-controlled tools create community-controlled movements\u2014democratic, secure, and sovereign.

    "},{"location":"phil/#common-questions","title":"Common Questions","text":""},{"location":"phil/#isnt-this-just-for-tech-people","title":"\"Isn't this just for tech people?\"","text":"

    No. We specifically designed Changemaker Lite for organizers, activists, and movement builders who may not have technical backgrounds. Our philosophy is that everyone deserves digital sovereignty, not just people with computer science degrees.

    This is not to say that you won't need to learn! These tools are just that; tools. They have no fancy or white-labeled marketing and are technical in nature. You will need to learn to use them, just as any worker needs to learn the power tools they use on the job.

    "},{"location":"phil/#what-about-convenience","title":"\"What about convenience?\"","text":"

    Corporate platforms are convenient because they've extracted billions of dollars from users to fund that convenience. When you own your tools, there's a learning curve\u2014but it's the same learning curve as learning to organize, learning to build power, learning to create change.

    "},{"location":"phil/#cant-we-just-use-corporate-tools-carefully","title":"\"Can't we just use corporate tools carefully?\"","text":"

    Would you hold your most sensitive organizing meetings in a room owned by your opposition? Would you store your membership lists in filing cabinets at a corporation that profits from surveillance? Digital tools are the same.

    "},{"location":"phil/#what-about-security","title":"\"What about security?\"","text":"

    Real security comes from community control, not corporate promises. When you control your infrastructure:

    • You decide what gets logged and what doesn't
    • You choose who has access and who doesn't
    • You know exactly where your data is and who can see it
    • You can't be de-platformed or locked out of your own data
    "},{"location":"phil/#historical-context","title":"Historical Context","text":""},{"location":"phil/#learning-from-past-struggles","title":"Learning from Past Struggles","text":"

    Every liberation movement has had to solve the problem of secure communication and information sharing:

    • Underground Railroad - Coded songs and safe houses
    • Labor Movement - Secret meetings and encrypted telegrams
    • Civil Rights Movement - CB radios and phone trees
    • LGBTQ+ Liberation - Chosen families and community networks

    The internet should expand these traditions, not replace them with corporate surveillance.

    "},{"location":"phil/#the-surveillance-capitalism-trap","title":"The Surveillance Capitalism Trap","text":"

    As Shoshana Zuboff documents in \"The Age of Surveillance Capitalism,\" we're living through a new form of capitalism that extracts value from human experience itself. Political movements are particularly valuable targets because:

    • Political data predicts behavior
    • Movement intelligence can be used to counter-organize
    • Community networks can be mapped and disrupted
    • Organizing strategies can be monitored and neutralized
    "},{"location":"phil/#taking-action","title":"Taking Action","text":""},{"location":"phil/#start-where-you-are","title":"Start Where You Are","text":"

    You don't have to replace everything at once. Start with one tool, one campaign, one project. Learn the technology alongside your organizing.

    "},{"location":"phil/#build-community-capacity","title":"Build Community Capacity","text":"

    The goal isn't individual self-sufficiency\u2014it's community technological sovereignty. Share skills, pool resources, learn together.

    "},{"location":"phil/#connect-with-others","title":"Connect with Others","text":"

    You're not alone in this. The free and open source software community, the digital security community, and the appropriate technology movement are all working on similar problems.

    "},{"location":"phil/#remember-why","title":"Remember Why","text":"

    This isn't about technology for its own sake. It's about building the infrastructure for the world we want to see\u2014where communities have power, where people control their own data, where technology serves liberation.

    "},{"location":"phil/#resources-for-deeper-learning","title":"Resources for Deeper Learning","text":""},{"location":"phil/#essential-reading","title":"Essential Reading","text":"
    • De-corp Your Software Stack - Our full manifesto
    • The Age of Surveillance Capitalism by Shoshana Zuboff
    • Security Culture Handbook
    "},{"location":"phil/#community-resources","title":"Community Resources","text":"
    • BNKops Repository - Documentation and knowledge base
    • Activist Handbook - Movement building resources
    • EFF Surveillance Self-Defense - Digital security guides
    "},{"location":"phil/#technical-learning","title":"Technical Learning","text":"
    • Self-Hosted Awesome List - Open source alternatives
    • Linux Journey - Learn Linux basics
    • Docker Curriculum - Learn containerization

    This philosophy document is a living document. Contribute your thoughts, experiences, and improvements through the BNKops documentation platform.

    "},{"location":"phil/cost-comparison/","title":"Cost Comparison: Corporation vs. Community","text":""},{"location":"phil/cost-comparison/#the-true-cost-of-corporate-dependency","title":"The True Cost of Corporate Dependency","text":"

    When movements choose corporate software, they're not just paying subscription fees\u2014they're paying with their power, their privacy, and their future. Let's break down the real costs.

    "},{"location":"phil/cost-comparison/#monthly-cost-analysis","title":"Monthly Cost Analysis","text":""},{"location":"phil/cost-comparison/#small-campaign-50-supporters-5000-emailsmonth","title":"Small Campaign (50 supporters, 5,000 emails/month)","text":"Service Category Corporate Solution Monthly Cost Changemaker Lite Monthly Cost Email Marketing Mailchimp $59/month Listmonk $0* Database & CRM Airtable Pro $240/month NocoDB $0* Website Hosting Squarespace $40/month Static Server $0* Documentation Notion Team $96/month MkDocs $0* Development GitHub Codespaces $87/month Code Server $0* Automation Zapier Professional $73/month n8n $0* File Storage Google Workspace $72/month PostgreSQL + Storage $0* Analytics Corporate tracking Privacy cost\u2020 Self-hosted $0* TOTAL $667/month $50/month

    *Included in base Changemaker Lite hosting cost \u2020Privacy costs are incalculable but include surveillance, data sales, and community manipulation

    "},{"location":"phil/cost-comparison/#medium-campaign-500-supporters-50000-emailsmonth","title":"Medium Campaign (500 supporters, 50,000 emails/month)","text":"Service Category Corporate Solution Monthly Cost Changemaker Lite Monthly Cost Email Marketing Mailchimp $299/month Listmonk $0* Database & CRM Airtable Pro $600/month NocoDB $0* Website Hosting Squarespace $65/month Static Server $0* Documentation Notion Team $240/month MkDocs $0* Development GitHub Codespaces $174/month Code Server $0* Automation Zapier Professional $146/month n8n $0* File Storage Google Workspace $144/month PostgreSQL + Storage $0* Analytics Corporate tracking Privacy cost\u2020 Self-hosted $0* TOTAL $1,668/month $75/month"},{"location":"phil/cost-comparison/#large-campaign-5000-supporters-500000-emailsmonth","title":"Large Campaign (5,000 supporters, 500,000 emails/month)","text":"Service Category Corporate Solution Monthly Cost Changemaker Lite Monthly Cost Email Marketing Mailchimp $1,499/month Listmonk $0* Database & CRM Airtable Pro $1,200/month NocoDB $0* Website Hosting Squarespace + CDN $120/month Static Server $0* Documentation Notion Team $480/month MkDocs $0* Development GitHub Codespaces $348/month Code Server $0* Automation Zapier Professional $292/month n8n $0* File Storage Google Workspace $288/month PostgreSQL + Storage $0* Analytics Corporate tracking Privacy cost\u2020 Self-hosted $0* TOTAL $4,227/month $150/month"},{"location":"phil/cost-comparison/#annual-savings-breakdown","title":"Annual Savings Breakdown","text":""},{"location":"phil/cost-comparison/#3-year-cost-comparison","title":"3-Year Cost Comparison","text":"Campaign Size Corporate Total Changemaker Total Savings Small $24,012 $1,800 $22,212 Medium $60,048 $2,700 $57,348 Large $152,172 $5,400 $146,772"},{"location":"phil/cost-comparison/#hidden-costs-of-corporate-software","title":"Hidden Costs of Corporate Software","text":""},{"location":"phil/cost-comparison/#what-you-cant-put-a-price-on","title":"What You Can't Put a Price On","text":""},{"location":"phil/cost-comparison/#privacy-violations","title":"Privacy Violations","text":"
    • Data Harvesting: Every interaction monitored and stored
    • Behavioral Profiling: Your community mapped and analyzed
    • Third-Party Sales: Your data sold to unknown entities
    • Government Access: Warrantless surveillance through corporate partnerships
    "},{"location":"phil/cost-comparison/#political-manipulation","title":"Political Manipulation","text":"
    • Algorithmic Suppression: Your content reach artificially limited
    • Narrative Control: Corporate interests shape what your community sees
    • Shadow Banning: Activists systematically de-platformed
    • Counter-Intelligence: Your strategies monitored by opposition
    "},{"location":"phil/cost-comparison/#movement-disruption","title":"Movement Disruption","text":"
    • Dependency Creation: Critical infrastructure controlled by adversaries
    • Community Fragmentation: Platforms designed to extract attention, not build power
    • Organizing Interference: Corporate algorithms prioritize engagement over solidarity
    • Cultural Assimilation: Movement culture shaped by corporate values
    "},{"location":"phil/cost-comparison/#the-changemaker-advantage","title":"The Changemaker Advantage","text":""},{"location":"phil/cost-comparison/#what-you-get-for-50-150month","title":"What You Get for $50-150/month","text":""},{"location":"phil/cost-comparison/#complete-infrastructure","title":"Complete Infrastructure","text":"
    • Email System: Unlimited contacts, unlimited sends
    • Database Power: Unlimited records, unlimited complexity
    • Web Presence: Unlimited sites, unlimited traffic
    • Development Environment: Full coding environment with AI assistance
    • Documentation Platform: Beautiful, searchable knowledge base
    • Automation Engine: Connect everything, automate everything
    • File Storage: Unlimited files, unlimited backups
    "},{"location":"phil/cost-comparison/#true-ownership","title":"True Ownership","text":"
    • Your Domain: No corporate branding or limitations
    • Your Data: Complete export capability, no lock-in
    • Your Rules: No terms of service to violate
    • Your Community: No algorithmic manipulation
    "},{"location":"phil/cost-comparison/#community-support","title":"Community Support","text":"
    • Open Documentation: Complete guides and tutorials available
    • Community-Driven Development: Built by and for liberation movements
    • Technical Support: Professional assistance from BNKops cooperative
    • Political Alignment: Technology designed with movement values
    "},{"location":"phil/cost-comparison/#the-compound-effect","title":"The Compound Effect","text":""},{"location":"phil/cost-comparison/#year-over-year-savings","title":"Year Over Year Savings","text":"

    Corporate software costs grow exponentially: - Year 1: \"Starter\" pricing to hook you - Year 2: Feature limits force tier upgrades - Year 3: Usage growth triggers premium pricing - Year 4: Platform changes force expensive migrations - Year 5: Lock-in enables arbitrary price increases

    Changemaker Lite costs grow linearly with actual infrastructure needs: - Year 1: Base infrastructure costs - Year 2: Modest increases for storage/bandwidth only - Year 3: Scale only with actual technical requirements - Year 4: Community-driven improvements at no extra cost - Year 5: Established infrastructure with declining per-user costs

    "},{"location":"phil/cost-comparison/#10-year-projection","title":"10-Year Projection","text":"Year Corporate (Medium Campaign) Changemaker Lite Annual Savings 1 $20,016 $900 $19,116 2 $22,017 $900 $21,117 3 $24,219 $1,080 $23,139 4 $26,641 $1,080 $25,561 5 $29,305 $1,260 $28,045 6 $32,235 $1,260 $30,975 7 $35,459 $1,440 $34,019 8 $39,005 $1,440 $37,565 9 $42,905 $1,620 $41,285 10 $47,196 $1,620 $45,576 TOTAL $318,998 $12,600 $306,398"},{"location":"phil/cost-comparison/#calculate-your-own-savings","title":"Calculate Your Own Savings","text":""},{"location":"phil/cost-comparison/#current-corporate-costs-worksheet","title":"Current Corporate Costs Worksheet","text":"

    Email Marketing: $____/month Database/CRM: $____/month Website Hosting: $____/month Documentation: $____/month Development Tools: $____/month Automation: $____/month File Storage: $____/month Other SaaS: $____/month

    Monthly Total: $____ Annual Total: $____

    Changemaker Alternative: $50-150/month Your Annual Savings: $____

    "},{"location":"phil/cost-comparison/#beyond-the-numbers","title":"Beyond the Numbers","text":""},{"location":"phil/cost-comparison/#what-movements-do-with-their-savings","title":"What Movements Do With Their Savings","text":"

    The money saved by choosing community-controlled technology doesn't disappear\u2014it goes directly back into movement building:

    • Hire organizers instead of paying corporate executives
    • Fund direct actions instead of funding surveillance infrastructure
    • Support community members instead of enriching shareholders
    • Build lasting power instead of temporary platform dependency
    "},{"location":"phil/cost-comparison/#making-the-switch","title":"Making the Switch","text":""},{"location":"phil/cost-comparison/#transition-strategy","title":"Transition Strategy","text":"

    You don't have to switch everything at once:

    1. Start with documentation - Move your knowledge base to MkDocs
    2. Add email infrastructure - Set up Listmonk for newsletters
    3. Build your database - Move contact management to NocoDB
    4. Automate connections - Use n8n to integrate everything
    5. Phase out corporate tools - Cancel subscriptions as you replicate functionality
    "},{"location":"phil/cost-comparison/#investment-timeline","title":"Investment Timeline","text":"
    • Month 1: Initial setup and learning ($150 including setup time)
    • Month 2-3: Data migration and team training ($100/month)
    • Month 4+: Full operation at optimal cost ($50-150/month based on scale)
    "},{"location":"phil/cost-comparison/#roi-calculation","title":"ROI Calculation","text":"

    Most campaigns recover their entire first-year investment in 60-90 days through subscription savings alone.

    Ready to stop feeding your budget to corporate surveillance? Get started with Changemaker Lite today and take control of your digital infrastructure.

    "},{"location":"services/","title":"Services","text":"

    Changemaker Lite includes several powerful services that work together to provide a complete documentation and development platform. Each service is containerized and can be accessed through its dedicated port.

    "},{"location":"services/#available-services","title":"Available Services","text":""},{"location":"services/#code-server","title":"Code Server","text":"

    Port: 8888 | Visual Studio Code in your browser for remote development

    • Full IDE experience
    • Extensions support
    • Git integration
    • Terminal access
    "},{"location":"services/#listmonk","title":"Listmonk","text":"

    Port: 9000 | Self-hosted newsletter and mailing list manager

    • Email campaigns
    • Subscriber management
    • Analytics
    • Template system
    "},{"location":"services/#postgresql","title":"PostgreSQL","text":"

    Port: 5432 | Reliable database backend - Data persistence for Listmonk - ACID compliance - High performance - Backup and restore capabilities

    "},{"location":"services/#mkdocs-material","title":"MkDocs Material","text":"

    Port: 4000 | Documentation site generator with live preview

    • Material Design theme
    • Live reload
    • Search functionality
    • Markdown support
    "},{"location":"services/#static-site-server","title":"Static Site Server","text":"

    Port: 4001 | Nginx-powered static site hosting - High-performance serving - Built documentation hosting - Caching and compression - Security headers

    "},{"location":"services/#n8n","title":"n8n","text":"

    Port: 5678 | Workflow automation tool

    • Visual workflow editor
    • 400+ integrations
    • Custom code execution
    • Webhook support
    "},{"location":"services/#nocodb","title":"NocoDB","text":"

    Port: 8090 | No-code database platform

    • Smart spreadsheet interface
    • Form builder and API generation
    • Real-time collaboration
    • Multi-database support
    "},{"location":"services/#homepage","title":"Homepage","text":"

    Port: 3010 | Modern dashboard for all services

    • Service dashboard and monitoring
    • Docker integration
    • Customizable layout
    • Quick search and bookmarks
    "},{"location":"services/#gitea","title":"Gitea","text":"

    Port: 3030 | Self-hosted Git service

    • Git repository hosting
    • Web-based interface
    • Issue tracking
    • Pull requests
    • Wiki and code review
    • Lightweight and easy to deploy
    "},{"location":"services/#mini-qr","title":"Mini QR","text":"

    Port: 8089 | Simple QR code generator service

    • Generate QR codes for text or URLs
    • Download QR codes as images
    • Simple and fast interface
    • No user registration required
    "},{"location":"services/#service-architecture","title":"Service Architecture","text":"
    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502   Homepage      \u2502    \u2502   Code Server   \u2502    \u2502     MkDocs      \u2502\n\u2502     :3010       \u2502    \u2502     :8888       \u2502    \u2502     :4000       \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 Static Server   \u2502    \u2502    Listmonk     \u2502    \u2502      n8n        \u2502\n\u2502     :4001       \u2502    \u2502     :9000       \u2502    \u2502     :5678       \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502     NocoDB      \u2502    \u2502 PostgreSQL      \u2502    \u2502 PostgreSQL      \u2502\n\u2502     :8090       \u2502    \u2502 (listmonk-db)   \u2502    \u2502 (root_db)       \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2502     :5432       \u2502    \u2502     :5432       \u2502\n         \u2502              \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n         \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n
    "},{"location":"services/#getting-started","title":"Getting Started","text":"
    1. Start all services: docker compose up -d
    2. Check service status: docker compose ps
    3. View logs: docker compose logs [service-name]
    4. Stop services: docker compose down
    "},{"location":"services/#service-dependencies","title":"Service Dependencies","text":"
    • Listmonk depends on PostgreSQL (listmonk-db)
    • NocoDB depends on PostgreSQL (root_db)
    • Static Server serves content built by MkDocs
    • n8n can integrate with all other services
    • All services share the changemaker network
    "},{"location":"services/#environment-configuration","title":"Environment Configuration","text":"

    Services are configured through environment variables in your .env file:

    # Port configurations\nCODE_SERVER_PORT=8888\nLISTMONK_PORT=9000\nLISTMONK_DB_PORT=5432\nMKDOCS_PORT=4000\nMKDOCS_SITE_SERVER_PORT=4001\nN8N_PORT=5678\n\n# User and group IDs\nUSER_ID=1000\nGROUP_ID=1000\n\n# Database configuration\nPOSTGRES_USER=listmonk\nPOSTGRES_PASSWORD=your_password\nPOSTGRES_DB=listmonk\n\n# n8n configuration\nN8N_ENCRYPTION_KEY=your_encryption_key\nN8N_USER_EMAIL=admin@example.com\nN8N_USER_PASSWORD=your_password\n
    "},{"location":"services/#monitoring-and-maintenance","title":"Monitoring and Maintenance","text":""},{"location":"services/#health-checks","title":"Health Checks","text":"
    # Check all services\ndocker compose ps\n\n# Check specific service logs\ndocker compose logs listmonk-app\ndocker compose logs code-server\n
    "},{"location":"services/#updates","title":"Updates","text":"
    # Pull latest images\ndocker compose pull\n\n# Restart with new images\ndocker compose down && docker compose up -d\n
    "},{"location":"services/#backups","title":"Backups","text":"
    • PostgreSQL: Regular database backups
    • n8n: Export workflows and credentials
    • Code Server: Backup configuration and workspace
    • MkDocs: Version control your documentation
    "},{"location":"services/#troubleshooting","title":"Troubleshooting","text":""},{"location":"services/#common-issues","title":"Common Issues","text":"
    1. Port Conflicts: Ensure ports are not used by other applications
    2. Permission Issues: Check USER_ID and GROUP_ID settings
    3. Network Issues: Verify services can communicate through the changemaker network
    4. Data Persistence: Ensure volumes are properly mounted
    "},{"location":"services/#getting-help","title":"Getting Help","text":"
    • Check individual service documentation
    • Review container logs for error messages
    • Verify environment variable configuration
    • Test network connectivity between services
    "},{"location":"services/code-server/","title":"Code Server","text":""},{"location":"services/code-server/#overview","title":"Overview","text":"

    Code Server provides a full Visual Studio Code experience in your web browser, allowing you to develop from any device. It runs on your server and provides access to your development environment through a web interface.

    "},{"location":"services/code-server/#features","title":"Features","text":"
    • Full VS Code experience in the browser
    • Extensions support
    • Terminal access
    • Git integration
    • File editing and management
    • Multi-language support
    "},{"location":"services/code-server/#access","title":"Access","text":"
    • Default Port: 8888
    • URL: http://localhost:8888
    • Default Workspace: /home/coder/mkdocs/
    "},{"location":"services/code-server/#configuration","title":"Configuration","text":""},{"location":"services/code-server/#environment-variables","title":"Environment Variables","text":"
    • DOCKER_USER: The user to run code-server as (default: coder)
    • DEFAULT_WORKSPACE: Default workspace directory
    • USER_ID: User ID for file permissions
    • GROUP_ID: Group ID for file permissions
    "},{"location":"services/code-server/#volumes","title":"Volumes","text":"
    • ./configs/code-server/.config: VS Code configuration
    • ./configs/code-server/.local: Local data
    • ./mkdocs: Main workspace directory
    "},{"location":"services/code-server/#usage","title":"Usage","text":"
    1. Access Code Server at http://localhost:8888
    2. Open the /home/coder/mkdocs/ workspace
    3. Start editing your documentation files
    4. Install extensions as needed
    5. Use the integrated terminal for commands
    "},{"location":"services/code-server/#useful-extensions","title":"Useful Extensions","text":"

    Consider installing these extensions for better documentation work:

    • Markdown All in One
    • Material Design Icons
    • GitLens
    • Docker
    • YAML
    "},{"location":"services/code-server/#official-documentation","title":"Official Documentation","text":"

    For more detailed information, visit the official Code Server documentation.

    "},{"location":"services/gitea/","title":"Gitea","text":"

    Self-hosted Git service for collaborative development.

    "},{"location":"services/gitea/#overview","title":"Overview","text":"

    Gitea is a lightweight, self-hosted Git service similar to GitHub, GitLab, and Bitbucket. It provides a web interface for managing repositories, issues, pull requests, and more.

    "},{"location":"services/gitea/#features","title":"Features","text":"
    • Git repository hosting
    • Web-based interface
    • Issue tracking
    • Pull requests
    • Wiki and code review
    • Lightweight and easy to deploy
    "},{"location":"services/gitea/#access","title":"Access","text":"
    • Default Web Port: ${GITEA_WEB_PORT:-3030} (default: 3030)
    • Default SSH Port: ${GITEA_SSH_PORT:-2222} (default: 2222)
    • URL: http://localhost:${GITEA_WEB_PORT:-3030}
    • Default Data Directory: /data/gitea
    "},{"location":"services/gitea/#configuration","title":"Configuration","text":""},{"location":"services/gitea/#environment-variables","title":"Environment Variables","text":"
    • GITEA__database__DB_TYPE: Database type (e.g., sqlite3, mysql, postgres)
    • GITEA__database__HOST: Database host (default: ${GITEA_DB_HOST:-gitea-db:3306})
    • GITEA__database__NAME: Database name (default: ${GITEA_DB_NAME:-gitea})
    • GITEA__database__USER: Database user (default: ${GITEA_DB_USER:-gitea})
    • GITEA__database__PASSWD: Database password (from .env)
    • GITEA__server__ROOT_URL: Root URL (e.g., ${GITEA_ROOT_URL})
    • GITEA__server__HTTP_PORT: Web port (default: 3000 inside container)
    • GITEA__server__DOMAIN: Domain (e.g., ${GITEA_DOMAIN})
    "},{"location":"services/gitea/#volumes","title":"Volumes","text":"
    • gitea_data:/data: Gitea configuration and data
    • /etc/timezone:/etc/timezone:ro
    • /etc/localtime:/etc/localtime:ro
    "},{"location":"services/gitea/#usage","title":"Usage","text":"
    1. Access Gitea at http://localhost:${GITEA_WEB_PORT:-3030}
    2. Register or log in as an admin user
    3. Create or import repositories
    4. Collaborate with your team
    "},{"location":"services/gitea/#official-documentation","title":"Official Documentation","text":"

    For more details, visit the official Gitea documentation.

    "},{"location":"services/homepage/","title":"Homepage","text":"

    Modern dashboard for accessing all your self-hosted services.

    "},{"location":"services/homepage/#overview","title":"Overview","text":"

    Homepage is a modern, fully static, fast, secure fully configurable application dashboard with integrations for over 100 services. It provides a beautiful and customizable interface to access all your Changemaker Lite services from a single location.

    "},{"location":"services/homepage/#features","title":"Features","text":"
    • Service Dashboard: Central hub for all your applications
    • Docker Integration: Automatic service discovery and monitoring
    • Customizable Layout: Flexible grid-based layout system
    • Service Widgets: Live status and metrics for services
    • Quick Search: Fast navigation with built-in search
    • Bookmarks: Organize frequently used links
    • Dark/Light Themes: Multiple color schemes available
    • Responsive Design: Works on desktop and mobile devices
    "},{"location":"services/homepage/#access","title":"Access","text":"
    • Default Port: 3010
    • URL: http://localhost:3010
    • Configuration: YAML-based configuration files
    "},{"location":"services/homepage/#configuration","title":"Configuration","text":""},{"location":"services/homepage/#environment-variables","title":"Environment Variables","text":"
    • HOMEPAGE_PORT: External port mapping (default: 3010)
    • PUID: User ID for file permissions (default: 1000)
    • PGID: Group ID for file permissions (default: 1000)
    • TZ: Timezone setting (default: Etc/UTC)
    • HOMEPAGE_ALLOWED_HOSTS: Allowed hosts for the dashboard
    "},{"location":"services/homepage/#configuration-files","title":"Configuration Files","text":"

    Homepage uses YAML configuration files located in ./configs/homepage/:

    • settings.yaml: Global settings and theme configuration
    • services.yaml: Service definitions and widgets
    • bookmarks.yaml: Bookmark categories and links
    • widgets.yaml: Dashboard widgets configuration
    • docker.yaml: Docker integration settings
    "},{"location":"services/homepage/#volumes","title":"Volumes","text":"
    • ./configs/homepage:/app/config: Configuration files
    • ./assets/icons:/app/public/icons: Custom service icons
    • ./assets/images:/app/public/images: Background images and assets
    • /var/run/docker.sock:/var/run/docker.sock: Docker socket for container monitoring
    "},{"location":"services/homepage/#changemaker-lite-services","title":"Changemaker Lite Services","text":"

    Homepage is pre-configured with all Changemaker Lite services:

    "},{"location":"services/homepage/#essential-tools","title":"Essential Tools","text":"
    • Code Server (Port 8888): VS Code in the browser
    • Listmonk (Port 9000): Newsletter & mailing list manager
    • NocoDB (Port 8090): No-code database platform
    "},{"location":"services/homepage/#content-documentation","title":"Content & Documentation","text":"
    • MkDocs (Port 4000): Live documentation server
    • Static Site (Port 4001): Built documentation hosting
    "},{"location":"services/homepage/#automation-data","title":"Automation & Data","text":"
    • n8n (Port 5678): Workflow automation platform
    • PostgreSQL (Port 5432): Database backends
    "},{"location":"services/homepage/#customization","title":"Customization","text":""},{"location":"services/homepage/#adding-custom-services","title":"Adding Custom Services","text":"

    Edit configs/homepage/services.yaml to add new services:

    - Custom Category:\n    - My Service:\n        href: http://localhost:8080\n        description: Custom service description\n        icon: mdi-application\n        widget:\n          type: ping\n          url: http://localhost:8080\n
    "},{"location":"services/homepage/#custom-icons","title":"Custom Icons","text":"

    Add custom icons to ./assets/icons/ directory and reference them in services.yaml:

    icon: /icons/my-custom-icon.png\n
    "},{"location":"services/homepage/#themes-and-styling","title":"Themes and Styling","text":"

    Modify configs/homepage/settings.yaml to customize appearance:

    theme: dark  # or light\ncolor: purple  # slate, gray, zinc, neutral, stone, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose\n
    "},{"location":"services/homepage/#widgets","title":"Widgets","text":"

    Enable live monitoring widgets in configs/homepage/services.yaml:

    - Service Name:\n    widget:\n      type: docker\n      container: container-name\n      server: my-docker\n
    "},{"location":"services/homepage/#service-monitoring","title":"Service Monitoring","text":"

    Homepage can display real-time status information for your services:

    • Docker Integration: Container status and resource usage
    • HTTP Ping: Service availability monitoring
    • Custom APIs: Integration with service-specific APIs
    "},{"location":"services/homepage/#docker-integration","title":"Docker Integration","text":"

    Homepage monitors Docker containers automatically when configured:

    1. Ensure Docker socket is mounted (/var/run/docker.sock)
    2. Configure container mappings in docker.yaml
    3. Add widget configurations to services.yaml
    "},{"location":"services/homepage/#security-considerations","title":"Security Considerations","text":"
    • Homepage runs with limited privileges
    • Configuration files should have appropriate permissions
    • Consider network isolation for production deployments
    • Use HTTPS for external access
    • Regularly update the Homepage image
    "},{"location":"services/homepage/#troubleshooting","title":"Troubleshooting","text":""},{"location":"services/homepage/#common-issues","title":"Common Issues","text":"

    Configuration not loading: Check YAML syntax in configuration files

    docker logs homepage-changemaker\n

    Icons not displaying: Verify icon paths and file permissions

    ls -la ./assets/icons/\n

    Services not reachable: Verify network connectivity between containers

    docker exec homepage-changemaker ping service-name\n

    Widget data not updating: Check Docker socket permissions and container access

    docker exec homepage-changemaker ls -la /var/run/docker.sock\n
    "},{"location":"services/homepage/#configuration-examples","title":"Configuration Examples","text":""},{"location":"services/homepage/#basic-service-widget","title":"Basic Service Widget","text":"
    - Code Server:\n    href: http://localhost:8888\n    description: VS Code in the browser\n    icon: code-server\n    widget:\n      type: docker\n      container: code-server-changemaker\n
    "},{"location":"services/homepage/#custom-dashboard-layout","title":"Custom Dashboard Layout","text":"
    # settings.yaml\nlayout:\n  style: columns\n  columns: 3\n\n# Responsive breakpoints\nresponsive:\n  mobile: 1\n  tablet: 2\n  desktop: 3\n
    "},{"location":"services/homepage/#official-documentation","title":"Official Documentation","text":"

    For comprehensive configuration guides and advanced features:

    • Homepage Documentation
    • GitHub Repository
    • Configuration Examples
    • Widget Integrations
    "},{"location":"services/listmonk/","title":"Listmonk","text":"

    Self-hosted newsletter and mailing list manager.

    "},{"location":"services/listmonk/#overview","title":"Overview","text":"

    Listmonk is a modern, feature-rich newsletter and mailing list manager designed for high performance and easy management. It provides a complete solution for email campaigns, subscriber management, and analytics.

    "},{"location":"services/listmonk/#features","title":"Features","text":"
    • Newsletter and email campaign management
    • Subscriber list management
    • Template system with HTML/markdown support
    • Campaign analytics and tracking
    • API for integration
    • Multi-list support
    • Bounce handling
    • Privacy-focused design
    "},{"location":"services/listmonk/#access","title":"Access","text":"
    • Default Port: 9000
    • URL: http://localhost:9000
    • Admin User: Set via LISTMONK_ADMIN_USER environment variable
    • Admin Password: Set via LISTMONK_ADMIN_PASSWORD environment variable
    "},{"location":"services/listmonk/#configuration","title":"Configuration","text":""},{"location":"services/listmonk/#environment-variables","title":"Environment Variables","text":"
    • LISTMONK_ADMIN_USER: Admin username
    • LISTMONK_ADMIN_PASSWORD: Admin password
    • POSTGRES_USER: Database username
    • POSTGRES_PASSWORD: Database password
    • POSTGRES_DB: Database name
    "},{"location":"services/listmonk/#database","title":"Database","text":"

    Listmonk uses PostgreSQL as its backend database. The database is automatically configured through the docker-compose setup.

    "},{"location":"services/listmonk/#uploads","title":"Uploads","text":"
    • Upload directory: ./assets/uploads
    • Used for media files, templates, and attachments
    "},{"location":"services/listmonk/#getting-started","title":"Getting Started","text":"
    1. Access Listmonk at http://localhost:9000
    2. Log in with your admin credentials
    3. Set up your first mailing list
    4. Configure SMTP settings for sending emails
    5. Import subscribers or create subscription forms
    6. Create your first campaign
    "},{"location":"services/listmonk/#important-notes","title":"Important Notes","text":"
    • Configure SMTP settings before sending emails
    • Set up proper domain authentication (SPF, DKIM) for better deliverability
    • Regularly backup your subscriber data and campaigns
    • Monitor bounce rates and maintain list hygiene
    "},{"location":"services/listmonk/#official-documentation","title":"Official Documentation","text":"

    For comprehensive guides and API documentation, visit: - Listmonk Documentation - GitHub Repository

    "},{"location":"services/map/","title":"Map","text":"

    Interactive map service for geospatial data visualization, powered by NocoDB and Leaflet.js.

    "},{"location":"services/map/#overview","title":"Overview","text":"

    The Map service provides an interactive web-based map for displaying, searching, and analyzing geospatial data from a NocoDB backend. It supports real-time geolocation, adding new locations, and is optimized for both desktop and mobile use.

    "},{"location":"services/map/#features","title":"Features","text":"
    • Interactive map visualization with OpenStreetMap
    • Real-time geolocation support
    • Add new locations directly from the map
    • Auto-refresh every 30 seconds
    • Responsive design for mobile devices
    • Secure API proxy to protect credentials
    • Docker containerization for easy deployment
    "},{"location":"services/map/#access","title":"Access","text":"
    • Default Port: ${MAP_PORT:-3000} (default: 3000)
    • URL: http://localhost:${MAP_PORT:-3000}
    • Default Workspace: /app/public/
    "},{"location":"services/map/#configuration","title":"Configuration","text":"

    All configuration is done via environment variables:

    Variable Description Default NOCODB_API_URL NocoDB API base URL Required NOCODB_API_TOKEN API authentication token Required NOCODB_VIEW_URL Full NocoDB view URL Required PORT Server port 3000 DEFAULT_LAT Default map latitude 53.5461 DEFAULT_LNG Default map longitude -113.4938 DEFAULT_ZOOM Default map zoom level 11"},{"location":"services/map/#volumes","title":"Volumes","text":"
    • ./map/app/public: Map public assets
    "},{"location":"services/map/#usage","title":"Usage","text":"
    1. Access the map at http://localhost:${MAP_PORT:-3000}
    2. Search for locations or addresses
    3. Add or view custom markers
    4. Analyze geospatial data as needed
    "},{"location":"services/map/#nocodb-table-setup","title":"NocoDB Table Setup","text":""},{"location":"services/map/#required-columns","title":"Required Columns","text":"
    • geodata (Text): Format \"latitude;longitude\"
    • latitude (Decimal): Precision 10, Scale 8
    • longitude (Decimal): Precision 11, Scale 8
    "},{"location":"services/map/#form-fields-as-seen-in-the-interface","title":"Form Fields (as seen in the interface)","text":"
    • First Name (Text): Person's first name
    • Last Name (Text): Person's last name
    • Email (Email): Contact email address
    • Unit Number (Text): Apartment/unit number
    • Support Level (Single Select):
    • 1 - Strong Support (Green)
    • 2 - Moderate Support (Yellow)
    • 3 - Low Support (Orange)
    • 4 - No Support (Red)
    • Address (Text): Full street address
    • Sign (Checkbox): Has campaign sign (true/false)
    • Sign Size (Single Select): Small, Medium, Large
    • Geo-Location (Text): Formatted as \"latitude;longitude\"
    "},{"location":"services/map/#api-endpoints","title":"API Endpoints","text":"
    • GET /api/locations - Fetch all locations
    • POST /api/locations - Create new location
    • GET /api/locations/:id - Get single location
    • PUT /api/locations/:id - Update location
    • DELETE /api/locations/:id - Delete location
    • GET /health - Health check
    "},{"location":"services/map/#security-considerations","title":"Security Considerations","text":"
    • API tokens are kept server-side only
    • CORS is configured for security
    • Rate limiting prevents abuse
    • Input validation on all endpoints
    • Helmet.js for security headers
    "},{"location":"services/map/#troubleshooting","title":"Troubleshooting","text":"
    • Ensure NocoDB table has required columns and valid coordinates
    • Check API token permissions and network connectivity
    "},{"location":"services/mini-qr/","title":"Mini QR","text":"

    Simple QR code generator service.

    "},{"location":"services/mini-qr/#overview","title":"Overview","text":"

    Mini QR is a lightweight service for generating QR codes for URLs, text, or other data. It provides a web interface for quick QR code creation and download.

    "},{"location":"services/mini-qr/#features","title":"Features","text":"
    • Generate QR codes for text or URLs
    • Download QR codes as images
    • Simple and fast interface
    • No user registration required
    "},{"location":"services/mini-qr/#access","title":"Access","text":"
    • Default Port: ${MINI_QR_PORT:-8089} (default: 8089)
    • URL: http://localhost:${MINI_QR_PORT:-8089}
    "},{"location":"services/mini-qr/#configuration","title":"Configuration","text":""},{"location":"services/mini-qr/#environment-variables","title":"Environment Variables","text":"
    • QR_DEFAULT_SIZE: Default size of generated QR codes
    • QR_IMAGE_FORMAT: Image format (e.g., png, svg)
    "},{"location":"services/mini-qr/#volumes","title":"Volumes","text":"
    • ./configs/mini-qr: QR code service configuration
    "},{"location":"services/mini-qr/#usage","title":"Usage","text":"
    1. Access Mini QR at http://localhost:${MINI_QR_PORT:-8089}
    2. Enter the text or URL to encode
    3. Download or share the generated QR code
    "},{"location":"services/mkdocs/","title":"MkDocs Material","text":"

    Modern documentation site generator with live preview.

    Looking for more info on BNKops code-server integration?

    \u2192 Code Server Configuration

    "},{"location":"services/mkdocs/#overview","title":"Overview","text":"

    MkDocs Material is a powerful documentation framework built on top of MkDocs, providing a beautiful Material Design theme and advanced features for creating professional documentation sites.

    "},{"location":"services/mkdocs/#features","title":"Features","text":"
    • Material Design theme
    • Live preview during development
    • Search functionality
    • Navigation and organization
    • Code syntax highlighting
    • Mathematical expressions support
    • Responsive design
    • Customizable themes and colors
    "},{"location":"services/mkdocs/#access","title":"Access","text":"
    • Development Port: 4000
    • Development URL: http://localhost:4000
    • Live Reload: Automatically refreshes on file changes
    "},{"location":"services/mkdocs/#configuration","title":"Configuration","text":""},{"location":"services/mkdocs/#main-configuration","title":"Main Configuration","text":"

    Configuration is managed through mkdocs.yml in the project root.

    "},{"location":"services/mkdocs/#volumes","title":"Volumes","text":"
    • ./mkdocs: Documentation source files
    • ./assets/images: Shared images directory
    "},{"location":"services/mkdocs/#environment-variables","title":"Environment Variables","text":"
    • SITE_URL: Base domain for the site
    • USER_ID: User ID for file permissions
    • GROUP_ID: Group ID for file permissions
    "},{"location":"services/mkdocs/#directory-structure","title":"Directory Structure","text":"
    mkdocs/\n\u251c\u2500\u2500 mkdocs.yml          # Configuration file\n\u251c\u2500\u2500 docs/               # Documentation source\n\u2502   \u251c\u2500\u2500 index.md       # Homepage\n\u2502   \u251c\u2500\u2500 services/      # Service documentation\n\u2502   \u251c\u2500\u2500 blog/          # Blog posts\n\u2502   \u2514\u2500\u2500 overrides/     # Template overrides\n\u2514\u2500\u2500 site/              # Built static site\n
    "},{"location":"services/mkdocs/#writing-documentation","title":"Writing Documentation","text":""},{"location":"services/mkdocs/#markdown-basics","title":"Markdown Basics","text":"
    • Use standard Markdown syntax
    • Support for tables, code blocks, and links
    • Mathematical expressions with MathJax
    • Admonitions for notes and warnings
    "},{"location":"services/mkdocs/#example-page","title":"Example Page","text":"
    # Page Title\n\nThis is a sample documentation page.\n\n## Section\n\nContent goes here with **bold** and *italic* text.\n\n### Code Example\n\n```python\ndef hello_world():\n    print(\"Hello, World!\")\n

    Note

    This is an informational note.

    ## Building and Deployment\n\n### Development\n\nThe development server runs automatically with live reload.\n\n### Building Static Site\n\n```bash\ndocker exec mkdocs-changemaker mkdocs build\n

    The built site will be available in the mkdocs/site/ directory.

    "},{"location":"services/mkdocs/#customization","title":"Customization","text":""},{"location":"services/mkdocs/#themes-and-colors","title":"Themes and Colors","text":"

    Customize appearance in mkdocs.yml:

    theme:\n  name: material\n  palette:\n    primary: blue\n    accent: indigo\n
    "},{"location":"services/mkdocs/#custom-css","title":"Custom CSS","text":"

    Add custom styles in docs/stylesheets/extra.css.

    "},{"location":"services/mkdocs/#official-documentation","title":"Official Documentation","text":"

    For comprehensive MkDocs Material documentation: - MkDocs Material - MkDocs Documentation - Markdown Guide

    "},{"location":"services/n8n/","title":"n8n","text":"

    Workflow automation tool for connecting services and automating tasks.

    "},{"location":"services/n8n/#overview","title":"Overview","text":"

    n8n is a powerful workflow automation tool that allows you to connect various apps and services together. It provides a visual interface for creating automated workflows, making it easy to integrate different systems and automate repetitive tasks.

    "},{"location":"services/n8n/#features","title":"Features","text":"
    • Visual workflow editor
    • 400+ integrations
    • Custom code execution (JavaScript/Python)
    • Webhook support
    • Scheduled workflows
    • Error handling and retries
    • User management
    • API access
    • Self-hosted and privacy-focused
    "},{"location":"services/n8n/#access","title":"Access","text":"
    • Default Port: 5678
    • URL: http://localhost:5678
    • Default User Email: Set via N8N_DEFAULT_USER_EMAIL
    • Default User Password: Set via N8N_DEFAULT_USER_PASSWORD
    "},{"location":"services/n8n/#configuration","title":"Configuration","text":""},{"location":"services/n8n/#environment-variables","title":"Environment Variables","text":"
    • N8N_HOST: Hostname for n8n (default: n8n.${DOMAIN})
    • N8N_PORT: Internal port (5678)
    • N8N_PROTOCOL: Protocol for webhooks (https)
    • NODE_ENV: Environment (production)
    • WEBHOOK_URL: Base URL for webhooks
    • GENERIC_TIMEZONE: Timezone setting
    • N8N_ENCRYPTION_KEY: Encryption key for credentials
    • N8N_USER_MANAGEMENT_DISABLED: Enable/disable user management
    • N8N_DEFAULT_USER_EMAIL: Default admin email
    • N8N_DEFAULT_USER_PASSWORD: Default admin password
    "},{"location":"services/n8n/#volumes","title":"Volumes","text":"
    • n8n_data: Persistent data storage
    • ./local-files: Local file access for workflows
    "},{"location":"services/n8n/#getting-started","title":"Getting Started","text":"
    1. Access n8n at http://localhost:5678
    2. Log in with your admin credentials
    3. Create your first workflow
    4. Add nodes for different services
    5. Configure connections between nodes
    6. Test and activate your workflow
    "},{"location":"services/n8n/#common-use-cases","title":"Common Use Cases","text":""},{"location":"services/n8n/#documentation-automation","title":"Documentation Automation","text":"
    • Auto-generate documentation from code comments
    • Sync documentation between different platforms
    • Notify team when documentation is updated
    "},{"location":"services/n8n/#email-campaign-integration","title":"Email Campaign Integration","text":"
    • Connect Listmonk with external data sources
    • Automate subscriber management
    • Trigger campaigns based on events
    "},{"location":"services/n8n/#database-management-with-nocodb","title":"Database Management with NocoDB","text":"
    • Sync data between NocoDB and external APIs
    • Automate data entry and validation
    • Create backup workflows for database content
    • Generate reports from NocoDB data
    "},{"location":"services/n8n/#development-workflows","title":"Development Workflows","text":"
    • Auto-deploy documentation on git push
    • Sync code changes with documentation
    • Backup automation
    "},{"location":"services/n8n/#data-processing","title":"Data Processing","text":"
    • Process CSV files and import to databases
    • Transform data between different formats
    • Schedule regular data updates
    "},{"location":"services/n8n/#example-workflows","title":"Example Workflows","text":""},{"location":"services/n8n/#simple-webhook-to-email","title":"Simple Webhook to Email","text":"
    Webhook \u2192 Email\n
    "},{"location":"services/n8n/#scheduled-documentation-backup","title":"Scheduled Documentation Backup","text":"
    Schedule \u2192 Read Files \u2192 Compress \u2192 Upload to Storage\n
    "},{"location":"services/n8n/#git-integration","title":"Git Integration","text":"
    Git Webhook \u2192 Process Changes \u2192 Update Documentation \u2192 Notify Team\n
    "},{"location":"services/n8n/#security-considerations","title":"Security Considerations","text":"
    • Use strong encryption keys
    • Secure webhook URLs
    • Regularly update credentials
    • Monitor workflow executions
    • Implement proper error handling
    "},{"location":"services/n8n/#integration-with-other-services","title":"Integration with Other Services","text":"

    n8n can integrate with all services in your Changemaker Lite setup:

    • Listmonk: Manage subscribers and campaigns
    • PostgreSQL: Read/write database operations
    • Code Server: File operations and git integration
    • MkDocs: Documentation generation and updates
    "},{"location":"services/n8n/#troubleshooting","title":"Troubleshooting","text":""},{"location":"services/n8n/#common-issues","title":"Common Issues","text":"
    • Workflow Execution Errors: Check node configurations and credentials
    • Webhook Issues: Verify URLs and authentication
    • Connection Problems: Check network connectivity between services
    "},{"location":"services/n8n/#debugging","title":"Debugging","text":"
    # Check container logs\ndocker logs n8n-changemaker\n\n# Access container shell\ndocker exec -it n8n-changemaker sh\n\n# Check workflow executions in the UI\n# Visit http://localhost:5678 \u2192 Executions\n
    "},{"location":"services/n8n/#official-documentation","title":"Official Documentation","text":"

    For comprehensive n8n documentation:

    • n8n Documentation
    • Community Workflows
    • Node Reference
    • GitHub Repository
    "},{"location":"services/nocodb/","title":"NocoDB","text":"

    No-code database platform that turns any database into a smart spreadsheet.

    "},{"location":"services/nocodb/#overview","title":"Overview","text":"

    NocoDB is an open-source no-code platform that transforms any database into a smart spreadsheet interface. It provides a user-friendly way to manage data, create forms, build APIs, and collaborate on database operations without requiring extensive technical knowledge.

    "},{"location":"services/nocodb/#features","title":"Features","text":"
    • Smart Spreadsheet Interface: Transform databases into intuitive spreadsheets
    • Form Builder: Create custom forms for data entry
    • API Generation: Auto-generated REST APIs for all tables
    • Collaboration: Real-time collaboration with team members
    • Access Control: Role-based permissions and sharing
    • Data Visualization: Charts and dashboard creation
    • Webhooks: Integration with external services
    • Import/Export: Support for CSV, Excel, and other formats
    • Multi-Database Support: Works with PostgreSQL, MySQL, SQLite, and more
    "},{"location":"services/nocodb/#access","title":"Access","text":"
    • Default Port: 8090
    • URL: http://localhost:8090
    • Database: PostgreSQL (dedicated root_db instance)
    "},{"location":"services/nocodb/#configuration","title":"Configuration","text":""},{"location":"services/nocodb/#environment-variables","title":"Environment Variables","text":"
    • NOCODB_PORT: External port mapping (default: 8090)
    • NC_DB: Database connection string for PostgreSQL backend
    "},{"location":"services/nocodb/#database-backend","title":"Database Backend","text":"

    NocoDB uses a dedicated PostgreSQL instance (root_db) with the following configuration:

    • Database Name: root_db
    • Username: postgres
    • Password: password
    • Host: root_db (internal container name)
    "},{"location":"services/nocodb/#volumes","title":"Volumes","text":"
    • nc_data: Application data and configuration storage
    • db_data: PostgreSQL database files
    "},{"location":"services/nocodb/#getting-started","title":"Getting Started","text":"
    1. Access NocoDB: Navigate to http://localhost:8090
    2. Initial Setup: Complete the onboarding process
    3. Create Project: Start with a new project or connect existing databases
    4. Add Tables: Import data or create new tables
    5. Configure Views: Set up different views (Grid, Form, Gallery, etc.)
    6. Set Permissions: Configure user access and sharing settings
    "},{"location":"services/nocodb/#common-use-cases","title":"Common Use Cases","text":""},{"location":"services/nocodb/#content-management","title":"Content Management","text":"
    • Create content databases for blogs and websites
    • Manage product catalogs and inventories
    • Track customer information and interactions
    "},{"location":"services/nocodb/#project-management","title":"Project Management","text":"
    • Task and project tracking systems
    • Team collaboration workspaces
    • Resource and timeline management
    "},{"location":"services/nocodb/#data-collection","title":"Data Collection","text":"
    • Custom forms for surveys and feedback
    • Event registration and management
    • Lead capture and CRM systems
    "},{"location":"services/nocodb/#integration-with-other-services","title":"Integration with Other Services","text":"

    NocoDB can integrate well with other Changemaker Lite services:

    • n8n Integration: Use NocoDB as a data source/destination in automation workflows
    • Listmonk Integration: Manage subscriber lists and campaign data
    • Documentation: Store and manage documentation metadata
    "},{"location":"services/nocodb/#api-usage","title":"API Usage","text":"

    NocoDB automatically generates REST APIs for all your tables:

    # Get all records from a table\nGET http://localhost:8090/api/v1/db/data/v1/{project}/table/{table}\n\n# Create a new record\nPOST http://localhost:8090/api/v1/db/data/v1/{project}/table/{table}\n\n# Update a record\nPATCH http://localhost:8090/api/v1/db/data/v1/{project}/table/{table}/{id}\n
    "},{"location":"services/nocodb/#backup-and-data-management","title":"Backup and Data Management","text":""},{"location":"services/nocodb/#database-backup","title":"Database Backup","text":"

    Since NocoDB uses PostgreSQL, you can backup the database:

    # Backup NocoDB database\ndocker exec root_db pg_dump -U postgres root_db > nocodb_backup.sql\n\n# Restore from backup\ndocker exec -i root_db psql -U postgres root_db < nocodb_backup.sql\n
    "},{"location":"services/nocodb/#application-data","title":"Application Data","text":"

    Application settings and metadata are stored in the nc_data volume.

    "},{"location":"services/nocodb/#security-considerations","title":"Security Considerations","text":"
    • Change default database credentials in production
    • Configure proper access controls within NocoDB
    • Use HTTPS for production deployments
    • Regularly backup both database and application data
    • Monitor access logs and user activities
    "},{"location":"services/nocodb/#performance-tips","title":"Performance Tips","text":"
    • Regular database maintenance and optimization
    • Monitor memory usage for large datasets
    • Use appropriate indexing for frequently queried fields
    • Consider database connection pooling for high-traffic scenarios
    "},{"location":"services/nocodb/#troubleshooting","title":"Troubleshooting","text":""},{"location":"services/nocodb/#common-issues","title":"Common Issues","text":"

    Service won't start: Check if the PostgreSQL database is healthy

    docker logs root_db\n

    Database connection errors: Verify database credentials and network connectivity

    docker exec nocodb nc_data nc\n

    Performance issues: Monitor resource usage and optimize queries

    docker stats nocodb root_db\n
    "},{"location":"services/nocodb/#official-documentation","title":"Official Documentation","text":"

    For comprehensive guides and advanced features:

    • NocoDB Documentation
    • GitHub Repository
    • Community Forum
    "},{"location":"services/postgresql/","title":"PostgreSQL Database","text":"

    Reliable database backend for applications.

    "},{"location":"services/postgresql/#overview","title":"Overview","text":"

    PostgreSQL is a powerful, open-source relational database system. In Changemaker Lite, it serves as the backend database for Listmonk and can be used by other applications requiring persistent data storage.

    "},{"location":"services/postgresql/#features","title":"Features","text":"
    • ACID compliance
    • Advanced SQL features
    • JSON/JSONB support
    • Full-text search
    • Extensibility
    • High performance
    • Reliability and data integrity
    "},{"location":"services/postgresql/#access","title":"Access","text":"
    • Default Port: 5432
    • Host: listmonk-db (internal container name)
    • Database: Set via POSTGRES_DB environment variable
    • Username: Set via POSTGRES_USER environment variable
    • Password: Set via POSTGRES_PASSWORD environment variable
    "},{"location":"services/postgresql/#configuration","title":"Configuration","text":""},{"location":"services/postgresql/#environment-variables","title":"Environment Variables","text":"
    • POSTGRES_USER: Database username
    • POSTGRES_PASSWORD: Database password
    • POSTGRES_DB: Database name
    "},{"location":"services/postgresql/#health-checks","title":"Health Checks","text":"

    The PostgreSQL container includes health checks to ensure the database is ready before dependent services start.

    "},{"location":"services/postgresql/#data-persistence","title":"Data Persistence","text":"

    Database data is stored in a Docker volume (listmonk-data) to ensure persistence across container restarts.

    "},{"location":"services/postgresql/#connecting-to-the-database","title":"Connecting to the Database","text":""},{"location":"services/postgresql/#from-host-machine","title":"From Host Machine","text":"

    You can connect to PostgreSQL from your host machine using:

    psql -h localhost -p 5432 -U [username] -d [database]\n
    "},{"location":"services/postgresql/#from-other-containers","title":"From Other Containers","text":"

    Other containers can connect using the internal hostname listmonk-db on port 5432.

    "},{"location":"services/postgresql/#backup-and-restore","title":"Backup and Restore","text":""},{"location":"services/postgresql/#backup","title":"Backup","text":"
    docker exec listmonk-db pg_dump -U [username] [database] > backup.sql\n
    "},{"location":"services/postgresql/#restore","title":"Restore","text":"
    docker exec -i listmonk-db psql -U [username] [database] < backup.sql\n
    "},{"location":"services/postgresql/#monitoring","title":"Monitoring","text":"

    Monitor database health and performance through: - Container logs: docker logs listmonk-db - Database metrics and queries - Connection monitoring

    "},{"location":"services/postgresql/#security-considerations","title":"Security Considerations","text":"
    • Use strong passwords
    • Regularly update PostgreSQL version
    • Monitor access logs
    • Implement regular backups
    • Consider network isolation
    "},{"location":"services/postgresql/#official-documentation","title":"Official Documentation","text":"

    For comprehensive PostgreSQL documentation: - PostgreSQL Documentation - Docker PostgreSQL Image

    "},{"location":"services/static-server/","title":"Static Site Server","text":"

    Nginx-powered static site server for hosting built documentation and websites.

    "},{"location":"services/static-server/#overview","title":"Overview","text":"

    The Static Site Server uses Nginx to serve your built documentation and static websites. It's configured to serve the built MkDocs site and other static content with high performance and reliability.

    "},{"location":"services/static-server/#features","title":"Features","text":"
    • High-performance static file serving
    • Automatic index file handling
    • Gzip compression
    • Caching headers
    • Security headers
    • Custom error pages
    • URL rewriting support
    "},{"location":"services/static-server/#access","title":"Access","text":"
    • Default Port: 4001
    • URL: http://localhost:4001
    • Document Root: /config/www (mounted from ./mkdocs/site)
    "},{"location":"services/static-server/#configuration","title":"Configuration","text":""},{"location":"services/static-server/#environment-variables","title":"Environment Variables","text":"
    • PUID: User ID for file permissions (default: 1000)
    • PGID: Group ID for file permissions (default: 1000)
    • TZ: Timezone setting (default: Etc/UTC)
    "},{"location":"services/static-server/#volumes","title":"Volumes","text":"
    • ./mkdocs/site:/config/www: Static site files
    • Built MkDocs site is automatically served
    "},{"location":"services/static-server/#usage","title":"Usage","text":"
    1. Build your MkDocs site: docker exec mkdocs-changemaker mkdocs build
    2. The built site is automatically available at http://localhost:4001
    3. Any files in ./mkdocs/site/ will be served statically
    "},{"location":"services/static-server/#file-structure","title":"File Structure","text":"
    mkdocs/site/           # Served at /\n\u251c\u2500\u2500 index.html         # Homepage\n\u251c\u2500\u2500 assets/           # CSS, JS, images\n\u251c\u2500\u2500 services/         # Service documentation\n\u2514\u2500\u2500 search/           # Search functionality\n
    "},{"location":"services/static-server/#performance-features","title":"Performance Features","text":"
    • Gzip Compression: Automatic compression for text files
    • Browser Caching: Optimized cache headers
    • Fast Static Serving: Nginx optimized for static content
    • Security Headers: Basic security header configuration
    "},{"location":"services/static-server/#custom-configuration","title":"Custom Configuration","text":"

    For advanced Nginx configuration, you can: 1. Create custom Nginx config files 2. Mount them as volumes 3. Restart the container

    "},{"location":"services/static-server/#monitoring","title":"Monitoring","text":"

    Monitor the static site server through: - Container logs: docker logs mkdocs-site-server-changemaker - Access logs for traffic analysis - Performance metrics

    "},{"location":"services/static-server/#troubleshooting","title":"Troubleshooting","text":""},{"location":"services/static-server/#common-issues","title":"Common Issues","text":"
    • 404 Errors: Ensure MkDocs site is built and files exist in ./mkdocs/site/
    • Permission Issues: Check PUID and PGID settings
    • File Not Found: Verify file paths and case sensitivity
    "},{"location":"services/static-server/#debugging","title":"Debugging","text":"
    # Check container logs\ndocker logs mkdocs-site-server-changemaker\n\n# Verify files are present\ndocker exec mkdocs-site-server-changemaker ls -la /config/www\n\n# Test file serving\ncurl -I http://localhost:4001\n
    "},{"location":"services/static-server/#official-documentation","title":"Official Documentation","text":"

    For more information about the underlying Nginx server: - LinuxServer.io Nginx - Nginx Documentation

    "},{"location":"blog/archive/2025/","title":"2025","text":""}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\u200b\\-_,:!=\\[\\]()\"`/]+|\\.(?!\\d)|&[lg]t;|(?!\\b)(?=[A-Z][a-z])","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Welcome to Changemaker Lite","text":"

    Stop feeding your secrets to corporations. Own your political infrastructure.

    "},{"location":"#quick-start","title":"Quick Start","text":"

    Get up and running in minutes:

    # Clone the repository\ngit clone https://gitea.bnkops.com/admin/changemaker.lite\ncd changemaker.lite\n\n# Configure environment\n./config.sh\n\n# Start all services\ndocker compose up -d\n\n# For production deployment with Cloudflare tunnels\n./start-production.sh\n
    "},{"location":"#services","title":"Services","text":"

    Changemaker Lite includes these essential services:

    "},{"location":"#core-services","title":"Core Services","text":"
    • Homepage (Port 3010) - Central dashboard and service monitoring
    • Code Server (Port 8888) - VS Code in your browser
    • MkDocs (Port 4000) - Documentation with live preview
    • Static Server (Port 4001) - Production documentation site
    "},{"location":"#communication-automation","title":"Communication & Automation","text":"
    • Listmonk (Port 9000) - Newsletter and email campaign management
    • n8n (Port 5678) - Workflow automation platform
    "},{"location":"#data-development","title":"Data & Development","text":"
    • NocoDB (Port 8090) - No-code database platform
    • PostgreSQL (Port 5432) - Database backend for Listmonk
    • Gitea (Port 3030) - Self-hosted Git service
    "},{"location":"#interactive-tools","title":"Interactive Tools","text":"
    • Map Viewer (Port 3000) - Interactive map with NocoDB integration
    • Mini QR (Port 8089) - QR code generator
    "},{"location":"#getting-started","title":"Getting Started","text":"
    1. Setup: Run ./config.sh to configure your environment
    2. Launch: Start services with docker compose up -d
    3. Dashboard: Access the Homepage at http://localhost:3010
    4. Production: Deploy with Cloudflare tunnels using ./start-production.sh
    "},{"location":"#project-structure","title":"Project Structure","text":"
    changemaker.lite/\n\u251c\u2500\u2500 docker-compose.yml    # Service definitions\n\u251c\u2500\u2500 config.sh            # Configuration wizard\n\u251c\u2500\u2500 start-production.sh  # Production deployment script\n\u251c\u2500\u2500 mkdocs/              # Documentation source\n\u2502   \u251c\u2500\u2500 docs/            # Markdown files\n\u2502   \u2514\u2500\u2500 mkdocs.yml       # MkDocs configuration\n\u251c\u2500\u2500 configs/             # Service configurations\n\u2502   \u251c\u2500\u2500 homepage/        # Homepage dashboard config\n\u2502   \u251c\u2500\u2500 code-server/     # VS Code settings\n\u2502   \u2514\u2500\u2500 cloudflare/      # Tunnel configurations\n\u251c\u2500\u2500 map/                 # Map application\n\u2502   \u251c\u2500\u2500 app/             # Node.js application\n\u2502   \u251c\u2500\u2500 Dockerfile       # Container definition\n\u2502   \u2514\u2500\u2500 .env             # Map configuration\n\u2514\u2500\u2500 assets/              # Shared assets\n    \u251c\u2500\u2500 images/          # Image files\n    \u251c\u2500\u2500 icons/           # Service icons\n    \u2514\u2500\u2500 uploads/         # Listmonk uploads\n
    "},{"location":"#key-features","title":"Key Features","text":"
    • \ud83d\udc33 Fully Containerized - All services run in Docker containers
    • \ud83d\udd12 Production Ready - Built-in Cloudflare tunnel support for secure access
    • \ud83d\udce6 All-in-One - Everything you need for documentation, development, and campaigns
    • \ud83d\uddfa\ufe0f Geographic Data - Interactive maps with real-time location tracking
    • \ud83d\udce7 Email Campaigns - Professional newsletter management
    • \ud83d\udd04 Automation - Connect services and automate workflows
    • \ud83d\udcbe Version Control - Self-hosted Git repository
    • \ud83c\udfaf No-Code Database - Build applications without programming
    "},{"location":"#system-requirements","title":"System Requirements","text":"
    • OS: Ubuntu 24.04 LTS (Noble Numbat) or compatible Linux distribution
    • Docker: Version 24.0+ with Docker Compose v2
    • Memory: Minimum 4GB RAM (8GB recommended)
    • Storage: 20GB+ available disk space
    • Network: Internet connection for initial setup
    "},{"location":"#learn-more","title":"Learn More","text":"
    • Getting Started - Detailed installation guide
    • Services Overview - Deep dive into each service
    • Blog - Updates and tutorials
    • GitHub Repository - Source code
    "},{"location":"test/","title":"Test","text":"

    lololol

    "},{"location":"adv/","title":"Advanced Configurations","text":"

    We are also publishing how BNKops does several advanced workflows. These include things like assembling hardware, how to manage a network, how to manage several changemakers simultaneously, and integrating AI.

    "},{"location":"adv/ansible/","title":"Setting Up Ansible with Tailscale for Remote Server Management","text":""},{"location":"adv/ansible/#overview","title":"Overview","text":"

    This guide walks you through setting up Ansible to manage remote servers (like ThinkCentre units) using Tailscale for secure networking. This approach provides reliable remote access without complex port forwarding or VPN configurations.

    In plainer language; this allows you to manage several Changemaker nodes remotely. If you are a full time campaigner, this can enable you to manage several campaigns infrastructure from a central location while each user gets their own Changemaker box.

    "},{"location":"adv/ansible/#what-youll-learn","title":"What You'll Learn","text":"
    • How to set up Ansible for infrastructure automation
    • How to configure secure remote access using Tailscale
    • How to troubleshoot common SSH and networking issues
    • Why this approach is better than alternatives like Cloudflare Tunnels for simple SSH access
    "},{"location":"adv/ansible/#prerequisites","title":"Prerequisites","text":"
    • Master Node: Your main computer running Ubuntu/Linux (control machine)
    • Target Nodes: Remote servers/ThinkCentres running Ubuntu/Linux
    • Both machines: Must have internet access
    • User Account: Same username on all machines (recommended)
    "},{"location":"adv/ansible/#part-1-initial-setup-on-master-node","title":"Part 1: Initial Setup on Master Node","text":""},{"location":"adv/ansible/#1-create-ansible-directory-structure","title":"1. Create Ansible Directory Structure","text":"
    # Create project directory\nmkdir ~/ansible_quickstart\ncd ~/ansible_quickstart\n\n# Create directory structure\nmkdir -p group_vars host_vars roles playbooks\n
    "},{"location":"adv/ansible/#2-install-ansible","title":"2. Install Ansible","text":"
    sudo apt update\nsudo apt install ansible\n
    "},{"location":"adv/ansible/#3-generate-ssh-keys-if-not-already-done","title":"3. Generate SSH Keys (if not already done)","text":"
    # Generate SSH key pair\nssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa\n\n# Display public key (save this for later)\ncat ~/.ssh/id_rsa.pub\n
    "},{"location":"adv/ansible/#part-2-target-node-setup-physical-access-required-initially","title":"Part 2: Target Node Setup (Physical Access Required Initially)","text":""},{"location":"adv/ansible/#1-enable-ssh-on-target-node","title":"1. Enable SSH on Target Node","text":"

    Access each target node physically (monitor + keyboard):

    # Update system\nsudo apt update && sudo apt upgrade -y\n\n# Install and enable SSH\nsudo apt install openssh-server\nsudo systemctl enable ssh\nsudo systemctl start ssh\n\n# Check SSH status\nsudo systemctl status ssh\n
    "},{"location":"adv/ansible/#2-configure-ssh-key-authentication","title":"2. Configure SSH Key Authentication","text":"
    # Create .ssh directory\nmkdir -p ~/.ssh\nchmod 700 ~/.ssh\n\n# Create authorized_keys file\nnano ~/.ssh/authorized_keys\n

    Paste your public key from the master node, then:

    # Set proper permissions\nchmod 600 ~/.ssh/authorized_keys\n
    "},{"location":"adv/ansible/#3-configure-ssh-security","title":"3. Configure SSH Security","text":"
    # Edit SSH config\nsudo nano /etc/ssh/sshd_config\n

    Ensure these lines are uncommented:

    PubkeyAuthentication yes\nAuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2\n
    # Restart SSH service\nsudo systemctl restart ssh\n
    "},{"location":"adv/ansible/#4-configure-firewall","title":"4. Configure Firewall","text":"
    # Check firewall status\nsudo ufw status\n\n# Allow SSH through firewall\nsudo ufw allow ssh\n\n# Fix home directory permissions (required for SSH keys)\nchmod 755 ~/\n
    "},{"location":"adv/ansible/#part-3-test-local-ssh-connection","title":"Part 3: Test Local SSH Connection","text":"

    Before proceeding with remote access, test SSH connectivity locally:

    # From master node, test SSH to target\nssh username@<target-local-ip>\n

    Common Issues and Solutions:

    • Connection hangs: Check firewall rules (sudo ufw allow ssh)
    • Permission denied: Verify SSH keys and file permissions
    • SSH config errors: Ensure PubkeyAuthentication yes is set
    "},{"location":"adv/ansible/#part-4-set-up-tailscale-for-remote-access","title":"Part 4: Set Up Tailscale for Remote Access","text":""},{"location":"adv/ansible/#why-tailscale-over-alternatives","title":"Why Tailscale Over Alternatives","text":"

    We initially tried Cloudflare Tunnels but encountered complexity with:

    • DNS routing issues
    • Complex configuration for SSH
    • Same-network testing problems
    • Multiple configuration approaches with varying success

    Tailscale is superior because:

    • Zero configuration mesh networking
    • Works from any network
    • Persistent IP addresses
    • No port forwarding needed
    • Free for personal use
    "},{"location":"adv/ansible/#1-install-tailscale-on-master-node","title":"1. Install Tailscale on Master Node","text":"
    # Install Tailscale\ncurl -fsSL https://tailscale.com/install.sh | sh\n\n# Connect to Tailscale network\nsudo tailscale up\n

    Follow the authentication URL to connect with your Google/Microsoft/GitHub account.

    "},{"location":"adv/ansible/#2-install-tailscale-on-target-nodes","title":"2. Install Tailscale on Target Nodes","text":"

    On each target node:

    # Install Tailscale\ncurl -fsSL https://tailscale.com/install.sh | sh\n\n# Connect to Tailscale network\nsudo tailscale up\n

    Authenticate each device through the provided URL.

    "},{"location":"adv/ansible/#3-get-tailscale-ip-addresses","title":"3. Get Tailscale IP Addresses","text":"

    On each machine:

    # Get your Tailscale IP\ntailscale ip -4\n

    Each device receives a persistent IP like 100.x.x.x.

    "},{"location":"adv/ansible/#part-5-configure-ansible","title":"Part 5: Configure Ansible","text":""},{"location":"adv/ansible/#1-create-inventory-file","title":"1. Create Inventory File","text":"
    # Create inventory.ini\ncd ~/ansible_quickstart\nnano inventory.ini\n

    Content:

    [thinkcenter]\ntc-node1 ansible_host=100.x.x.x ansible_user=your-username\ntc-node2 ansible_host=100.x.x.x ansible_user=your-username\n\n[all:vars]\nansible_ssh_private_key_file=~/.ssh/id_rsa\nansible_host_key_checking=False\n

    Replace:

    • 100.x.x.x with actual Tailscale IPs
    • your-username with your actual username
    "},{"location":"adv/ansible/#2-test-ansible-connectivity","title":"2. Test Ansible Connectivity","text":"
    # Test connection to all nodes\nansible all -i inventory.ini -m ping\n

    Expected output:

    tc-node1 | SUCCESS => {\n    \"changed\": false,\n    \"ping\": \"pong\"\n}\n
    "},{"location":"adv/ansible/#part-6-create-and-run-playbooks","title":"Part 6: Create and Run Playbooks","text":""},{"location":"adv/ansible/#1-simple-information-gathering-playbook","title":"1. Simple Information Gathering Playbook","text":"
    mkdir -p playbooks\nnano playbooks/info-playbook.yml\n

    Content:

    ---\n- name: Gather Node Information\n  hosts: all\n  tasks:\n    - name: Get system information\n      setup:\n\n    - name: Display basic system info\n      debug:\n        msg: |\n          Hostname: {{ ansible_hostname }}\n          Operating System: {{ ansible_distribution }} {{ ansible_distribution_version }}\n          Architecture: {{ ansible_architecture }}\n          Memory: {{ ansible_memtotal_mb }}MB\n          CPU Cores: {{ ansible_processor_vcpus }}\n\n    - name: Show disk usage\n      command: df -h /\n      register: disk_info\n\n    - name: Display disk usage\n      debug:\n        msg: \"Root filesystem usage: {{ disk_info.stdout_lines[1] }}\"\n\n    - name: Check uptime\n      command: uptime\n      register: uptime_info\n\n    - name: Display uptime\n      debug:\n        msg: \"System uptime: {{ uptime_info.stdout }}\"\n
    "},{"location":"adv/ansible/#2-run-the-playbook","title":"2. Run the Playbook","text":"
    ansible-playbook -i inventory.ini playbooks/info-playbook.yml\n
    "},{"location":"adv/ansible/#part-7-advanced-playbook-example","title":"Part 7: Advanced Playbook Example","text":""},{"location":"adv/ansible/#system-setup-playbook","title":"System Setup Playbook","text":"
    nano playbooks/setup-node.yml\n

    Content:

    ---\n- name: Setup ThinkCentre Node\n  hosts: all\n  become: yes\n  tasks:\n    - name: Update package cache\n      apt:\n        update_cache: yes\n\n    - name: Install essential packages\n      package:\n        name:\n          - htop\n          - vim\n          - curl\n          - git\n          - docker.io\n        state: present\n\n    - name: Add user to docker group\n      user:\n        name: \"{{ ansible_user }}\"\n        groups: docker\n        append: yes\n\n    - name: Create management directory\n      file:\n        path: /opt/management\n        state: directory\n        owner: \"{{ ansible_user }}\"\n        group: \"{{ ansible_user }}\"\n
    "},{"location":"adv/ansible/#troubleshooting-guide","title":"Troubleshooting Guide","text":""},{"location":"adv/ansible/#ssh-issues","title":"SSH Issues","text":"

    Problem: SSH connection hangs

    • Check firewall: sudo ufw status and sudo ufw allow ssh
    • Verify SSH service: sudo systemctl status ssh
    • Test local connectivity first

    Problem: Permission denied (publickey)

    • Check SSH key permissions: chmod 600 ~/.ssh/authorized_keys
    • Verify home directory permissions: chmod 755 ~/
    • Ensure SSH config allows key auth: PubkeyAuthentication yes

    Problem: Bad owner or permissions on SSH config

    chmod 600 ~/.ssh/config\n
    "},{"location":"adv/ansible/#ansible-issues","title":"Ansible Issues","text":"

    Problem: Host key verification failed

    • Add to inventory: ansible_host_key_checking=False

    Problem: Ansible command not found

    sudo apt install ansible\n

    Problem: Connection timeouts

    • Verify Tailscale connectivity: ping <tailscale-ip>
    • Check if both nodes are connected: tailscale status
    "},{"location":"adv/ansible/#tailscale-issues","title":"Tailscale Issues","text":"

    Problem: Can't connect to Tailscale IP

    • Verify both devices are authenticated: tailscale status
    • Check Tailscale is running: sudo systemctl status tailscaled
    • Restart Tailscale: sudo tailscale up
    "},{"location":"adv/ansible/#scaling-to-multiple-nodes","title":"Scaling to Multiple Nodes","text":""},{"location":"adv/ansible/#adding-new-nodes","title":"Adding New Nodes","text":"
    1. Install Tailscale on new node
    2. Set up SSH access (repeat Part 2)
    3. Add to inventory.ini:
    [thinkcenter]\ntc-node1 ansible_host=100.125.148.60 ansible_user=bunker-admin\ntc-node2 ansible_host=100.x.x.x ansible_user=bunker-admin\ntc-node3 ansible_host=100.x.x.x ansible_user=bunker-admin\n
    "},{"location":"adv/ansible/#group-management","title":"Group Management","text":"
    [webservers]\ntc-node1 ansible_host=100.x.x.x ansible_user=bunker-admin\ntc-node2 ansible_host=100.x.x.x ansible_user=bunker-admin\n\n[databases]\ntc-node3 ansible_host=100.x.x.x ansible_user=bunker-admin\n\n[all:vars]\nansible_ssh_private_key_file=~/.ssh/id_rsa\nansible_host_key_checking=False\n

    Run playbooks on specific groups:

    ansible-playbook -i inventory.ini -l webservers playbook.yml\n
    "},{"location":"adv/ansible/#best-practices","title":"Best Practices","text":""},{"location":"adv/ansible/#security","title":"Security","text":"
    • Use SSH keys, not passwords
    • Keep Tailscale client updated
    • Regular security updates via Ansible
    • Use become: yes only when necessary
    "},{"location":"adv/ansible/#organization","title":"Organization","text":"
    ansible_quickstart/\n\u251c\u2500\u2500 inventory.ini\n\u251c\u2500\u2500 group_vars/\n\u251c\u2500\u2500 host_vars/\n\u251c\u2500\u2500 roles/\n\u2514\u2500\u2500 playbooks/\n    \u251c\u2500\u2500 info-playbook.yml\n    \u251c\u2500\u2500 setup-node.yml\n    \u2514\u2500\u2500 maintenance.yml\n
    "},{"location":"adv/ansible/#monitoring-and-maintenance","title":"Monitoring and Maintenance","text":"

    Create regular maintenance playbooks:

    - name: System maintenance\n  hosts: all\n  become: yes\n  tasks:\n    - name: Update all packages\n      apt:\n        upgrade: dist\n        update_cache: yes\n\n    - name: Clean package cache\n      apt:\n        autoclean: yes\n        autoremove: yes\n
    "},{"location":"adv/ansible/#alternative-approaches-we-considered","title":"Alternative Approaches We Considered","text":""},{"location":"adv/ansible/#cloudflare-tunnels","title":"Cloudflare Tunnels","text":"
    • Pros: Good for web services, handles NAT traversal
    • Cons: Complex SSH setup, DNS routing issues, same-network problems
    • Use case: Better for web applications than SSH access
    "},{"location":"adv/ansible/#traditional-vpn","title":"Traditional VPN","text":"
    • Pros: Full network access
    • Cons: Complex setup, port forwarding required, router configuration
    • Use case: When you control the network infrastructure
    "},{"location":"adv/ansible/#ssh-reverse-tunnels","title":"SSH Reverse Tunnels","text":"
    • Pros: Simple concept
    • Cons: Requires VPS, single point of failure, manual setup
    • Use case: Temporary access or when other methods fail
    "},{"location":"adv/ansible/#conclusion","title":"Conclusion","text":"

    This setup provides:

    • Reliable remote access from anywhere
    • Secure mesh networking with Tailscale
    • Infrastructure automation with Ansible
    • Easy scaling to multiple nodes
    • No complex networking required

    The combination of Ansible + Tailscale is ideal for managing distributed infrastructure without the complexity of traditional VPN setups or the limitations of cloud-specific solutions.

    "},{"location":"adv/ansible/#quick-reference-commands","title":"Quick Reference Commands","text":"
    # Check Tailscale status\ntailscale status\n\n# Test Ansible connectivity\nansible all -i inventory.ini -m ping\n\n# Run playbook on all hosts\nansible-playbook -i inventory.ini playbook.yml\n\n# Run playbook on specific group\nansible-playbook -i inventory.ini -l groupname playbook.yml\n\n# Run single command on all hosts\nansible all -i inventory.ini -m command -a \"uptime\"\n\n# SSH to node via Tailscale\nssh username@100.x.x.x\n
    "},{"location":"adv/vscode-ssh/","title":"Remote Development with VSCode over Tailscale","text":""},{"location":"adv/vscode-ssh/#overview","title":"Overview","text":"

    This guide describes how to set up Visual Studio Code for remote development on servers using the Tailscale network. This enables development directly on remote machines as if they were local, with full access to files, terminals, and debugging capabilities.

    "},{"location":"adv/vscode-ssh/#what-youll-learn","title":"What You'll Learn","text":"
    • How to configure VSCode for remote SSH connections
    • How to set up remote development environments
    • How to manage multiple remote servers efficiently
    • How to troubleshoot common remote development issues
    • Best practices for remote development workflows
    "},{"location":"adv/vscode-ssh/#prerequisites","title":"Prerequisites","text":"
    • Ansible + Tailscale setup completed (see previous guide)
    • VSCode installed on the local machine (master node)
    • Working SSH access to remote servers via Tailscale
    • Tailscale running on both local and remote machines
    "},{"location":"adv/vscode-ssh/#verify-prerequisites","title":"Verify Prerequisites","text":"

    Before starting, verify the setup:

    # Check Tailscale connectivity\ntailscale status\n\n# Test SSH access\nssh <username>@<tailscale-ip>\n\n# Check VSCode is installed\ncode --version\n
    "},{"location":"adv/vscode-ssh/#part-1-install-and-configure-remote-ssh-extension","title":"Part 1: Install and Configure Remote-SSH Extension","text":""},{"location":"adv/vscode-ssh/#1-install-the-remote-development-extensions","title":"1. Install the Remote Development Extensions","text":"

    Option A: Install Remote Development Pack (Recommended)

    1. Open VSCode
    2. Press Ctrl+Shift+X (or Cmd+Shift+X on Mac)
    3. Search for \"Remote Development\"
    4. Install the Remote Development extension pack by Microsoft

    This pack includes:

    • Remote - SSH
    • Remote - SSH: Editing Configuration Files
    • Remote - Containers
    • Remote - WSL (Windows only)

    Option B: Install Individual Extension

    1. Search for \"Remote - SSH\"
    2. Install Remote - SSH by Microsoft
    "},{"location":"adv/vscode-ssh/#2-verify-installation","title":"2. Verify Installation","text":"

    After installation, the following should be visible:

    • Remote Explorer icon in the Activity Bar (left sidebar)
    • \"Remote-SSH\" commands in Command Palette (Ctrl+Shift+P)
    "},{"location":"adv/vscode-ssh/#part-2-configure-ssh-connections","title":"Part 2: Configure SSH Connections","text":""},{"location":"adv/vscode-ssh/#1-access-ssh-configuration","title":"1. Access SSH Configuration","text":"

    Method A: Through VSCode

    1. Press Ctrl+Shift+P to open Command Palette
    2. Type \"Remote-SSH: Open SSH Configuration File...\"
    3. Select the SSH config file (usually the first option)

    Method B: Direct File Editing

    # Edit SSH config file directly\nnano ~/.ssh/config\n

    "},{"location":"adv/vscode-ssh/#2-add-server-configurations","title":"2. Add Server Configurations","text":"

    Add servers to the SSH config file:

    # Example Node\nHost node1\n    HostName <tailscale-ip>\n    User <username>\n    IdentityFile ~/.ssh/id_rsa\n    ForwardAgent yes\n    ServerAliveInterval 60\n    ServerAliveCountMax 3\n\n# Additional nodes (add as needed)\nHost node2\n    HostName <tailscale-ip>\n    User <username>\n    IdentityFile ~/.ssh/id_rsa\n    ForwardAgent yes\n    ServerAliveInterval 60\n    ServerAliveCountMax 3\n

    Configuration Options Explained:

    • Host: Friendly name for the connection
    • HostName: Tailscale IP address
    • User: Username on the remote server
    • IdentityFile: Path to the SSH private key
    • ForwardAgent: Enables SSH agent forwarding for Git operations
    • ServerAliveInterval: Keeps connection alive (prevents timeouts)
    • ServerAliveCountMax: Number of keepalive attempts
    "},{"location":"adv/vscode-ssh/#3-set-proper-ssh-key-permissions","title":"3. Set Proper SSH Key Permissions","text":"
    # Ensure SSH config has correct permissions\nchmod 600 ~/.ssh/config\n\n# Verify SSH key permissions\nchmod 600 ~/.ssh/id_rsa\nchmod 644 ~/.ssh/id_rsa.pub\n
    "},{"location":"adv/vscode-ssh/#part-3-connect-to-remote-servers","title":"Part 3: Connect to Remote Servers","text":""},{"location":"adv/vscode-ssh/#1-connect-via-command-palette","title":"1. Connect via Command Palette","text":"
    1. Press Ctrl+Shift+P
    2. Type \"Remote-SSH: Connect to Host...\"
    3. Select the server (e.g., node1)
    4. VSCode will open a new window connected to the remote server
    "},{"location":"adv/vscode-ssh/#2-connect-via-remote-explorer","title":"2. Connect via Remote Explorer","text":"
    1. Click the Remote Explorer icon in Activity Bar
    2. Expand SSH Targets
    3. Click the connect icon next to the server name
    "},{"location":"adv/vscode-ssh/#3-connect-via-quick-menu","title":"3. Connect via Quick Menu","text":"
    1. Click the remote indicator in bottom-left corner (looks like ><)
    2. Select \"Connect to Host...\"
    3. Choose the server from the list
    "},{"location":"adv/vscode-ssh/#4-first-connection-process","title":"4. First Connection Process","text":"

    On first connection, VSCode will:

    1. Verify the host key (click \"Continue\" if prompted)
    2. Install VSCode Server on the remote machine (automatic)
    3. Open a remote window with access to the remote file system

    Expected Timeline: - First connection: 1-3 minutes (installs VSCode Server) - Subsequent connections: 10-30 seconds

    "},{"location":"adv/vscode-ssh/#part-4-remote-development-environment-setup","title":"Part 4: Remote Development Environment Setup","text":""},{"location":"adv/vscode-ssh/#1-open-remote-workspace","title":"1. Open Remote Workspace","text":"

    Once connected:

    # In the VSCode terminal (now running on remote server)\n# Navigate to the project directory\ncd /home/<username>/projects\n\n# Open current directory in VSCode\ncode .\n\n# Or open a specific project\ncode /opt/myproject\n
    "},{"location":"adv/vscode-ssh/#2-install-extensions-on-remote-server","title":"2. Install Extensions on Remote Server","text":"

    Extensions must be installed separately on the remote server:

    Essential Development Extensions:

    1. Python (Microsoft) - Python development
    2. GitLens (GitKraken) - Enhanced Git capabilities
    3. Docker (Microsoft) - Container development
    4. Prettier - Code formatting
    5. ESLint - JavaScript linting
    6. Auto Rename Tag - HTML/XML tag editing

    To Install:

    1. Go to Extensions (Ctrl+Shift+X)
    2. Find the desired extension
    3. Click \"Install in SSH: node1\" (not local install)
    "},{"location":"adv/vscode-ssh/#3-configure-git-on-remote-server","title":"3. Configure Git on Remote Server","text":"
    # In VSCode terminal (remote)\ngit config --global user.name \"<Full Name>\"\ngit config --global user.email \"<email@example.com>\"\n\n# Test Git connectivity\ngit clone https://github.com/<username>/<repo>.git\n
    "},{"location":"adv/vscode-ssh/#part-5-remote-development-workflows","title":"Part 5: Remote Development Workflows","text":""},{"location":"adv/vscode-ssh/#1-file-management","title":"1. File Management","text":"

    File Explorer:

    • Shows remote server's file system
    • Create, edit, delete files directly
    • Drag and drop between local and remote (limited)

    File Transfer:

    # Upload files to remote (from local terminal)\nscp localfile.txt <username>@<tailscale-ip>:/home/<username>/\n\n# Download files from remote\nscp <username>@<tailscale-ip>:/remote/path/file.txt ./local/path/\n

    "},{"location":"adv/vscode-ssh/#2-terminal-usage","title":"2. Terminal Usage","text":"

    Integrated Terminal:

    • Press Ctrl+` to open terminal
    • Runs directly on remote server
    • Multiple terminals supported
    • Full shell access (bash, zsh, etc.)

    Common Remote Terminal Commands:

    # Check system resources\nhtop\ndf -h\nfree -h\n\n# Install packages\nsudo apt update\nsudo apt install nodejs npm\n\n# Start services\nsudo systemctl start nginx\nsudo docker-compose up -d\n

    "},{"location":"adv/vscode-ssh/#3-port-forwarding","title":"3. Port Forwarding","text":"

    Automatic Port Forwarding: VSCode automatically detects and forwards common development ports.

    Manual Port Forwarding:

    1. Open Ports tab in terminal panel
    2. Click \"Forward a Port\"
    3. Enter port number (e.g., 3000, 8080, 5000)
    4. Access via http://localhost:port on the local machine

    Example: Web Development

    # Start a web server on remote (port 3000)\nnpm start\n\n# VSCode automatically suggests forwarding port 3000\n# Access at http://localhost:3000 on the local machine\n

    "},{"location":"adv/vscode-ssh/#4-debugging-remote-applications","title":"4. Debugging Remote Applications","text":"

    Python Debugging:

    // .vscode/launch.json on remote server\n{\n    \"version\": \"0.2.0\",\n    \"configurations\": [\n        {\n            \"name\": \"Python: Current File\",\n            \"type\": \"python\",\n            \"request\": \"launch\",\n            \"program\": \"${file}\",\n            \"console\": \"integratedTerminal\"\n        }\n    ]\n}\n

    Node.js Debugging:

    // .vscode/launch.json\n{\n    \"version\": \"0.2.0\",\n    \"configurations\": [\n        {\n            \"name\": \"Launch Program\",\n            \"type\": \"node\",\n            \"request\": \"launch\",\n            \"program\": \"${workspaceFolder}/app.js\"\n        }\n    ]\n}\n

    "},{"location":"adv/vscode-ssh/#part-6-advanced-configuration","title":"Part 6: Advanced Configuration","text":""},{"location":"adv/vscode-ssh/#1-workspace-settings","title":"1. Workspace Settings","text":"

    Create remote-specific settings:

    // .vscode/settings.json (on remote server)\n{\n    \"python.defaultInterpreterPath\": \"/usr/bin/python3\",\n    \"terminal.integrated.shell.linux\": \"/bin/bash\",\n    \"files.autoSave\": \"afterDelay\",\n    \"editor.formatOnSave\": true,\n    \"remote.SSH.remotePlatform\": {\n        \"node1\": \"linux\"\n    }\n}\n
    "},{"location":"adv/vscode-ssh/#2-multi-server-management","title":"2. Multi-Server Management","text":"

    Switch Between Servers:

    1. Click remote indicator (bottom-left)
    2. Select \"Connect to Host...\"
    3. Choose a different server

    Compare Files Across Servers:

    1. Open file from server A
    2. Connect to server B in new window
    3. Open corresponding file
    4. Use \"Compare with...\" command
    "},{"location":"adv/vscode-ssh/#3-sync-configuration","title":"3. Sync Configuration","text":"

    Settings Sync:

    1. Enable Settings Sync in VSCode
    2. Settings, extensions, and keybindings sync to remote
    3. Consistent experience across all servers
    "},{"location":"adv/vscode-ssh/#part-7-project-specific-setups","title":"Part 7: Project-Specific Setups","text":""},{"location":"adv/vscode-ssh/#1-python-development","title":"1. Python Development","text":"
    # On remote server\n# Create virtual environment\npython3 -m venv venv\nsource venv/bin/activate\n\n# Install packages\npip install flask django requests\n\n# VSCode automatically detects Python interpreter\n

    VSCode Python Configuration:

    // .vscode/settings.json\n{\n    \"python.defaultInterpreterPath\": \"./venv/bin/python\",\n    \"python.linting.enabled\": true,\n    \"python.linting.pylintEnabled\": true\n}\n

    "},{"location":"adv/vscode-ssh/#2-nodejs-development","title":"2. Node.js Development","text":"
    # On remote server\n# Install Node.js\ncurl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -\nsudo apt-get install -y nodejs\n\n# Create project\nmkdir myapp && cd myapp\nnpm init -y\nnpm install express\n
    "},{"location":"adv/vscode-ssh/#3-docker-development","title":"3. Docker Development","text":"
    # On remote server\n# Install Docker (if not already done via Ansible)\nsudo apt install docker.io docker-compose\nsudo usermod -aG docker $USER\n\n# Create Dockerfile\ncat > Dockerfile << EOF\nFROM node:18\nWORKDIR /app\nCOPY package*.json ./\nRUN npm install\nCOPY . .\nEXPOSE 3000\nCMD [\"npm\", \"start\"]\nEOF\n

    VSCode Docker Integration:

    • Install Docker extension on remote
    • Right-click Dockerfile \u2192 \"Build Image\"
    • Manage containers from VSCode interface
    "},{"location":"adv/vscode-ssh/#part-8-troubleshooting-guide","title":"Part 8: Troubleshooting Guide","text":""},{"location":"adv/vscode-ssh/#common-connection-issues","title":"Common Connection Issues","text":"

    Problem: \"Could not establish connection to remote host\"

    Solutions:

    # Check Tailscale connectivity\ntailscale status\nping <tailscale-ip>\n\n# Test SSH manually\nssh <username>@<tailscale-ip>\n\n# Check SSH config syntax\nssh -T node1\n

    Problem: \"Permission denied (publickey)\"

    Solutions:

    # Check SSH key permissions\nchmod 600 ~/.ssh/id_rsa\nchmod 600 ~/.ssh/config\n\n# Verify SSH agent\nssh-add ~/.ssh/id_rsa\nssh-add -l\n\n# Test SSH connection verbosely\nssh -v <username>@<tailscale-ip>\n

    Problem: \"Host key verification failed\"

    Solutions:

    # Remove old host key\nssh-keygen -R <tailscale-ip>\n\n# Or disable host key checking (less secure)\n# Add to SSH config:\n# StrictHostKeyChecking no\n

    "},{"location":"adv/vscode-ssh/#vscode-specific-issues","title":"VSCode-Specific Issues","text":"

    Problem: Extensions not working on remote

    Solutions:

    1. Install extensions specifically for the remote server
    2. Check extension compatibility with remote development
    3. Reload VSCode window: Ctrl+Shift+P \u2192 \"Developer: Reload Window\"

    Problem: Slow performance

    Solutions: - Use .vscode/settings.json to exclude large directories:

    {\n    \"files.watcherExclude\": {\n        \"**/node_modules/**\": true,\n        \"**/.git/objects/**\": true,\n        \"**/dist/**\": true\n    }\n}\n

    Problem: Terminal not starting

    Solutions:

    # Check shell path in remote settings\n\"terminal.integrated.shell.linux\": \"/bin/bash\"\n\n# Or let VSCode auto-detect\n\"terminal.integrated.defaultProfile.linux\": \"bash\"\n

    "},{"location":"adv/vscode-ssh/#network-and-performance-issues","title":"Network and Performance Issues","text":"

    Problem: Connection timeouts

    Solutions: Add to SSH config:

    ServerAliveInterval 60\nServerAliveCountMax 3\nTCPKeepAlive yes\n

    Problem: File transfer slow

    Solutions: - Use .vscodeignore to exclude unnecessary files - Compress large files before transfer - Use rsync for large file operations:

    rsync -avz --progress localdir/ <username>@<tailscale-ip>:remotedir/\n

    "},{"location":"adv/vscode-ssh/#part-9-best-practices","title":"Part 9: Best Practices","text":""},{"location":"adv/vscode-ssh/#security-best-practices","title":"Security Best Practices","text":"
    1. Use SSH keys, never passwords
    2. Keep SSH agent secure
    3. Regular security updates on remote servers
    4. Use VSCode's secure connection verification
    "},{"location":"adv/vscode-ssh/#performance-optimization","title":"Performance Optimization","text":"
    1. Exclude unnecessary files:

      // .vscode/settings.json\n{\n    \"files.watcherExclude\": {\n        \"**/node_modules/**\": true,\n        \"**/.git/**\": true,\n        \"**/dist/**\": true,\n        \"**/build/**\": true\n    },\n    \"search.exclude\": {\n        \"**/node_modules\": true,\n        \"**/bower_components\": true,\n        \"**/*.code-search\": true\n    }\n}\n

    2. Use remote workspace for large projects

    3. Close unnecessary windows and extensions
    4. Use efficient development workflows
    "},{"location":"adv/vscode-ssh/#development-workflow","title":"Development Workflow","text":"
    1. Use version control effectively:

      # Always work in Git repositories\ngit status\ngit add .\ngit commit -m \"feature: add new functionality\"\ngit push origin main\n

    2. Environment separation:

      # Development\nssh node1\ncd /home/<username>/dev-projects\n\n# Production\nssh node2\ncd /opt/production-apps\n

    3. Backup important work:

      # Regular backups via Git\ngit push origin main\n\n# Or manual backup\nscp -r <username>@<tailscale-ip>:/important/project ./backup/\n

    "},{"location":"adv/vscode-ssh/#part-10-team-collaboration","title":"Part 10: Team Collaboration","text":""},{"location":"adv/vscode-ssh/#shared-development-servers","title":"Shared Development Servers","text":"

    SSH Config for Team:

    # Shared development server\nHost team-dev\n    HostName <tailscale-ip>\n    User <team-user>\n    IdentityFile ~/.ssh/team_dev_key\n    ForwardAgent yes\n\n# Personal development\nHost my-dev\n    HostName <tailscale-ip>\n    User <username>\n    IdentityFile ~/.ssh/id_rsa\n

    "},{"location":"adv/vscode-ssh/#project-structure","title":"Project Structure","text":"
    /opt/projects/\n\u251c\u2500\u2500 project-a/\n\u2502   \u251c\u2500\u2500 dev/          # Development branch\n\u2502   \u251c\u2500\u2500 staging/      # Staging environment\n\u2502   \u2514\u2500\u2500 docs/         # Documentation\n\u251c\u2500\u2500 project-b/\n\u2514\u2500\u2500 shared-tools/     # Common utilities\n
    "},{"location":"adv/vscode-ssh/#access-management","title":"Access Management","text":"
    # Create shared project directory\nsudo mkdir -p /opt/projects\nsudo chown -R :developers /opt/projects\nsudo chmod -R g+w /opt/projects\n\n# Add users to developers group\nsudo usermod -a -G developers <username>\n
    "},{"location":"adv/vscode-ssh/#quick-reference","title":"Quick Reference","text":""},{"location":"adv/vscode-ssh/#essential-vscode-remote-commands","title":"Essential VSCode Remote Commands","text":"
    # Command Palette shortcuts\nCtrl+Shift+P \u2192 \"Remote-SSH: Connect to Host...\"\nCtrl+Shift+P \u2192 \"Remote-SSH: Open SSH Configuration File...\"\nCtrl+Shift+P \u2192 \"Remote-SSH: Kill VS Code Server on Host...\"\n\n# Terminal\nCtrl+` \u2192 Open integrated terminal\nCtrl+Shift+` \u2192 Create new terminal\n\n# File operations\nCtrl+O \u2192 Open file\nCtrl+S \u2192 Save file\nCtrl+Shift+E \u2192 Focus file explorer\n
    "},{"location":"adv/vscode-ssh/#ssh-connection-quick-test","title":"SSH Connection Quick Test","text":"
    # Test connectivity\nssh -T node1\n\n# Connect with verbose output\nssh -v <username>@<tailscale-ip>\n\n# Check SSH config\nssh -F ~/.ssh/config node1\n
    "},{"location":"adv/vscode-ssh/#port-forwarding-commands","title":"Port Forwarding Commands","text":"
    # Manual port forwarding\nssh -L 3000:localhost:3000 <username>@<tailscale-ip>\n\n# Background tunnel\nssh -f -N -L 8080:localhost:80 <username>@<tailscale-ip>\n
    "},{"location":"adv/vscode-ssh/#conclusion","title":"Conclusion","text":"

    This remote development setup provides:

    • Full development environment on remote servers
    • Seamless file access and editing capabilities
    • Integrated debugging and terminal access
    • Port forwarding for web development
    • Extension ecosystem available remotely
    • Secure connections through Tailscale network

    The combination of VSCode Remote Development with Tailscale networking creates a powerful, flexible development environment that works from anywhere while maintaining security and performance.

    Whether developing Python applications, Node.js services, or managing Docker containers, this setup provides a professional remote development experience that rivals local development while leveraging the power and resources of remote servers.

    "},{"location":"blog/2025/07/03/blog-1/","title":"Blog 1","text":"

    Hello! Just putting something up here because, well, gosh darn, feels like the right thing to do.

    Making swift progress. Can now write things fast as heck lad.

    "},{"location":"build/","title":"Getting Started with Digital Liberation","text":"

    Welcome to Changemaker-Lite! You're about to reclaim your digital sovereignty and stop feeding your secrets to corporations. This guide will help you set up your own political infrastructure that you actually own and control.

    "},{"location":"build/#quick-start","title":"Quick Start","text":""},{"location":"build/#build-changemkaer-lite","title":"Build Changemkaer-Lite","text":"
    # Clone the repository\ngit clone https://gitea.bnkops.com/admin/changemaker.lite\ncd changemaker.lite\n

    Cloudflare Credentials

    The config.sh script will ask you for your Cloudflare credentials to get started. You can find more information on how to find this in the Cloudlflare Configuration

    # Configure environment (creates .env file)\n./config.sh\n
    # Start all services\ndocker compose up -d\n
    "},{"location":"build/#optional-site-builld","title":"Optional - Site Builld","text":"

    If you want to have your site prepared for launch, you can now proceed with reseting the site build. See Build Site for more detials.

    "},{"location":"build/#deploy","title":"Deploy","text":"

    Cloudflare

    Right now, we suggest deploying using Cloudflare for simplicity and protections against 99% of surface level attacks to digital infrastructure. If you want to avoid using this service, we recommend checking out Pagolin as a drop in replacement.

    For secure public access, use the production deployment script:

    ./start-production.sh\n
    "},{"location":"build/#why-changemaker-lite","title":"Why Changemaker Lite?","text":"

    Before we dive into the technical setup, let's be clear about what you're doing here:

    The Reality

    If you do politics, who is reading your secrets? Every corporate platform you use is extracting your power, selling your data, and building profiles on your community. It's time to break free.

    "},{"location":"build/#what-youre-getting","title":"What You're Getting","text":"
    • Data Sovereignty: Your data stays on your servers
    • Cost Savings: $50/month instead of $2,000+/month for corporate solutions
    • Community Control: Technology that serves movements, not shareholders
    • Trans Liberation: Tools built with radical politics and care
    "},{"location":"build/#what-youre-leaving-behind","title":"What You're Leaving Behind","text":"
    • \u274c Corporate surveillance and data extraction
    • \u274c Escalating subscription fees and vendor lock-in
    • \u274c Algorithmic manipulation of your community
    • \u274c Terms of service that can silence you anytime
    "},{"location":"build/#system-requirements","title":"System Requirements","text":""},{"location":"build/#operating-system","title":"Operating System","text":"
    • Ubuntu 24.04 LTS (Noble Numbat) - Recommended and tested

    Getting Started on Ubunut

    Want some help getting started with a baseline buildout for a Ubunut server? You can use our BNKops Server Build Script

    • Other Linux distributions with systemd support
    • WSL2 on Windows (limited functionality)
    • Mac OS

    New to Linux?

    Consider Linux Mint - it looks like Windows but opens the door to true digital freedom.

    "},{"location":"build/#hardware-requirements","title":"Hardware Requirements","text":"
    • CPU: 2+ cores (4+ recommended)
    • RAM: 4GB minimum (8GB recommended)
    • Storage: 20GB+ available disk space
    • Network: Stable internet connection

    Cloud Hosting

    You can run this on a VPS from providers like Hetzner, DigitalOcean, or Linode for ~$20/month.

    "},{"location":"build/#software-prerequisites","title":"Software Prerequisites","text":"

    Getting Started on Docker

    Want some help getting started with a baseline buildout for a Ubunutu server? You can use our BNKops Server Build Script to roll out a configured server in about 20 mins!

    1. Docker Engine (24.0+)
    # Install Docker\ncurl -fsSL https://get.docker.com | sudo sh\n\n# Add your user to docker group\nsudo usermod -aG docker $USER\n\n# Log out and back in for group changes to take effect\n
    1. Docker Compose (v2.20+)
    # Verify Docker Compose v2 is installed\ndocker compose version\n
    1. Essential Tools
    # Install required packages\nsudo apt update\nsudo apt install -y git curl jq openssl\n
    "},{"location":"build/#installation","title":"Installation","text":""},{"location":"build/#1-clone-repository","title":"1. Clone Repository","text":"
    git clone https://gitea.bnkops.com/admin/changemaker.lite\ncd changemaker.lite\n
    "},{"location":"build/#2-run-configuration-wizard","title":"2. Run Configuration Wizard","text":"

    The config.sh script will guide you through the initial setup:

    ./config.sh\n

    This wizard will:

    • \u2705 Create a .env file with secure defaults
    • \u2705 Scan for available ports to avoid conflicts
    • \u2705 Set up your domain configuration
    • \u2705 Generate secure passwords for databases
    • \u2705 Configure Cloudflare credentials (optional)
    • \u2705 Update all configuration files with your settings
    "},{"location":"build/#configuration-options","title":"Configuration Options","text":"

    During setup, you'll be prompted for:

    1. Domain Name: Your primary domain (e.g., example.com)
    2. Cloudflare Settings (optional):
    3. API Token
    4. Zone ID
    5. Account ID
    6. Admin Credentials:
    7. Listmonk admin email and password
    8. n8n admin email and password
    "},{"location":"build/#3-start-services","title":"3. Start Services","text":"

    Launch all services with Docker Compose:

    docker compose up -d\n

    Wait for services to initialize (first run may take 5-10 minutes):

    # Watch container status\ndocker compose ps\n\n# View logs\ndocker compose logs -f\n
    "},{"location":"build/#4-verify-installation","title":"4. Verify Installation","text":"

    Check that all services are running:

    docker compose ps\n

    Expected output should show all services as \"Up\":

    • code-server-changemaker
    • listmonk_app
    • listmonk_db
    • mkdocs-changemaker
    • mkdocs-site-server-changemaker
    • n8n-changemaker
    • nocodb
    • root_db
    • homepage-changemaker
    • gitea_changemaker
    • gitea_mysql_changemaker
    • mini-qr
    "},{"location":"build/#local-access","title":"Local Access","text":"

    Once services are running, access them locally:

    "},{"location":"build/#homepage-dashboard","title":"\ud83c\udfe0 Homepage Dashboard","text":"
    • URL: http://localhost:3010
    • Purpose: Central hub for all services
    • Features: Service status, quick links, monitoring
    "},{"location":"build/#development-tools","title":"\ud83d\udcbb Development Tools","text":"
    • Code Server: http://localhost:8888 \u2014 VS Code in browser
    • Gitea: http://localhost:3030 \u2014 Git repository management
    • MkDocs Dev: http://localhost:4000 \u2014 Live documentation preview
    • MkDocs Prod: http://localhost:4001 \u2014 Built documentation
    "},{"location":"build/#communication","title":"\ud83d\udce7 Communication","text":"
    • Listmonk: http://localhost:9000 \u2014 Email campaigns Login with credentials set during configuration
    "},{"location":"build/#automation-data","title":"\ud83d\udd04 Automation & Data","text":"
    • n8n: http://localhost:5678 \u2014 Workflow automation Login with credentials set during configuration
    • NocoDB: http://localhost:8090 \u2014 No-code database
    "},{"location":"build/#interactive-tools","title":"\ud83d\udee0\ufe0f Interactive Tools","text":"
    • Mini QR: http://localhost:8089 \u2014 QR code generator
    "},{"location":"build/#map","title":"Map","text":"

    Map

    Map is the canvassing application that is custom view of nocodb data. Map is best built after production deployment to reduce duplicate build efforts.

    "},{"location":"build/#map-manual","title":"Map Manual","text":""},{"location":"build/#production-deployment","title":"Production Deployment","text":""},{"location":"build/#deploy-with-cloudflare-tunnels","title":"Deploy with Cloudflare Tunnels","text":"

    For secure public access, use the production deployment script:

    ./start-production.sh\n

    This script will:

    1. Install and configure cloudflared
    2. Create a Cloudflare tunnel
    3. Set up DNS records automatically
    4. Configure access policies
    5. Create a systemd service for persistence
    "},{"location":"build/#what-happens-during-production-setup","title":"What Happens During Production Setup","text":"
    1. Cloudflare Authentication: Browser-based login to Cloudflare
    2. Tunnel Creation: Secure tunnel named changemaker-lite
    3. DNS Configuration: Automatic CNAME records for all services
    4. Access Policies: Email-based authentication for sensitive services
    5. Service Installation: Systemd service for automatic startup
    "},{"location":"build/#production-urls","title":"Production URLs","text":"

    After successful deployment, services will be available at:

    Public Services:

    • https://yourdomain.com - Main documentation site
    • https://listmonk.yourdomain.com - Email campaigns
    • https://docs.yourdomain.com - Documentation preview
    • https://n8n.yourdomain.com - Automation platform
    • https://db.yourdomain.com - NocoDB
    • https://git.yourdomain.com - Gitea
    • https://map.yourdomain.com - Map viewer
    • https://qr.yourdomain.com - QR generator

    Protected Services (require authentication):

    • https://homepage.yourdomain.com - Dashboard
    • https://code.yourdomain.com - Code Server
    "},{"location":"build/#configuration-management","title":"Configuration Management","text":""},{"location":"build/#environment-variables","title":"Environment Variables","text":"

    Key settings in .env file:

    # Domain Configuration\nDOMAIN=yourdomain.com\nBASE_DOMAIN=https://yourdomain.com\n\n# Service Ports (automatically assigned to avoid conflicts)\nHOMEPAGE_PORT=3010\nCODE_SERVER_PORT=8888\nLISTMONK_PORT=9000\nMKDOCS_PORT=4000\nMKDOCS_SITE_SERVER_PORT=4001\nN8N_PORT=5678\nNOCODB_PORT=8090\nGITEA_WEB_PORT=3030\nGITEA_SSH_PORT=2222\nMAP_PORT=3000\nMINI_QR_PORT=8089\n\n# Cloudflare (for production)\nCF_API_TOKEN=your_token\nCF_ZONE_ID=your_zone_id\nCF_ACCOUNT_ID=your_account_id\n
    "},{"location":"build/#reconfigure-services","title":"Reconfigure Services","text":"

    To update configuration:

    # Re-run configuration wizard\n./config.sh\n\n# Restart services\ndocker compose down && docker compose up -d\n
    "},{"location":"build/#common-tasks","title":"Common Tasks","text":""},{"location":"build/#service-management","title":"Service Management","text":"
    # View all services\ndocker compose ps\n\n# View logs for specific service\ndocker compose logs -f [service-name]\n\n# Restart a service\ndocker compose restart [service-name]\n\n# Stop all services\ndocker compose down\n\n# Stop and remove all data (CAUTION!)\ndocker compose down -v\n
    "},{"location":"build/#backup-data","title":"Backup Data","text":"
    # Backup all volumes\ndocker run --rm -v changemaker_listmonk-data:/data -v $(pwd):/backup alpine tar czf /backup/listmonk-backup.tar.gz -C /data .\n\n# Backup configuration\ntar czf configs-backup.tar.gz configs/\n\n# Backup documentation\ntar czf docs-backup.tar.gz mkdocs/docs/\n
    "},{"location":"build/#update-services","title":"Update Services","text":"
    # Pull latest images\ndocker compose pull\n\n# Recreate containers with new images\ndocker compose up -d\n
    "},{"location":"build/#troubleshooting","title":"Troubleshooting","text":""},{"location":"build/#port-conflicts","title":"Port Conflicts","text":"

    If services fail to start due to port conflicts:

    1. Check which ports are in use:
    sudo ss -tulpn | grep LISTEN\n
    1. Re-run configuration to get new ports:
    ./config.sh\n
    1. Or manually edit .env file and change conflicting ports
    "},{"location":"build/#permission-issues","title":"Permission Issues","text":"

    Fix permission problems:

    # Get your user and group IDs\nid -u  # User ID\nid -g  # Group ID\n\n# Update .env file with correct IDs\nUSER_ID=1000\nGROUP_ID=1000\n\n# Restart services\ndocker compose down && docker compose up -d\n
    "},{"location":"build/#service-wont-start","title":"Service Won't Start","text":"

    Debug service issues:

    # Check detailed logs\ndocker compose logs [service-name] --tail 50\n\n# Check container status\ndocker ps -a\n\n# Inspect container\ndocker inspect [container-name]\n
    "},{"location":"build/#cloudflare-tunnel-issues","title":"Cloudflare Tunnel Issues","text":"
    # Check tunnel service status\nsudo systemctl status cloudflared-changemaker\n\n# View tunnel logs\nsudo journalctl -u cloudflared-changemaker -f\n\n# Restart tunnel\nsudo systemctl restart cloudflared-changemaker\n
    "},{"location":"build/#next-steps","title":"Next Steps","text":"

    Now that your Changemaker Lite instance is running:

    1. Set up Listmonk - Configure SMTP and create your first campaign
    2. Create workflows - Build automations in n8n
    3. Import data - Set up your NocoDB databases
    4. Configure map - Add location data for the map viewer
    5. Write documentation - Start creating content in MkDocs
    6. Set up Git - Initialize repositories in Gitea
    "},{"location":"build/#getting-help","title":"Getting Help","text":"
    • Check the Services documentation for detailed guides
    • Review container logs for specific error messages
    • Ensure all prerequisites are properly installed
    • Verify your domain DNS settings for production deployment
    "},{"location":"build/map/","title":"Map","text":"

    Map is BNKops canvassing application. It is built from the ground up to serve our community (Edmonton).

    "},{"location":"build/map/#prerequisites","title":"Prerequisites","text":"
    • Docker and Docker Compose installed
    • NocoDB instance with API access
    • Domain name (optional but recommended for production)
    "},{"location":"build/map/#nocodb-table-setup","title":"NocoDB Table Setup","text":""},{"location":"build/map/#required-columns","title":"Required Columns","text":"

    Case Sensitive

    When entering in the required columns, make sure that you enter in exact information. Case sensitivity matters for mapping the values to the map itself.

    Create a table in NocoDB with these required columns. The format here is the Name of the column - column type - details:

    1. Geo-Location (geo-data) - Format: \"latitude;longitude\"
    2. latitude (Decimal) - Precision: 10, Scale: 8
    3. longitude (Decimal) - Precision: 11, Scale: 8
    "},{"location":"build/map/#recommended-columns","title":"Recommended Columns","text":"
    • First Name (Text)
    • Last Name (Text)
    • Email (Email)
    • Phone (Phone)
    • Unit Number (Text)
    • Address (LongText)
    • Support Level (Single Select) - Values (only enter numbers):
    • 1 Strong Support (Green)
    • 2 Moderate Support (Yellow)
    • 3 Low Support (Orange)
    • 4 No Support (Red)
    • Sign (Checkbox)
    • Sign Size (Single Select) - Values: Small, Medium, Large
    • Notes (LongText)
    "},{"location":"build/map/#login-sheet-setup","title":"Login Sheet Setup","text":"

    Create a separate table for authorized users with: - Email (Email) - Primary column - Name (Text) - Optional

    "},{"location":"build/map/#api-token-setup","title":"API Token Setup","text":"
    1. In NocoDB, click user icon \u2192 Account Settings
    2. Go to \"API Tokens\" tab
    3. Create new token with read/write permissions for both tables
    "},{"location":"build/map/#6-finding-nocodb-ids","title":"6. Finding NocoDB IDs","text":"
    • Project and Table IDs: Use the full NocoDB view URL in NOCODB_VIEW_URL
    • Login Sheet ID: Use the full URL to your login sheet in NOCODB_LOGIN_SHEET
    "},{"location":"build/map/#environment-configuration","title":"Environment Configuration","text":"

    Config

    The ./config.sh should have created a new .env file. If .env file is present, and it has properly defined domain, skip to step 2

    1. Copy the example env file:
    cp .env.example .env\n
    1. Edit .env with your NocoDB details:
      NOCODB_API_URL=https://your-nocodb-instance.com/api/v1\nNOCODB_API_TOKEN=your-api-token-here\nNOCODB_VIEW_URL=https://your-nocodb-instance.com/dashboard/#/nc/project-id/table-id\nNOCODB_LOGIN_SHEET=https://your-nocodb-instance.com/dashboard/#/nc/project-id/login-sheet-id\n\n# Server Configuration\nPORT=3000\nNODE_ENV=production\n\n# Session Secret (generate with: openssl rand -hex 32)\nSESSION_SECRET=your-secure-random-string\n\n# Map Defaults\nDEFAULT_LAT=53.5461\nDEFAULT_LNG=-113.4938\nDEFAULT_ZOOM=11\n\n# Optional: Map Boundaries\n# BOUND_NORTH=53.7\n# BOUND_SOUTH=53.4\n# BOUND_EAST=-113.3\n# BOUND_WEST=-113.7\n\n# Domain Settings (for cookies)\nCOOKIE_DOMAIN=.yourdomain.com\nALLOWED_ORIGINS=https://map.yourdomain.com,http://localhost:3000\n
    "},{"location":"build/map/#running-the-application","title":"Running the Application","text":""},{"location":"build/map/#development-mode","title":"Development Mode","text":"
    cd app\nnpm install\nnpm run dev\n
    "},{"location":"build/map/#production-with-docker","title":"Production with Docker","text":"
    docker-compose up -d\n
    "},{"location":"build/map/#first-run","title":"First Run","text":"
    1. Access the application at http://localhost:3000 (or your domain)
    2. Login with an email from your authorized users list
    3. Verify locations appear on the map
    "},{"location":"build/map/#maintenance","title":"Maintenance","text":"
    • To clear the geocoding cache, restart the application
    • To update the application:
      docker-compose down\ngit pull origin main\ndocker-compose up -d --build\n
    "},{"location":"build/map/#troubleshooting","title":"Troubleshooting","text":"
    • Locations not showing: Verify table has required columns and API token has read permissions
    • Cannot add locations: Check API token has write permissions
    • Authentication issues: Verify login sheet is properly configured
    "},{"location":"build/map/#security-recommendations","title":"Security Recommendations","text":"
    1. Use HTTPS in production
    2. Regularly rotate API tokens
    3. Restrict API token permissions to only what's needed
    4. Set appropriate CORS and cookie domains
    5. Keep dependencies updated

    The application will automatically:

    • Parse project/table IDs from view URLs
    • Sync geo fields between different formats
    • Cache geocoding results for performance
    • Rate limit API endpoints
    • Validate all inputs
    "},{"location":"build/server/","title":"BNKops Server Build","text":"

    Purpose: a Ubuntu server build-out for general application

    This documentation is a overview of the full build out for a server OS and baseline for running Changemaker-lite. It is a manual to re-install this server on any machine.

    All of the following systems are free and the majority are open source.

    "},{"location":"build/server/#ubuntu-os","title":"Ubuntu OS","text":"

    Ubuntu is a Linux distribution derived from Debian and composed mostly of free and open-source software.

    "},{"location":"build/server/#install-ubuntu","title":"Install Ubuntu","text":""},{"location":"build/server/#post-install","title":"Post Install","text":"

    Post installation, run update:

    sudo apt update\n

    sudo apt upgrade\n
    "},{"location":"build/server/#configuration","title":"Configuration","text":"

    Further configurations:

    • User profile was updated to Automatically Login
    • Remote Desktop, Sharing, and Login have all been enabled.
    • Default system settings have been set to dark mode.
    "},{"location":"build/server/#vscode-insiders","title":"VSCode Insiders","text":"

    Visual Studio Code is a new choice of tool that combines the simplicity of a code editor with what developers need for the core edit-build-debug cycle.

    "},{"location":"build/server/#install-using-app-centre","title":"Install Using App Centre","text":""},{"location":"build/server/#obsidian","title":"Obsidian","text":"

    The free and flexible app for your private\u00a0thoughts.

    "},{"location":"build/server/#install-using-app-center","title":"Install Using App Center","text":""},{"location":"build/server/#curl","title":"Curl","text":"

    command line tool and library for transferring data with URLs (since 1998)

    "},{"location":"build/server/#install","title":"Install","text":"
    sudo apt install curl \n
    "},{"location":"build/server/#glances","title":"Glances","text":"

    Glances an Eye on your system. A top/htop alternative for GNU/Linux, BSD, Mac OS and Windows operating systems.

    "},{"location":"build/server/#install_1","title":"Install","text":"
    sudo snap install glances \n
    "},{"location":"build/server/#syncthing","title":"Syncthing","text":"

    Syncthing is a continuous file synchronization program. It synchronizes files between two or more computers in real time, safely protected from prying eyes. Your data is your data alone and you deserve to choose where it is stored, whether it is shared with some third party, and how it\u2019s transmitted over the internet.

    "},{"location":"build/server/#install_2","title":"Install","text":"
    # Add the release PGP keys:\nsudo mkdir -p /etc/apt/keyrings\nsudo curl -L -o /etc/apt/keyrings/syncthing-archive-keyring.gpg https://syncthing.net/release-key.gpg\n
    # Add the \"stable\" channel to your APT sources:\necho \"deb [signed-by=/etc/apt/keyrings/syncthing-archive-keyring.gpg] https://apt.syncthing.net/ syncthing stable\" | sudo tee /etc/apt/sources.list.d/syncthing.list\n
    # Update and install syncthing:\nsudo apt-get update\nsudo apt-get install syncthing\n
    "},{"location":"build/server/#post-install_1","title":"Post Install","text":"

    Run syncthing as a system service.

    sudo systemctl start syncthing@yourusername\n

    sudo systemctl enable syncthing@yourusername\n
    "},{"location":"build/server/#docker","title":"Docker","text":"

    Docker helps developers build, share, run, and verify applications anywhere \u2014 without tedious environment configuration or management.

    # Add Docker's official GPG key:\nsudo apt-get update\nsudo apt-get install ca-certificates curl\nsudo install -m 0755 -d /etc/apt/keyrings\nsudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc\nsudo chmod a+r /etc/apt/keyrings/docker.asc\n\n# Add the repository to Apt sources:\necho \\\n  \"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \\\n  $(. /etc/os-release && echo \"${UBUNTU_CODENAME:-$VERSION_CODENAME}\") stable\" | \\\n  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null\nsudo apt-get update\n

    sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin\n
    "},{"location":"build/server/#update-users","title":"Update Users","text":"
    sudo groupadd docker\n
    sudo usermod -aG docker $USER\n
    newgrp docker\n
    "},{"location":"build/server/#enable-on-boot","title":"Enable on Boot","text":"
    sudo systemctl enable docker.service\nsudo systemctl enable containerd.service\n
    "},{"location":"build/server/#cloudflared","title":"Cloudflared","text":"

    Connect, protect, and build everywhere. We make websites, apps, and networks faster and more secure. Our developer platform is the best place to build modern apps and deliver AI initiatives.

    sudo mkdir -p --mode=0755 /usr/share/keyrings\ncurl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null\n
    echo \"deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared any main\" | sudo tee /etc/apt/sources.list.d/cloudflared.list\n
    sudo apt-get update && sudo apt-get install cloudflared\n
    "},{"location":"build/server/#post-install_2","title":"Post Install","text":"

    Login to Cloudflare

    cloudflared login\n

    "},{"location":"build/server/#configuration_1","title":"Configuration","text":"

    The ./config.sh and ./start-production.sh scripts will properly configure a Cloudflare tunnel and service to put your system online. More info in the Cloudflare Configuration.

    "},{"location":"build/server/#pandoc","title":"Pandoc","text":"

    If you need to convert files from one markup format into another, pandoc is your swiss-army knife.

    sudo apt install pandoc\n
    "},{"location":"build/site/","title":"Building the Site with MkDocs Material","text":"

    Welcome! This guide will help you get started building and customizing your site using MkDocs Material.

    "},{"location":"build/site/#how-to-build-your-site-step-by-step","title":"\ud83d\ude80 How to Build Your Site (Step by Step)","text":"
    1. Open your Coder instance. For example: coder.yourdomain.com
    2. Go to the mkdocs folder: In the terminal (for a new terminal press Crtl - Shift - ~), type:
      cd mkdocs\n
    3. Build the site: Type:
      mkdocs build\n
      This creates the static website from your documents and places them in the mkdocs/site directory.

    Preview your site locally: Visit localhost:4000 for local development or live.youdomain.com to see a public live load.

    • All documentation in the mkdocs/docs folder is included automatically.
    • The site uses the beautiful and easy-to-use Material for MkDocs theme.

    Material for MkDocs Documentation

    Build vs Serve

    Your website is built in stages. Any edits to documents in the mkdocs directory are instantly served and visible at localhost:4000 or if in production mode live.yourdomain.com. The live site is not meant as a public access point and will crash if too many requests are made to it.

    Running mkdocs build pushes any changes to the site directory, which then a ngnix server pushes them to the production server for public access at your root domain (yourdomain.com).

    You can think of it as serve/live = draft for personal review and build = save/push to production for the public.

    This combination allows for rapid development of documentation while ensuring your live site does not get updated until your content is ready.

    "},{"location":"build/site/#resetting-the-site","title":"\ud83e\uddf9 Resetting the Site","text":"

    If you want to start fresh:

    1. Delete all folders EXCEPT these folders:

      • /blog
      • /javascripts
      • /hooks
      • /assets
      • /stylesheets
      • /overrides
    2. Reset the landing page:

      • Open the main index.md file and remove everything at the very top (the \"front matter\").
      • Or edit /overrides/home.html to change the landing page.
    3. Reset the mkdocs.yml

      • Open mkdocs.yml and delete the nav section entirely.
      • This action will enable mkdocs to build your site navigation based on file names in the root directory.
    "},{"location":"build/site/#using-ai-to-help-build-your-site","title":"\ud83e\udd16 Using AI to Help Build Your Site","text":"
    • If you have a claude.ai subscription, you can use powerful AI in your Coder terminal to write or rewrite pages, including a new home.html.
    • All you need to do is open the terminal and type:
      claude\n
    • You can also try local AI tools like Ollama for on-demand help.
    "},{"location":"build/site/#first-time-setup-tips","title":"\ud83d\udee0\ufe0f First-Time Setup Tips","text":"
    • Navigation: Open mkdocs.yml and remove the nav section to start with a blank menu. Add your own pages as you go.
    • Customize the look: Check out the Material for MkDocs customization guide.
    • Live preview: Use mkdocs serve (see above) to see changes instantly as you edit.
    • Custom files: Put your own CSS, JavaScript, or HTML in /assets, /stylesheets, /javascripts, or /overrides.

    Quick Start Guide

    "},{"location":"build/site/#more-resources","title":"\ud83d\udcda More Resources","text":"
    • MkDocs User Guide
    • Material for MkDocs Features
    • BNKops MKdocs Configuration & Customization

    Happy building!

    "},{"location":"config/","title":"Configuration","text":"

    There are several configuration steps to building a production ready Changemaker-Lite.

    In the order we suggest doing them:

    "},{"location":"config/cloudflare-config/","title":"Configure Cloudflare","text":"

    Cloudflare is the largest DNS routing service on the planet. We use their free service tier to provide Changemaker users with a fast, secure, and reliable way to get online that blocks 99% of surface level attacks and has built in user authenticaion (if you so choose to use it)

    "},{"location":"config/cloudflare-config/#credentials","title":"Credentials","text":"

    The config.sh and start-production.sh scripts require the following Cloudflare credentials to function properly:

    "},{"location":"config/cloudflare-config/#1-cloudflare-api-token","title":"1. Cloudflare API Token","text":"
    • Purpose: Used to authenticate API requests to Cloudflare for managing DNS records, tunnels, and access policies.
    • Required Permissions:
      • Zone.DNS (Read/Write)
      • Account.Cloudflare Tunnel (Read/Write)
    • How to Obtain:
      • Log in to your Cloudflare account.
      • Go to My Profile > API Tokens > Create Token.
      • Use the Edit zone DNS template and add Cloudflare Tunnel permissions.
    "},{"location":"config/cloudflare-config/#2-cloudflare-zone-id","title":"2. Cloudflare Zone ID","text":"
    • Purpose: Identifies the specific DNS zone (domain) in Cloudflare where DNS records will be created.
    • How to Obtain:
      • Log in to your Cloudflare account.
      • Select the domain you want to use.
      • The Zone ID is displayed in the Overview section under API.
    "},{"location":"config/cloudflare-config/#3-cloudflare-account-id","title":"3. Cloudflare Account ID","text":"
    • Purpose: Identifies your Cloudflare account for tunnel creation and management.
    • How to Obtain:
      • Log in to your Cloudflare account.
      • Go to My Profile > API Tokens.
      • The Account ID is displayed at the top of the page.
    "},{"location":"config/cloudflare-config/#4-cloudflare-tunnel-id-optional-in-configsh-required-in-start-productionsh","title":"4. Cloudflare Tunnel ID (Optional in config.sh, Required in start-production.sh)","text":"
    • Purpose: Identifies the specific Cloudflare Tunnel that will be used to route traffic to your services.
    • How to Obtain:
      • This is automatically generated when you create a tunnel using cloudflared tunnel create or via the Cloudflare dashboard.
      • The start-production.sh script will create this for you if it doesn't exist.
    "},{"location":"config/cloudflare-config/#summary-of-required-credentials","title":"Summary of Required Credentials:","text":"
    # In .env file\nCF_API_TOKEN=your_cloudflare_api_token\nCF_ZONE_ID=your_cloudflare_zone_id\nCF_ACCOUNT_ID=your_cloudflare_account_id\nCF_TUNNEL_ID=will_be_set_by_start_production  # This will be set by start-production.sh\n
    "},{"location":"config/cloudflare-config/#notes","title":"Notes:","text":"
    • The config.sh script will prompt you for these credentials during setup.
    • The start-production.sh script will verify these credentials and use them to configure DNS records, create tunnels, and set up access policies.
    • Ensure that the API token has the correct permissions, or the scripts will fail to configure Cloudflare services.
    "},{"location":"config/coder/","title":"Coder Server Configuration","text":"

    This section describes the configuration and features of the code-server environment.

    "},{"location":"config/coder/#accessing-code-server","title":"Accessing Code Server","text":"
    • URL: http://localhost:8080
    • Authentication: Password-based (see below for password retrieval)
    "},{"location":"config/coder/#retrieving-the-code-server-password","title":"Retrieving the Code Server Password","text":"

    After the first build, the code-server password is stored in:

    configs/code-server/.config/code-server/config.yaml\n

    Look for the password: field in that file. For example:

    password: 0c0dca951a2d12eff1665817\n

    Note: It is recommended not to change this password manually, as it is securely generated.

    "},{"location":"config/coder/#main-configuration-options","title":"Main Configuration Options","text":"
    • bind-addr: The address and port code-server listens on (default: 127.0.0.1:8080)
    • auth: Authentication method (default: password)
    • password: The login password (see above)
    • cert: Whether to use HTTPS (default: false)
    "},{"location":"config/coder/#installed-tools-and-features","title":"Installed Tools and Features","text":"

    The code-server environment includes:

    • Node.js 18+ and npm
    • Claude Code (@anthropic-ai/claude-code) globally installed
    • Python 3 and tools:
    • python3-pip, python3-venv, python3-full, pipx
    • Image and PDF processing libraries:
    • CairoSVG, Pillow, libcairo2-dev, libfreetype6-dev, libjpeg-dev, libpng-dev, libwebp-dev, libtiff5-dev, libopenjp2-7-dev, liblcms2-dev
    • weasyprint, fonts-roboto
    • Git for version control and plugin management
    • Build tools: build-essential, pkg-config, python3-dev, zlib1g-dev
    • MkDocs Material and a wide range of MkDocs plugins, installed in a dedicated Python virtual environment at /home/coder/.venv/mkdocs
    • Convenience script: run-mkdocs for running MkDocs commands easily
    "},{"location":"config/coder/#using-mkdocs","title":"Using MkDocs","text":"

    The virtual environment for MkDocs is automatically added to your PATH. You can run MkDocs commands directly, or use the provided script. For example, to build the site, from a clean terminal we would rung:

    cd mkdocs \nmkdocs build\n
    "},{"location":"config/coder/#claude-code-integration","title":"Claude Code Integration","text":"

    The code-server environment comes with Claude Code (@anthropic-ai/claude-code) globally installed via npm.

    "},{"location":"config/coder/#what-is-claude-code","title":"What is Claude Code?","text":"

    Claude Code is an AI-powered coding assistant by Anthropic, designed to help you write, refactor, and understand code directly within your development environment.

    "},{"location":"config/coder/#usage","title":"Usage","text":"
    • Access Claude Code features through the command palette or sidebar in code-server.
    • Use Claude Code to generate code, explain code snippets, or assist with documentation and refactoring tasks.
    • For more information, refer to the Claude Code documentation.

    Note: Claude Code requires an API key or account with Anthropic for full functionality. Refer to the extension settings for configuration.

    "},{"location":"config/coder/#call-claude","title":"Call Claude","text":"

    To use claude simply type claude into the terminal and follow instructions.

    claude\n
    "},{"location":"config/coder/#shell-environment","title":"Shell Environment","text":"

    The .bashrc is configured to include the MkDocs virtual environment and user-local binaries in your PATH for convenience.

    "},{"location":"config/coder/#code-navigation-and-editing-features","title":"Code Navigation and Editing Features","text":"

    The code-server environment provides robust code navigation and editing features, including:

    • IntelliSense: Smart code completions based on variable types, function definitions, and imported modules.
    • Code Navigation: Easily navigate to definitions, references, and symbol searches within your codebase.
    • Debugging Support: Integrated debugging support for Node.js and Python, with breakpoints, call stacks, and interactive consoles.
    • Terminal Access: Built-in terminal access to run commands, scripts, and version control operations.
    "},{"location":"config/coder/#collaboration-features","title":"Collaboration Features","text":"

    Code-server includes features to support collaboration:

    • Live Share: Collaborate in real-time with others, sharing your code and terminal sessions.
    • ChatGPT Integration: AI-powered code assistance and chat-based collaboration.
    "},{"location":"config/coder/#security-considerations","title":"Security Considerations","text":"

    When using code-server, consider the following security aspects:

    • Password Management: The default password is securely generated. Do not share it or expose it in public repositories.
    • Network Security: Ensure that your firewall settings allow access to the code-server port (default: 8080) only from trusted networks.
    • Data Privacy: Be cautious when uploading sensitive data or code to the server. Use environment variables or secure vaults for sensitive information.
    "},{"location":"config/coder/#ollama-integration","title":"Ollama Integration","text":"

    The code-server environment includes Ollama, a tool for running large language models locally on your machine.

    "},{"location":"config/coder/#what-is-ollama","title":"What is Ollama?","text":"

    Ollama is a lightweight, extensible framework for building and running language models locally. It provides a simple API for creating, running, and managing models, making it easy to integrate AI capabilities into your development workflow without relying on external services.

    "},{"location":"config/coder/#getting-started-with-ollama","title":"Getting Started with Ollama","text":""},{"location":"config/coder/#staring-ollama","title":"Staring Ollama","text":"

    For ollama to be available, you need to open a terminal and run:

    ollama serve\n

    This will start the ollama server and you can then proceed to pulling a model and chatting.

    "},{"location":"config/coder/#pulling-a-model","title":"Pulling a Model","text":"

    To get started, you'll need to pull a model. For development and testing, we recommend starting with a smaller model like Gemma 2B:

    ollama pull gemma2:2b\n

    For even lighter resource usage, you can use the 1B parameter version:

    ollama pull gemma2:1b\n
    "},{"location":"config/coder/#running-a-model","title":"Running a Model","text":"

    Once you've pulled a model, you can start an interactive session:

    ollama run gemma2:2b\n
    "},{"location":"config/coder/#available-models","title":"Available Models","text":"

    Popular models available through Ollama include:

    • Gemma 2 (1B, 2B, 9B, 27B): Google's efficient language models
    • Llama 3.2 (1B, 3B, 11B, 90B): Meta's latest language models
    • Qwen 2.5 (0.5B, 1.5B, 3B, 7B, 14B, 32B, 72B): Alibaba's multilingual models
    • Phi 3.5 (3.8B): Microsoft's compact language model
    • Code Llama (7B, 13B, 34B): Specialized for code generation
    "},{"location":"config/coder/#using-ollama-in-your-development-workflow","title":"Using Ollama in Your Development Workflow","text":""},{"location":"config/coder/#api-access","title":"API Access","text":"

    Ollama provides a REST API that runs on http://localhost:11434 by default. You can integrate this into your applications:

    curl http://localhost:11434/api/generate -d '{\n  \"model\": \"gemma2:2b\",\n  \"prompt\": \"Write a Python function to calculate fibonacci numbers\",\n  \"stream\": false\n}'\n
    "},{"location":"config/coder/#model-management","title":"Model Management","text":"

    List installed models:

    ollama list\n

    Remove a model:

    ollama rm gemma2:2b\n

    Show model information:

    ollama show gemma2:2b\n

    "},{"location":"config/coder/#resource-considerations","title":"Resource Considerations","text":"
    • 1B models: Require ~1GB RAM, suitable for basic tasks and resource-constrained environments
    • 2B models: Require ~2GB RAM, good balance of capability and resource usage
    • Larger models: Provide better performance but require significantly more resources
    "},{"location":"config/coder/#integration-with-development-tools","title":"Integration with Development Tools","text":"

    Ollama can be integrated with various development tools and editors through its API, enabling features like:

    • Code completion and generation
    • Documentation writing assistance
    • Code review and explanation
    • Automated testing suggestions

    For more information, visit the Ollama documentation.

    For more detailed information on configuring and using code-server, refer to the official code-server documentation.

    "},{"location":"config/mkdocs/","title":"MkDocs Customization & Features Overview","text":"

    BNKops has been building our own features, widgets, and css styles for MKdocs material theme.

    This document explains the custom styling, repository widgets, and key features enabled in this MkDocs site.

    For more info on how to build your site see Site Build

    "},{"location":"config/mkdocs/#using-the-repository-widget-in-documentation","title":"Using the Repository Widget in Documentation","text":"

    You can embed repository widgets directly in your Markdown documentation to display live repository stats and metadata. To do this, add a div with the appropriate class and data-repo attribute for the repository you want to display.

    Example (for a Gitea repository):

    <div class=\"gitea-widget\" data-repo=\"admin/changemaker.lite\"></div>\n

    This will render a styled card with information about the admin/changemaker.lite repository:

    Options: You can control the widget display with additional data attributes: - data-show-description=\"false\" \u2014 Hide the description - data-show-language=\"false\" \u2014 Hide the language - data-show-last-update=\"false\" \u2014 Hide the last update date

    Example with options:

    <div class=\"gitea-widget\" data-repo=\"admin/changemaker.lite\" data-show-description=\"false\"></div>\n

    For GitHub repositories, use the github-widget class:

    <div class=\"github-widget\" data-repo=\"lyqht/mini-qr\"></div>\n

    "},{"location":"config/mkdocs/#custom-css-styling-stylesheetsextracss","title":"Custom CSS Styling (stylesheets/extra.css)","text":"

    The extra.css file provides extensive custom styling for the site, including:

    • Login and Git Code Buttons: Custom styles for .login-button and .git-code-button to create visually distinct, modern buttons with hover effects.

    • Code Block Improvements: Forces code blocks to wrap text (white-space: pre-wrap) and ensures inline code and tables with code display correctly on all devices.

    • GitHub Widget Styles: Styles for .github-widget and its subcomponents, including:

    • Card-like container with gradient backgrounds and subtle box-shadows.
    • Header with icon, repo link, and stats (stars, forks, issues).
    • Description area with accent border.
    • Footer with language, last update, and license info.
    • Loading and error states with spinners and error messages.
    • Responsive grid layout for multiple widgets.
    • Compact variant for smaller displays.
    • Dark mode adjustments.

    • Gitea Widget Styles: Similar to GitHub widget, but with Gitea branding (green accents). Includes .gitea-widget, .gitea-widget-container, and related classes for header, stats, description, footer, loading, and error states.

    • Responsive Design: Media queries ensure widgets and tables look good on mobile devices.

    "},{"location":"config/mkdocs/#repository-widgets","title":"Repository Widgets","text":""},{"location":"config/mkdocs/#data-generation-hooksrepo_widget_hookpy","title":"Data Generation (hooks/repo_widget_hook.py)","text":"
    • Purpose: During the MkDocs build, this hook fetches metadata for a list of GitHub and Gitea repositories and writes JSON files to docs/assets/repo-data/.
    • How it works:
    • Runs before build (unless in serve mode).
    • Fetches repo data (stars, forks, issues, language, etc.) via GitHub/Gitea APIs.
    • Outputs a JSON file per repo (e.g., lyqht-mini-qr.json).
    • Used by frontend widgets for fast, client-side rendering.
    "},{"location":"config/mkdocs/#github-widget-javascriptsgithub-widgetjs","title":"GitHub Widget (javascripts/github-widget.js)","text":"
    • Purpose: Renders a card for each GitHub repository using the pre-generated JSON data.
    • Features:
    • Displays repo name, link, stars, forks, open issues, language, last update, and license.
    • Shows loading spinner while fetching data.
    • Handles errors gracefully.
    • Supports dynamic content (re-initializes on DOM changes).
    • Language color coding for popular languages.
    "},{"location":"config/mkdocs/#gitea-widget-javascriptsgitea-widgetjs","title":"Gitea Widget (javascripts/gitea-widget.js)","text":"
    • Purpose: Renders a card for each Gitea repository using the pre-generated JSON data.
    • Features:
    • Similar to GitHub widget, but styled for Gitea.
    • Shows repo name, link, stars, forks, open issues, language, last update.
    • Loading and error states.
    • Language color coding.
    "},{"location":"config/mkdocs/#mkdocs-features-mkdocsyml","title":"MkDocs Features (mkdocs.yml)","text":"

    Key features and plugins enabled:

    • Material Theme: Modern, responsive UI with dark/light mode toggle, custom fonts, and accent colors.

    • Navigation Enhancements:

    • Tabs, sticky navigation, instant loading, breadcrumbs, and sectioned navigation.
    • Table of contents with permalinks.

    • Content Features:

    • Code annotation, copy buttons, tooltips, and improved code highlighting.
    • Admonitions, tabbed content, task lists, and emoji support.

    • Plugins:

    • Search: Advanced search with custom tokenization.
    • Social: OpenGraph/social card generation.
    • Blog: Blogging support with archives and categories.
    • Tags: Tagging for content organization.

    • Custom Hooks:

    • repo_widget_hook.py for repository widget data.

    • Extra CSS/JS:

    • Custom styles and scripts for widgets and homepage.

    • Extra Configuration:

    • Social links, copyright.
    "},{"location":"config/mkdocs/#summary","title":"Summary","text":"

    This MkDocs site is highly customized for developer documentation, with visually rich repository widgets, improved code and table rendering, and a modern, responsive UI. All repository stats are fetched at build time for performance and reliability.

    "},{"location":"phil/","title":"Philosophy: Your Secrets, Your Power, Your Movement","text":""},{"location":"phil/#the-question-that-changes-everything","title":"The Question That Changes Everything!","text":"

    If you are a political actor, who do you trust with your secrets?

    This isn't just a technical question\u2014it's the core political question of our time. Every email you send, every document you create, every contact list you build, every strategy you develop: where does it live? Who owns the servers? Who has the keys?

    "},{"location":"phil/#the-corporate-extraction-machine","title":"The Corporate Extraction Machine","text":""},{"location":"phil/#how-they-hook-you","title":"How They Hook You","text":"

    Corporate software companies have perfected the art of digital snake oil sales:

    1. Free Trials - They lure you in with \"free\" accounts
    2. Feature Creep - Essential features require paid tiers
    3. Data Lock-In - Your data becomes harder to export
    4. Price Escalation - $40/month becomes $750/month as you grow
    5. Surveillance Integration - Your organizing becomes their intelligence
    "},{"location":"phil/#the-real-product","title":"The Real Product","text":"

    You Are Not the Customer

    If you're not paying for the product, you ARE the product. But even when you are paying, you're often still the product.

    Corporate platforms don't make money from your subscription fees\u2014they make money from:

    • Data Sales to third parties
    • Algorithmic Manipulation for corporate and political interests
    • Surveillance Contracts with governments and corporations
    • Predictive Analytics about your community and movement
    "},{"location":"phil/#the-bnkops-alternative","title":"The BNKops Alternative","text":""},{"location":"phil/#who-we-are","title":"Who We Are","text":"

    BNKops is a cooperative based in amiskwaciy-w\u00e2skahikan (Edmonton, Alberta) on Treaty 6 territory. We're not a corporation\u2014we're a collective of skilled organizers, developers, and community builders who believe technology should serve liberation, not oppression.

    "},{"location":"phil/#our-principles","title":"Our Principles","text":""},{"location":"phil/#liberation-first","title":"\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f \ud83c\udff3\ufe0f\u200d\ud83c\udf08 \ud83c\uddf5\ud83c\uddf8 Liberation First","text":"

    Technology that centers the most marginalized voices and fights for collective liberation. We believe strongly that the medium is the message; if you the use the medium of fascists, what does that say about your movement?

    "},{"location":"phil/#community-over-profit","title":"\ud83e\udd1d Community Over Profit","text":"

    We operate as a cooperative because we believe in shared ownership and democratic decision-making. No venture capitalists, no shareholders, no extraction.

    "},{"location":"phil/#data-sovereignty","title":"\u26a1 Data Sovereignty","text":"

    Your data belongs to you and your community. We build tools that let you own your digital infrastructure completely.

    "},{"location":"phil/#security-culture","title":"\ud83d\udd12 Security Culture","text":"

    Real security comes from community control, not corporate promises. We integrate security culture practices into our technology design.

    "},{"location":"phil/#the-changemaker-difference","title":"The Changemaker Difference","text":""},{"location":"phil/#traditional-corporate-flow","title":"Traditional Corporate Flow","text":"
    Your Data \u2192 Corporate Server \u2192 Surveillance \u2192 Profit \u2192 Your Oppression\n
    "},{"location":"phil/#changemaker-flow","title":"Changemaker Flow","text":"
    Your Data \u2192 Your Server \u2192 Your Community \u2192 Your Power \u2192 Liberation\n
    "},{"location":"phil/#why-this-matters","title":"Why This Matters","text":"

    When you control your technology infrastructure:

    • Your secrets stay secret - No corporate access to sensitive organizing data
    • Your community stays connected - No algorithmic manipulation of your reach
    • Your costs stay low - No extraction-based pricing as you grow
    • Your future stays yours - No vendor lock-in or platform dependency
    "},{"location":"phil/#the-philosophy-in-practice","title":"The Philosophy in Practice","text":""},{"location":"phil/#security-culture-meets-technology","title":"Security Culture Meets Technology","text":"

    Traditional security culture asks: \"Who needs to know this information?\"

    Digital security culture asks: \"Who controls the infrastructure where this information lives?\"

    "},{"location":"phil/#community-technology","title":"Community Technology","text":"

    We believe in community technology - tools that:

    • Are owned and controlled by the communities that use them
    • Are designed with liberation politics from the ground up
    • Prioritize care, consent, and collective power
    • Can be understood, modified, and improved by community members
    "},{"location":"phil/#prefigurative-politics","title":"Prefigurative Politics","text":"

    The tools we use shape the movements we build. Corporate tools create corporate movements\u2014hierarchical, surveilled, and dependent. Community-controlled tools create community-controlled movements\u2014democratic, secure, and sovereign.

    "},{"location":"phil/#common-questions","title":"Common Questions","text":""},{"location":"phil/#isnt-this-just-for-tech-people","title":"\"Isn't this just for tech people?\"","text":"

    No. We specifically designed Changemaker Lite for organizers, activists, and movement builders who may not have technical backgrounds. Our philosophy is that everyone deserves digital sovereignty, not just people with computer science degrees.

    This is not to say that you won't need to learn! These tools are just that; tools. They have no fancy or white-labeled marketing and are technical in nature. You will need to learn to use them, just as any worker needs to learn the power tools they use on the job.

    "},{"location":"phil/#what-about-convenience","title":"\"What about convenience?\"","text":"

    Corporate platforms are convenient because they've extracted billions of dollars from users to fund that convenience. When you own your tools, there's a learning curve\u2014but it's the same learning curve as learning to organize, learning to build power, learning to create change.

    "},{"location":"phil/#cant-we-just-use-corporate-tools-carefully","title":"\"Can't we just use corporate tools carefully?\"","text":"

    Would you hold your most sensitive organizing meetings in a room owned by your opposition? Would you store your membership lists in filing cabinets at a corporation that profits from surveillance? Digital tools are the same.

    "},{"location":"phil/#what-about-security","title":"\"What about security?\"","text":"

    Real security comes from community control, not corporate promises. When you control your infrastructure:

    • You decide what gets logged and what doesn't
    • You choose who has access and who doesn't
    • You know exactly where your data is and who can see it
    • You can't be de-platformed or locked out of your own data
    "},{"location":"phil/#historical-context","title":"Historical Context","text":""},{"location":"phil/#learning-from-past-struggles","title":"Learning from Past Struggles","text":"

    Every liberation movement has had to solve the problem of secure communication and information sharing:

    • Underground Railroad - Coded songs and safe houses
    • Labor Movement - Secret meetings and encrypted telegrams
    • Civil Rights Movement - CB radios and phone trees
    • LGBTQ+ Liberation - Chosen families and community networks

    The internet should expand these traditions, not replace them with corporate surveillance.

    "},{"location":"phil/#the-surveillance-capitalism-trap","title":"The Surveillance Capitalism Trap","text":"

    As Shoshana Zuboff documents in \"The Age of Surveillance Capitalism,\" we're living through a new form of capitalism that extracts value from human experience itself. Political movements are particularly valuable targets because:

    • Political data predicts behavior
    • Movement intelligence can be used to counter-organize
    • Community networks can be mapped and disrupted
    • Organizing strategies can be monitored and neutralized
    "},{"location":"phil/#taking-action","title":"Taking Action","text":""},{"location":"phil/#start-where-you-are","title":"Start Where You Are","text":"

    You don't have to replace everything at once. Start with one tool, one campaign, one project. Learn the technology alongside your organizing.

    "},{"location":"phil/#build-community-capacity","title":"Build Community Capacity","text":"

    The goal isn't individual self-sufficiency\u2014it's community technological sovereignty. Share skills, pool resources, learn together.

    "},{"location":"phil/#connect-with-others","title":"Connect with Others","text":"

    You're not alone in this. The free and open source software community, the digital security community, and the appropriate technology movement are all working on similar problems.

    "},{"location":"phil/#remember-why","title":"Remember Why","text":"

    This isn't about technology for its own sake. It's about building the infrastructure for the world we want to see\u2014where communities have power, where people control their own data, where technology serves liberation.

    "},{"location":"phil/#resources-for-deeper-learning","title":"Resources for Deeper Learning","text":""},{"location":"phil/#essential-reading","title":"Essential Reading","text":"
    • De-corp Your Software Stack - Our full manifesto
    • The Age of Surveillance Capitalism by Shoshana Zuboff
    • Security Culture Handbook
    "},{"location":"phil/#community-resources","title":"Community Resources","text":"
    • BNKops Repository - Documentation and knowledge base
    • Activist Handbook - Movement building resources
    • EFF Surveillance Self-Defense - Digital security guides
    "},{"location":"phil/#technical-learning","title":"Technical Learning","text":"
    • Self-Hosted Awesome List - Open source alternatives
    • Linux Journey - Learn Linux basics
    • Docker Curriculum - Learn containerization

    This philosophy document is a living document. Contribute your thoughts, experiences, and improvements through the BNKops documentation platform.

    "},{"location":"phil/cost-comparison/","title":"Cost Comparison: Corporation vs. Community","text":""},{"location":"phil/cost-comparison/#the-true-cost-of-corporate-dependency","title":"The True Cost of Corporate Dependency","text":"

    When movements choose corporate software, they're not just paying subscription fees\u2014they're paying with their power, their privacy, and their future. Let's break down the real costs.

    "},{"location":"phil/cost-comparison/#monthly-cost-analysis","title":"Monthly Cost Analysis","text":""},{"location":"phil/cost-comparison/#small-campaign-50-supporters-5000-emailsmonth","title":"Small Campaign (50 supporters, 5,000 emails/month)","text":"Service Category Corporate Solution Monthly Cost Changemaker Lite Monthly Cost Email Marketing Mailchimp $59/month Listmonk $0* Database & CRM Airtable Pro $240/month NocoDB $0* Website Hosting Squarespace $40/month Static Server $0* Documentation Notion Team $96/month MkDocs $0* Development GitHub Codespaces $87/month Code Server $0* Automation Zapier Professional $73/month n8n $0* File Storage Google Workspace $72/month PostgreSQL + Storage $0* Analytics Corporate tracking Privacy cost\u2020 Self-hosted $0* TOTAL $667/month $50/month

    *Included in base Changemaker Lite hosting cost \u2020Privacy costs are incalculable but include surveillance, data sales, and community manipulation

    "},{"location":"phil/cost-comparison/#medium-campaign-500-supporters-50000-emailsmonth","title":"Medium Campaign (500 supporters, 50,000 emails/month)","text":"Service Category Corporate Solution Monthly Cost Changemaker Lite Monthly Cost Email Marketing Mailchimp $299/month Listmonk $0* Database & CRM Airtable Pro $600/month NocoDB $0* Website Hosting Squarespace $65/month Static Server $0* Documentation Notion Team $240/month MkDocs $0* Development GitHub Codespaces $174/month Code Server $0* Automation Zapier Professional $146/month n8n $0* File Storage Google Workspace $144/month PostgreSQL + Storage $0* Analytics Corporate tracking Privacy cost\u2020 Self-hosted $0* TOTAL $1,668/month $75/month"},{"location":"phil/cost-comparison/#large-campaign-5000-supporters-500000-emailsmonth","title":"Large Campaign (5,000 supporters, 500,000 emails/month)","text":"Service Category Corporate Solution Monthly Cost Changemaker Lite Monthly Cost Email Marketing Mailchimp $1,499/month Listmonk $0* Database & CRM Airtable Pro $1,200/month NocoDB $0* Website Hosting Squarespace + CDN $120/month Static Server $0* Documentation Notion Team $480/month MkDocs $0* Development GitHub Codespaces $348/month Code Server $0* Automation Zapier Professional $292/month n8n $0* File Storage Google Workspace $288/month PostgreSQL + Storage $0* Analytics Corporate tracking Privacy cost\u2020 Self-hosted $0* TOTAL $4,227/month $150/month"},{"location":"phil/cost-comparison/#annual-savings-breakdown","title":"Annual Savings Breakdown","text":""},{"location":"phil/cost-comparison/#3-year-cost-comparison","title":"3-Year Cost Comparison","text":"Campaign Size Corporate Total Changemaker Total Savings Small $24,012 $1,800 $22,212 Medium $60,048 $2,700 $57,348 Large $152,172 $5,400 $146,772"},{"location":"phil/cost-comparison/#hidden-costs-of-corporate-software","title":"Hidden Costs of Corporate Software","text":""},{"location":"phil/cost-comparison/#what-you-cant-put-a-price-on","title":"What You Can't Put a Price On","text":""},{"location":"phil/cost-comparison/#privacy-violations","title":"Privacy Violations","text":"
    • Data Harvesting: Every interaction monitored and stored
    • Behavioral Profiling: Your community mapped and analyzed
    • Third-Party Sales: Your data sold to unknown entities
    • Government Access: Warrantless surveillance through corporate partnerships
    "},{"location":"phil/cost-comparison/#political-manipulation","title":"Political Manipulation","text":"
    • Algorithmic Suppression: Your content reach artificially limited
    • Narrative Control: Corporate interests shape what your community sees
    • Shadow Banning: Activists systematically de-platformed
    • Counter-Intelligence: Your strategies monitored by opposition
    "},{"location":"phil/cost-comparison/#movement-disruption","title":"Movement Disruption","text":"
    • Dependency Creation: Critical infrastructure controlled by adversaries
    • Community Fragmentation: Platforms designed to extract attention, not build power
    • Organizing Interference: Corporate algorithms prioritize engagement over solidarity
    • Cultural Assimilation: Movement culture shaped by corporate values
    "},{"location":"phil/cost-comparison/#the-changemaker-advantage","title":"The Changemaker Advantage","text":""},{"location":"phil/cost-comparison/#what-you-get-for-50-150month","title":"What You Get for $50-150/month","text":""},{"location":"phil/cost-comparison/#complete-infrastructure","title":"Complete Infrastructure","text":"
    • Email System: Unlimited contacts, unlimited sends
    • Database Power: Unlimited records, unlimited complexity
    • Web Presence: Unlimited sites, unlimited traffic
    • Development Environment: Full coding environment with AI assistance
    • Documentation Platform: Beautiful, searchable knowledge base
    • Automation Engine: Connect everything, automate everything
    • File Storage: Unlimited files, unlimited backups
    "},{"location":"phil/cost-comparison/#true-ownership","title":"True Ownership","text":"
    • Your Domain: No corporate branding or limitations
    • Your Data: Complete export capability, no lock-in
    • Your Rules: No terms of service to violate
    • Your Community: No algorithmic manipulation
    "},{"location":"phil/cost-comparison/#community-support","title":"Community Support","text":"
    • Open Documentation: Complete guides and tutorials available
    • Community-Driven Development: Built by and for liberation movements
    • Technical Support: Professional assistance from BNKops cooperative
    • Political Alignment: Technology designed with movement values
    "},{"location":"phil/cost-comparison/#the-compound-effect","title":"The Compound Effect","text":""},{"location":"phil/cost-comparison/#year-over-year-savings","title":"Year Over Year Savings","text":"

    Corporate software costs grow exponentially: - Year 1: \"Starter\" pricing to hook you - Year 2: Feature limits force tier upgrades - Year 3: Usage growth triggers premium pricing - Year 4: Platform changes force expensive migrations - Year 5: Lock-in enables arbitrary price increases

    Changemaker Lite costs grow linearly with actual infrastructure needs: - Year 1: Base infrastructure costs - Year 2: Modest increases for storage/bandwidth only - Year 3: Scale only with actual technical requirements - Year 4: Community-driven improvements at no extra cost - Year 5: Established infrastructure with declining per-user costs

    "},{"location":"phil/cost-comparison/#10-year-projection","title":"10-Year Projection","text":"Year Corporate (Medium Campaign) Changemaker Lite Annual Savings 1 $20,016 $900 $19,116 2 $22,017 $900 $21,117 3 $24,219 $1,080 $23,139 4 $26,641 $1,080 $25,561 5 $29,305 $1,260 $28,045 6 $32,235 $1,260 $30,975 7 $35,459 $1,440 $34,019 8 $39,005 $1,440 $37,565 9 $42,905 $1,620 $41,285 10 $47,196 $1,620 $45,576 TOTAL $318,998 $12,600 $306,398"},{"location":"phil/cost-comparison/#calculate-your-own-savings","title":"Calculate Your Own Savings","text":""},{"location":"phil/cost-comparison/#current-corporate-costs-worksheet","title":"Current Corporate Costs Worksheet","text":"

    Email Marketing: $____/month Database/CRM: $____/month Website Hosting: $____/month Documentation: $____/month Development Tools: $____/month Automation: $____/month File Storage: $____/month Other SaaS: $____/month

    Monthly Total: $____ Annual Total: $____

    Changemaker Alternative: $50-150/month Your Annual Savings: $____

    "},{"location":"phil/cost-comparison/#beyond-the-numbers","title":"Beyond the Numbers","text":""},{"location":"phil/cost-comparison/#what-movements-do-with-their-savings","title":"What Movements Do With Their Savings","text":"

    The money saved by choosing community-controlled technology doesn't disappear\u2014it goes directly back into movement building:

    • Hire organizers instead of paying corporate executives
    • Fund direct actions instead of funding surveillance infrastructure
    • Support community members instead of enriching shareholders
    • Build lasting power instead of temporary platform dependency
    "},{"location":"phil/cost-comparison/#making-the-switch","title":"Making the Switch","text":""},{"location":"phil/cost-comparison/#transition-strategy","title":"Transition Strategy","text":"

    You don't have to switch everything at once:

    1. Start with documentation - Move your knowledge base to MkDocs
    2. Add email infrastructure - Set up Listmonk for newsletters
    3. Build your database - Move contact management to NocoDB
    4. Automate connections - Use n8n to integrate everything
    5. Phase out corporate tools - Cancel subscriptions as you replicate functionality
    "},{"location":"phil/cost-comparison/#investment-timeline","title":"Investment Timeline","text":"
    • Month 1: Initial setup and learning ($150 including setup time)
    • Month 2-3: Data migration and team training ($100/month)
    • Month 4+: Full operation at optimal cost ($50-150/month based on scale)
    "},{"location":"phil/cost-comparison/#roi-calculation","title":"ROI Calculation","text":"

    Most campaigns recover their entire first-year investment in 60-90 days through subscription savings alone.

    Ready to stop feeding your budget to corporate surveillance? Get started with Changemaker Lite today and take control of your digital infrastructure.

    "},{"location":"services/","title":"Services","text":"

    Changemaker Lite includes several powerful services that work together to provide a complete documentation and development platform. Each service is containerized and can be accessed through its dedicated port.

    "},{"location":"services/#available-services","title":"Available Services","text":""},{"location":"services/#code-server","title":"Code Server","text":"

    Port: 8888 | Visual Studio Code in your browser for remote development

    • Full IDE experience
    • Extensions support
    • Git integration
    • Terminal access
    "},{"location":"services/#listmonk","title":"Listmonk","text":"

    Port: 9000 | Self-hosted newsletter and mailing list manager

    • Email campaigns
    • Subscriber management
    • Analytics
    • Template system
    "},{"location":"services/#postgresql","title":"PostgreSQL","text":"

    Port: 5432 | Reliable database backend - Data persistence for Listmonk - ACID compliance - High performance - Backup and restore capabilities

    "},{"location":"services/#mkdocs-material","title":"MkDocs Material","text":"

    Port: 4000 | Documentation site generator with live preview

    • Material Design theme
    • Live reload
    • Search functionality
    • Markdown support
    "},{"location":"services/#static-site-server","title":"Static Site Server","text":"

    Port: 4001 | Nginx-powered static site hosting - High-performance serving - Built documentation hosting - Caching and compression - Security headers

    "},{"location":"services/#n8n","title":"n8n","text":"

    Port: 5678 | Workflow automation tool

    • Visual workflow editor
    • 400+ integrations
    • Custom code execution
    • Webhook support
    "},{"location":"services/#nocodb","title":"NocoDB","text":"

    Port: 8090 | No-code database platform

    • Smart spreadsheet interface
    • Form builder and API generation
    • Real-time collaboration
    • Multi-database support
    "},{"location":"services/#homepage","title":"Homepage","text":"

    Port: 3010 | Modern dashboard for all services

    • Service dashboard and monitoring
    • Docker integration
    • Customizable layout
    • Quick search and bookmarks
    "},{"location":"services/#gitea","title":"Gitea","text":"

    Port: 3030 | Self-hosted Git service

    • Git repository hosting
    • Web-based interface
    • Issue tracking
    • Pull requests
    • Wiki and code review
    • Lightweight and easy to deploy
    "},{"location":"services/#mini-qr","title":"Mini QR","text":"

    Port: 8089 | Simple QR code generator service

    • Generate QR codes for text or URLs
    • Download QR codes as images
    • Simple and fast interface
    • No user registration required
    "},{"location":"services/#service-architecture","title":"Service Architecture","text":"
    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502   Homepage      \u2502    \u2502   Code Server   \u2502    \u2502     MkDocs      \u2502\n\u2502     :3010       \u2502    \u2502     :8888       \u2502    \u2502     :4000       \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 Static Server   \u2502    \u2502    Listmonk     \u2502    \u2502      n8n        \u2502\n\u2502     :4001       \u2502    \u2502     :9000       \u2502    \u2502     :5678       \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502     NocoDB      \u2502    \u2502 PostgreSQL      \u2502    \u2502 PostgreSQL      \u2502\n\u2502     :8090       \u2502    \u2502 (listmonk-db)   \u2502    \u2502 (root_db)       \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2502     :5432       \u2502    \u2502     :5432       \u2502\n         \u2502              \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n         \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n
    "},{"location":"services/#getting-started","title":"Getting Started","text":"
    1. Start all services: docker compose up -d
    2. Check service status: docker compose ps
    3. View logs: docker compose logs [service-name]
    4. Stop services: docker compose down
    "},{"location":"services/#service-dependencies","title":"Service Dependencies","text":"
    • Listmonk depends on PostgreSQL (listmonk-db)
    • NocoDB depends on PostgreSQL (root_db)
    • Static Server serves content built by MkDocs
    • n8n can integrate with all other services
    • All services share the changemaker network
    "},{"location":"services/#environment-configuration","title":"Environment Configuration","text":"

    Services are configured through environment variables in your .env file:

    # Port configurations\nCODE_SERVER_PORT=8888\nLISTMONK_PORT=9000\nLISTMONK_DB_PORT=5432\nMKDOCS_PORT=4000\nMKDOCS_SITE_SERVER_PORT=4001\nN8N_PORT=5678\n\n# User and group IDs\nUSER_ID=1000\nGROUP_ID=1000\n\n# Database configuration\nPOSTGRES_USER=listmonk\nPOSTGRES_PASSWORD=your_password\nPOSTGRES_DB=listmonk\n\n# n8n configuration\nN8N_ENCRYPTION_KEY=your_encryption_key\nN8N_USER_EMAIL=admin@example.com\nN8N_USER_PASSWORD=your_password\n
    "},{"location":"services/#monitoring-and-maintenance","title":"Monitoring and Maintenance","text":""},{"location":"services/#health-checks","title":"Health Checks","text":"
    # Check all services\ndocker compose ps\n\n# Check specific service logs\ndocker compose logs listmonk-app\ndocker compose logs code-server\n
    "},{"location":"services/#updates","title":"Updates","text":"
    # Pull latest images\ndocker compose pull\n\n# Restart with new images\ndocker compose down && docker compose up -d\n
    "},{"location":"services/#backups","title":"Backups","text":"
    • PostgreSQL: Regular database backups
    • n8n: Export workflows and credentials
    • Code Server: Backup configuration and workspace
    • MkDocs: Version control your documentation
    "},{"location":"services/#troubleshooting","title":"Troubleshooting","text":""},{"location":"services/#common-issues","title":"Common Issues","text":"
    1. Port Conflicts: Ensure ports are not used by other applications
    2. Permission Issues: Check USER_ID and GROUP_ID settings
    3. Network Issues: Verify services can communicate through the changemaker network
    4. Data Persistence: Ensure volumes are properly mounted
    "},{"location":"services/#getting-help","title":"Getting Help","text":"
    • Check individual service documentation
    • Review container logs for error messages
    • Verify environment variable configuration
    • Test network connectivity between services
    "},{"location":"services/code-server/","title":"Code Server","text":""},{"location":"services/code-server/#overview","title":"Overview","text":"

    Code Server provides a full Visual Studio Code experience in your web browser, allowing you to develop from any device. It runs on your server and provides access to your development environment through a web interface.

    "},{"location":"services/code-server/#features","title":"Features","text":"
    • Full VS Code experience in the browser
    • Extensions support
    • Terminal access
    • Git integration
    • File editing and management
    • Multi-language support
    "},{"location":"services/code-server/#access","title":"Access","text":"
    • Default Port: 8888
    • URL: http://localhost:8888
    • Default Workspace: /home/coder/mkdocs/
    "},{"location":"services/code-server/#configuration","title":"Configuration","text":""},{"location":"services/code-server/#environment-variables","title":"Environment Variables","text":"
    • DOCKER_USER: The user to run code-server as (default: coder)
    • DEFAULT_WORKSPACE: Default workspace directory
    • USER_ID: User ID for file permissions
    • GROUP_ID: Group ID for file permissions
    "},{"location":"services/code-server/#volumes","title":"Volumes","text":"
    • ./configs/code-server/.config: VS Code configuration
    • ./configs/code-server/.local: Local data
    • ./mkdocs: Main workspace directory
    "},{"location":"services/code-server/#usage","title":"Usage","text":"
    1. Access Code Server at http://localhost:8888
    2. Open the /home/coder/mkdocs/ workspace
    3. Start editing your documentation files
    4. Install extensions as needed
    5. Use the integrated terminal for commands
    "},{"location":"services/code-server/#useful-extensions","title":"Useful Extensions","text":"

    Consider installing these extensions for better documentation work:

    • Markdown All in One
    • Material Design Icons
    • GitLens
    • Docker
    • YAML
    "},{"location":"services/code-server/#official-documentation","title":"Official Documentation","text":"

    For more detailed information, visit the official Code Server documentation.

    "},{"location":"services/gitea/","title":"Gitea","text":"

    Self-hosted Git service for collaborative development.

    "},{"location":"services/gitea/#overview","title":"Overview","text":"

    Gitea is a lightweight, self-hosted Git service similar to GitHub, GitLab, and Bitbucket. It provides a web interface for managing repositories, issues, pull requests, and more.

    "},{"location":"services/gitea/#features","title":"Features","text":"
    • Git repository hosting
    • Web-based interface
    • Issue tracking
    • Pull requests
    • Wiki and code review
    • Lightweight and easy to deploy
    "},{"location":"services/gitea/#access","title":"Access","text":"
    • Default Web Port: ${GITEA_WEB_PORT:-3030} (default: 3030)
    • Default SSH Port: ${GITEA_SSH_PORT:-2222} (default: 2222)
    • URL: http://localhost:${GITEA_WEB_PORT:-3030}
    • Default Data Directory: /data/gitea
    "},{"location":"services/gitea/#configuration","title":"Configuration","text":""},{"location":"services/gitea/#environment-variables","title":"Environment Variables","text":"
    • GITEA__database__DB_TYPE: Database type (e.g., sqlite3, mysql, postgres)
    • GITEA__database__HOST: Database host (default: ${GITEA_DB_HOST:-gitea-db:3306})
    • GITEA__database__NAME: Database name (default: ${GITEA_DB_NAME:-gitea})
    • GITEA__database__USER: Database user (default: ${GITEA_DB_USER:-gitea})
    • GITEA__database__PASSWD: Database password (from .env)
    • GITEA__server__ROOT_URL: Root URL (e.g., ${GITEA_ROOT_URL})
    • GITEA__server__HTTP_PORT: Web port (default: 3000 inside container)
    • GITEA__server__DOMAIN: Domain (e.g., ${GITEA_DOMAIN})
    "},{"location":"services/gitea/#volumes","title":"Volumes","text":"
    • gitea_data:/data: Gitea configuration and data
    • /etc/timezone:/etc/timezone:ro
    • /etc/localtime:/etc/localtime:ro
    "},{"location":"services/gitea/#usage","title":"Usage","text":"
    1. Access Gitea at http://localhost:${GITEA_WEB_PORT:-3030}
    2. Register or log in as an admin user
    3. Create or import repositories
    4. Collaborate with your team
    "},{"location":"services/gitea/#official-documentation","title":"Official Documentation","text":"

    For more details, visit the official Gitea documentation.

    "},{"location":"services/homepage/","title":"Homepage","text":"

    Modern dashboard for accessing all your self-hosted services.

    "},{"location":"services/homepage/#overview","title":"Overview","text":"

    Homepage is a modern, fully static, fast, secure fully configurable application dashboard with integrations for over 100 services. It provides a beautiful and customizable interface to access all your Changemaker Lite services from a single location.

    "},{"location":"services/homepage/#features","title":"Features","text":"
    • Service Dashboard: Central hub for all your applications
    • Docker Integration: Automatic service discovery and monitoring
    • Customizable Layout: Flexible grid-based layout system
    • Service Widgets: Live status and metrics for services
    • Quick Search: Fast navigation with built-in search
    • Bookmarks: Organize frequently used links
    • Dark/Light Themes: Multiple color schemes available
    • Responsive Design: Works on desktop and mobile devices
    "},{"location":"services/homepage/#access","title":"Access","text":"
    • Default Port: 3010
    • URL: http://localhost:3010
    • Configuration: YAML-based configuration files
    "},{"location":"services/homepage/#configuration","title":"Configuration","text":""},{"location":"services/homepage/#environment-variables","title":"Environment Variables","text":"
    • HOMEPAGE_PORT: External port mapping (default: 3010)
    • PUID: User ID for file permissions (default: 1000)
    • PGID: Group ID for file permissions (default: 1000)
    • TZ: Timezone setting (default: Etc/UTC)
    • HOMEPAGE_ALLOWED_HOSTS: Allowed hosts for the dashboard
    "},{"location":"services/homepage/#configuration-files","title":"Configuration Files","text":"

    Homepage uses YAML configuration files located in ./configs/homepage/:

    • settings.yaml: Global settings and theme configuration
    • services.yaml: Service definitions and widgets
    • bookmarks.yaml: Bookmark categories and links
    • widgets.yaml: Dashboard widgets configuration
    • docker.yaml: Docker integration settings
    "},{"location":"services/homepage/#volumes","title":"Volumes","text":"
    • ./configs/homepage:/app/config: Configuration files
    • ./assets/icons:/app/public/icons: Custom service icons
    • ./assets/images:/app/public/images: Background images and assets
    • /var/run/docker.sock:/var/run/docker.sock: Docker socket for container monitoring
    "},{"location":"services/homepage/#changemaker-lite-services","title":"Changemaker Lite Services","text":"

    Homepage is pre-configured with all Changemaker Lite services:

    "},{"location":"services/homepage/#essential-tools","title":"Essential Tools","text":"
    • Code Server (Port 8888): VS Code in the browser
    • Listmonk (Port 9000): Newsletter & mailing list manager
    • NocoDB (Port 8090): No-code database platform
    "},{"location":"services/homepage/#content-documentation","title":"Content & Documentation","text":"
    • MkDocs (Port 4000): Live documentation server
    • Static Site (Port 4001): Built documentation hosting
    "},{"location":"services/homepage/#automation-data","title":"Automation & Data","text":"
    • n8n (Port 5678): Workflow automation platform
    • PostgreSQL (Port 5432): Database backends
    "},{"location":"services/homepage/#customization","title":"Customization","text":""},{"location":"services/homepage/#adding-custom-services","title":"Adding Custom Services","text":"

    Edit configs/homepage/services.yaml to add new services:

    - Custom Category:\n    - My Service:\n        href: http://localhost:8080\n        description: Custom service description\n        icon: mdi-application\n        widget:\n          type: ping\n          url: http://localhost:8080\n
    "},{"location":"services/homepage/#custom-icons","title":"Custom Icons","text":"

    Add custom icons to ./assets/icons/ directory and reference them in services.yaml:

    icon: /icons/my-custom-icon.png\n
    "},{"location":"services/homepage/#themes-and-styling","title":"Themes and Styling","text":"

    Modify configs/homepage/settings.yaml to customize appearance:

    theme: dark  # or light\ncolor: purple  # slate, gray, zinc, neutral, stone, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose\n
    "},{"location":"services/homepage/#widgets","title":"Widgets","text":"

    Enable live monitoring widgets in configs/homepage/services.yaml:

    - Service Name:\n    widget:\n      type: docker\n      container: container-name\n      server: my-docker\n
    "},{"location":"services/homepage/#service-monitoring","title":"Service Monitoring","text":"

    Homepage can display real-time status information for your services:

    • Docker Integration: Container status and resource usage
    • HTTP Ping: Service availability monitoring
    • Custom APIs: Integration with service-specific APIs
    "},{"location":"services/homepage/#docker-integration","title":"Docker Integration","text":"

    Homepage monitors Docker containers automatically when configured:

    1. Ensure Docker socket is mounted (/var/run/docker.sock)
    2. Configure container mappings in docker.yaml
    3. Add widget configurations to services.yaml
    "},{"location":"services/homepage/#security-considerations","title":"Security Considerations","text":"
    • Homepage runs with limited privileges
    • Configuration files should have appropriate permissions
    • Consider network isolation for production deployments
    • Use HTTPS for external access
    • Regularly update the Homepage image
    "},{"location":"services/homepage/#troubleshooting","title":"Troubleshooting","text":""},{"location":"services/homepage/#common-issues","title":"Common Issues","text":"

    Configuration not loading: Check YAML syntax in configuration files

    docker logs homepage-changemaker\n

    Icons not displaying: Verify icon paths and file permissions

    ls -la ./assets/icons/\n

    Services not reachable: Verify network connectivity between containers

    docker exec homepage-changemaker ping service-name\n

    Widget data not updating: Check Docker socket permissions and container access

    docker exec homepage-changemaker ls -la /var/run/docker.sock\n
    "},{"location":"services/homepage/#configuration-examples","title":"Configuration Examples","text":""},{"location":"services/homepage/#basic-service-widget","title":"Basic Service Widget","text":"
    - Code Server:\n    href: http://localhost:8888\n    description: VS Code in the browser\n    icon: code-server\n    widget:\n      type: docker\n      container: code-server-changemaker\n
    "},{"location":"services/homepage/#custom-dashboard-layout","title":"Custom Dashboard Layout","text":"
    # settings.yaml\nlayout:\n  style: columns\n  columns: 3\n\n# Responsive breakpoints\nresponsive:\n  mobile: 1\n  tablet: 2\n  desktop: 3\n
    "},{"location":"services/homepage/#official-documentation","title":"Official Documentation","text":"

    For comprehensive configuration guides and advanced features:

    • Homepage Documentation
    • GitHub Repository
    • Configuration Examples
    • Widget Integrations
    "},{"location":"services/listmonk/","title":"Listmonk","text":"

    Self-hosted newsletter and mailing list manager.

    "},{"location":"services/listmonk/#overview","title":"Overview","text":"

    Listmonk is a modern, feature-rich newsletter and mailing list manager designed for high performance and easy management. It provides a complete solution for email campaigns, subscriber management, and analytics.

    "},{"location":"services/listmonk/#features","title":"Features","text":"
    • Newsletter and email campaign management
    • Subscriber list management
    • Template system with HTML/markdown support
    • Campaign analytics and tracking
    • API for integration
    • Multi-list support
    • Bounce handling
    • Privacy-focused design
    "},{"location":"services/listmonk/#access","title":"Access","text":"
    • Default Port: 9000
    • URL: http://localhost:9000
    • Admin User: Set via LISTMONK_ADMIN_USER environment variable
    • Admin Password: Set via LISTMONK_ADMIN_PASSWORD environment variable
    "},{"location":"services/listmonk/#configuration","title":"Configuration","text":""},{"location":"services/listmonk/#environment-variables","title":"Environment Variables","text":"
    • LISTMONK_ADMIN_USER: Admin username
    • LISTMONK_ADMIN_PASSWORD: Admin password
    • POSTGRES_USER: Database username
    • POSTGRES_PASSWORD: Database password
    • POSTGRES_DB: Database name
    "},{"location":"services/listmonk/#database","title":"Database","text":"

    Listmonk uses PostgreSQL as its backend database. The database is automatically configured through the docker-compose setup.

    "},{"location":"services/listmonk/#uploads","title":"Uploads","text":"
    • Upload directory: ./assets/uploads
    • Used for media files, templates, and attachments
    "},{"location":"services/listmonk/#getting-started","title":"Getting Started","text":"
    1. Access Listmonk at http://localhost:9000
    2. Log in with your admin credentials
    3. Set up your first mailing list
    4. Configure SMTP settings for sending emails
    5. Import subscribers or create subscription forms
    6. Create your first campaign
    "},{"location":"services/listmonk/#important-notes","title":"Important Notes","text":"
    • Configure SMTP settings before sending emails
    • Set up proper domain authentication (SPF, DKIM) for better deliverability
    • Regularly backup your subscriber data and campaigns
    • Monitor bounce rates and maintain list hygiene
    "},{"location":"services/listmonk/#official-documentation","title":"Official Documentation","text":"

    For comprehensive guides and API documentation, visit: - Listmonk Documentation - GitHub Repository

    "},{"location":"services/map/","title":"Map","text":"

    Interactive map service for geospatial data visualization, powered by NocoDB and Leaflet.js.

    "},{"location":"services/map/#overview","title":"Overview","text":"

    The Map service provides an interactive web-based map for displaying, searching, and analyzing geospatial data from a NocoDB backend. It supports real-time geolocation, adding new locations, and is optimized for both desktop and mobile use.

    "},{"location":"services/map/#features","title":"Features","text":"
    • Interactive map visualization with OpenStreetMap
    • Real-time geolocation support
    • Add new locations directly from the map
    • Auto-refresh every 30 seconds
    • Responsive design for mobile devices
    • Secure API proxy to protect credentials
    • Docker containerization for easy deployment
    "},{"location":"services/map/#access","title":"Access","text":"
    • Default Port: ${MAP_PORT:-3000} (default: 3000)
    • URL: http://localhost:${MAP_PORT:-3000}
    • Default Workspace: /app/public/
    "},{"location":"services/map/#configuration","title":"Configuration","text":"

    All configuration is done via environment variables:

    Variable Description Default NOCODB_API_URL NocoDB API base URL Required NOCODB_API_TOKEN API authentication token Required NOCODB_VIEW_URL Full NocoDB view URL Required PORT Server port 3000 DEFAULT_LAT Default map latitude 53.5461 DEFAULT_LNG Default map longitude -113.4938 DEFAULT_ZOOM Default map zoom level 11"},{"location":"services/map/#volumes","title":"Volumes","text":"
    • ./map/app/public: Map public assets
    "},{"location":"services/map/#usage","title":"Usage","text":"
    1. Access the map at http://localhost:${MAP_PORT:-3000}
    2. Search for locations or addresses
    3. Add or view custom markers
    4. Analyze geospatial data as needed
    "},{"location":"services/map/#nocodb-table-setup","title":"NocoDB Table Setup","text":""},{"location":"services/map/#required-columns","title":"Required Columns","text":"
    • geodata (Text): Format \"latitude;longitude\"
    • latitude (Decimal): Precision 10, Scale 8
    • longitude (Decimal): Precision 11, Scale 8
    "},{"location":"services/map/#form-fields-as-seen-in-the-interface","title":"Form Fields (as seen in the interface)","text":"
    • First Name (Text): Person's first name
    • Last Name (Text): Person's last name
    • Email (Email): Contact email address
    • Unit Number (Text): Apartment/unit number
    • Support Level (Single Select):
    • 1 - Strong Support (Green)
    • 2 - Moderate Support (Yellow)
    • 3 - Low Support (Orange)
    • 4 - No Support (Red)
    • Address (Text): Full street address
    • Sign (Checkbox): Has campaign sign (true/false)
    • Sign Size (Single Select): Small, Medium, Large
    • Geo-Location (Text): Formatted as \"latitude;longitude\"
    "},{"location":"services/map/#api-endpoints","title":"API Endpoints","text":"
    • GET /api/locations - Fetch all locations
    • POST /api/locations - Create new location
    • GET /api/locations/:id - Get single location
    • PUT /api/locations/:id - Update location
    • DELETE /api/locations/:id - Delete location
    • GET /health - Health check
    "},{"location":"services/map/#security-considerations","title":"Security Considerations","text":"
    • API tokens are kept server-side only
    • CORS is configured for security
    • Rate limiting prevents abuse
    • Input validation on all endpoints
    • Helmet.js for security headers
    "},{"location":"services/map/#troubleshooting","title":"Troubleshooting","text":"
    • Ensure NocoDB table has required columns and valid coordinates
    • Check API token permissions and network connectivity
    "},{"location":"services/mini-qr/","title":"Mini QR","text":"

    Simple QR code generator service.

    "},{"location":"services/mini-qr/#overview","title":"Overview","text":"

    Mini QR is a lightweight service for generating QR codes for URLs, text, or other data. It provides a web interface for quick QR code creation and download.

    "},{"location":"services/mini-qr/#features","title":"Features","text":"
    • Generate QR codes for text or URLs
    • Download QR codes as images
    • Simple and fast interface
    • No user registration required
    "},{"location":"services/mini-qr/#access","title":"Access","text":"
    • Default Port: ${MINI_QR_PORT:-8089} (default: 8089)
    • URL: http://localhost:${MINI_QR_PORT:-8089}
    "},{"location":"services/mini-qr/#configuration","title":"Configuration","text":""},{"location":"services/mini-qr/#environment-variables","title":"Environment Variables","text":"
    • QR_DEFAULT_SIZE: Default size of generated QR codes
    • QR_IMAGE_FORMAT: Image format (e.g., png, svg)
    "},{"location":"services/mini-qr/#volumes","title":"Volumes","text":"
    • ./configs/mini-qr: QR code service configuration
    "},{"location":"services/mini-qr/#usage","title":"Usage","text":"
    1. Access Mini QR at http://localhost:${MINI_QR_PORT:-8089}
    2. Enter the text or URL to encode
    3. Download or share the generated QR code
    "},{"location":"services/mkdocs/","title":"MkDocs Material","text":"

    Modern documentation site generator with live preview.

    Looking for more info on BNKops code-server integration?

    \u2192 Code Server Configuration

    "},{"location":"services/mkdocs/#overview","title":"Overview","text":"

    MkDocs Material is a powerful documentation framework built on top of MkDocs, providing a beautiful Material Design theme and advanced features for creating professional documentation sites.

    "},{"location":"services/mkdocs/#features","title":"Features","text":"
    • Material Design theme
    • Live preview during development
    • Search functionality
    • Navigation and organization
    • Code syntax highlighting
    • Mathematical expressions support
    • Responsive design
    • Customizable themes and colors
    "},{"location":"services/mkdocs/#access","title":"Access","text":"
    • Development Port: 4000
    • Development URL: http://localhost:4000
    • Live Reload: Automatically refreshes on file changes
    "},{"location":"services/mkdocs/#configuration","title":"Configuration","text":""},{"location":"services/mkdocs/#main-configuration","title":"Main Configuration","text":"

    Configuration is managed through mkdocs.yml in the project root.

    "},{"location":"services/mkdocs/#volumes","title":"Volumes","text":"
    • ./mkdocs: Documentation source files
    • ./assets/images: Shared images directory
    "},{"location":"services/mkdocs/#environment-variables","title":"Environment Variables","text":"
    • SITE_URL: Base domain for the site
    • USER_ID: User ID for file permissions
    • GROUP_ID: Group ID for file permissions
    "},{"location":"services/mkdocs/#directory-structure","title":"Directory Structure","text":"
    mkdocs/\n\u251c\u2500\u2500 mkdocs.yml          # Configuration file\n\u251c\u2500\u2500 docs/               # Documentation source\n\u2502   \u251c\u2500\u2500 index.md       # Homepage\n\u2502   \u251c\u2500\u2500 services/      # Service documentation\n\u2502   \u251c\u2500\u2500 blog/          # Blog posts\n\u2502   \u2514\u2500\u2500 overrides/     # Template overrides\n\u2514\u2500\u2500 site/              # Built static site\n
    "},{"location":"services/mkdocs/#writing-documentation","title":"Writing Documentation","text":""},{"location":"services/mkdocs/#markdown-basics","title":"Markdown Basics","text":"
    • Use standard Markdown syntax
    • Support for tables, code blocks, and links
    • Mathematical expressions with MathJax
    • Admonitions for notes and warnings
    "},{"location":"services/mkdocs/#example-page","title":"Example Page","text":"
    # Page Title\n\nThis is a sample documentation page.\n\n## Section\n\nContent goes here with **bold** and *italic* text.\n\n### Code Example\n\n```python\ndef hello_world():\n    print(\"Hello, World!\")\n

    Note

    This is an informational note.

    ## Building and Deployment\n\n### Development\n\nThe development server runs automatically with live reload.\n\n### Building Static Site\n\n```bash\ndocker exec mkdocs-changemaker mkdocs build\n

    The built site will be available in the mkdocs/site/ directory.

    "},{"location":"services/mkdocs/#customization","title":"Customization","text":""},{"location":"services/mkdocs/#themes-and-colors","title":"Themes and Colors","text":"

    Customize appearance in mkdocs.yml:

    theme:\n  name: material\n  palette:\n    primary: blue\n    accent: indigo\n
    "},{"location":"services/mkdocs/#custom-css","title":"Custom CSS","text":"

    Add custom styles in docs/stylesheets/extra.css.

    "},{"location":"services/mkdocs/#official-documentation","title":"Official Documentation","text":"

    For comprehensive MkDocs Material documentation: - MkDocs Material - MkDocs Documentation - Markdown Guide

    "},{"location":"services/n8n/","title":"n8n","text":"

    Workflow automation tool for connecting services and automating tasks.

    "},{"location":"services/n8n/#overview","title":"Overview","text":"

    n8n is a powerful workflow automation tool that allows you to connect various apps and services together. It provides a visual interface for creating automated workflows, making it easy to integrate different systems and automate repetitive tasks.

    "},{"location":"services/n8n/#features","title":"Features","text":"
    • Visual workflow editor
    • 400+ integrations
    • Custom code execution (JavaScript/Python)
    • Webhook support
    • Scheduled workflows
    • Error handling and retries
    • User management
    • API access
    • Self-hosted and privacy-focused
    "},{"location":"services/n8n/#access","title":"Access","text":"
    • Default Port: 5678
    • URL: http://localhost:5678
    • Default User Email: Set via N8N_DEFAULT_USER_EMAIL
    • Default User Password: Set via N8N_DEFAULT_USER_PASSWORD
    "},{"location":"services/n8n/#configuration","title":"Configuration","text":""},{"location":"services/n8n/#environment-variables","title":"Environment Variables","text":"
    • N8N_HOST: Hostname for n8n (default: n8n.${DOMAIN})
    • N8N_PORT: Internal port (5678)
    • N8N_PROTOCOL: Protocol for webhooks (https)
    • NODE_ENV: Environment (production)
    • WEBHOOK_URL: Base URL for webhooks
    • GENERIC_TIMEZONE: Timezone setting
    • N8N_ENCRYPTION_KEY: Encryption key for credentials
    • N8N_USER_MANAGEMENT_DISABLED: Enable/disable user management
    • N8N_DEFAULT_USER_EMAIL: Default admin email
    • N8N_DEFAULT_USER_PASSWORD: Default admin password
    "},{"location":"services/n8n/#volumes","title":"Volumes","text":"
    • n8n_data: Persistent data storage
    • ./local-files: Local file access for workflows
    "},{"location":"services/n8n/#getting-started","title":"Getting Started","text":"
    1. Access n8n at http://localhost:5678
    2. Log in with your admin credentials
    3. Create your first workflow
    4. Add nodes for different services
    5. Configure connections between nodes
    6. Test and activate your workflow
    "},{"location":"services/n8n/#common-use-cases","title":"Common Use Cases","text":""},{"location":"services/n8n/#documentation-automation","title":"Documentation Automation","text":"
    • Auto-generate documentation from code comments
    • Sync documentation between different platforms
    • Notify team when documentation is updated
    "},{"location":"services/n8n/#email-campaign-integration","title":"Email Campaign Integration","text":"
    • Connect Listmonk with external data sources
    • Automate subscriber management
    • Trigger campaigns based on events
    "},{"location":"services/n8n/#database-management-with-nocodb","title":"Database Management with NocoDB","text":"
    • Sync data between NocoDB and external APIs
    • Automate data entry and validation
    • Create backup workflows for database content
    • Generate reports from NocoDB data
    "},{"location":"services/n8n/#development-workflows","title":"Development Workflows","text":"
    • Auto-deploy documentation on git push
    • Sync code changes with documentation
    • Backup automation
    "},{"location":"services/n8n/#data-processing","title":"Data Processing","text":"
    • Process CSV files and import to databases
    • Transform data between different formats
    • Schedule regular data updates
    "},{"location":"services/n8n/#example-workflows","title":"Example Workflows","text":""},{"location":"services/n8n/#simple-webhook-to-email","title":"Simple Webhook to Email","text":"
    Webhook \u2192 Email\n
    "},{"location":"services/n8n/#scheduled-documentation-backup","title":"Scheduled Documentation Backup","text":"
    Schedule \u2192 Read Files \u2192 Compress \u2192 Upload to Storage\n
    "},{"location":"services/n8n/#git-integration","title":"Git Integration","text":"
    Git Webhook \u2192 Process Changes \u2192 Update Documentation \u2192 Notify Team\n
    "},{"location":"services/n8n/#security-considerations","title":"Security Considerations","text":"
    • Use strong encryption keys
    • Secure webhook URLs
    • Regularly update credentials
    • Monitor workflow executions
    • Implement proper error handling
    "},{"location":"services/n8n/#integration-with-other-services","title":"Integration with Other Services","text":"

    n8n can integrate with all services in your Changemaker Lite setup:

    • Listmonk: Manage subscribers and campaigns
    • PostgreSQL: Read/write database operations
    • Code Server: File operations and git integration
    • MkDocs: Documentation generation and updates
    "},{"location":"services/n8n/#troubleshooting","title":"Troubleshooting","text":""},{"location":"services/n8n/#common-issues","title":"Common Issues","text":"
    • Workflow Execution Errors: Check node configurations and credentials
    • Webhook Issues: Verify URLs and authentication
    • Connection Problems: Check network connectivity between services
    "},{"location":"services/n8n/#debugging","title":"Debugging","text":"
    # Check container logs\ndocker logs n8n-changemaker\n\n# Access container shell\ndocker exec -it n8n-changemaker sh\n\n# Check workflow executions in the UI\n# Visit http://localhost:5678 \u2192 Executions\n
    "},{"location":"services/n8n/#official-documentation","title":"Official Documentation","text":"

    For comprehensive n8n documentation:

    • n8n Documentation
    • Community Workflows
    • Node Reference
    • GitHub Repository
    "},{"location":"services/nocodb/","title":"NocoDB","text":"

    No-code database platform that turns any database into a smart spreadsheet.

    "},{"location":"services/nocodb/#overview","title":"Overview","text":"

    NocoDB is an open-source no-code platform that transforms any database into a smart spreadsheet interface. It provides a user-friendly way to manage data, create forms, build APIs, and collaborate on database operations without requiring extensive technical knowledge.

    "},{"location":"services/nocodb/#features","title":"Features","text":"
    • Smart Spreadsheet Interface: Transform databases into intuitive spreadsheets
    • Form Builder: Create custom forms for data entry
    • API Generation: Auto-generated REST APIs for all tables
    • Collaboration: Real-time collaboration with team members
    • Access Control: Role-based permissions and sharing
    • Data Visualization: Charts and dashboard creation
    • Webhooks: Integration with external services
    • Import/Export: Support for CSV, Excel, and other formats
    • Multi-Database Support: Works with PostgreSQL, MySQL, SQLite, and more
    "},{"location":"services/nocodb/#access","title":"Access","text":"
    • Default Port: 8090
    • URL: http://localhost:8090
    • Database: PostgreSQL (dedicated root_db instance)
    "},{"location":"services/nocodb/#configuration","title":"Configuration","text":""},{"location":"services/nocodb/#environment-variables","title":"Environment Variables","text":"
    • NOCODB_PORT: External port mapping (default: 8090)
    • NC_DB: Database connection string for PostgreSQL backend
    "},{"location":"services/nocodb/#database-backend","title":"Database Backend","text":"

    NocoDB uses a dedicated PostgreSQL instance (root_db) with the following configuration:

    • Database Name: root_db
    • Username: postgres
    • Password: password
    • Host: root_db (internal container name)
    "},{"location":"services/nocodb/#volumes","title":"Volumes","text":"
    • nc_data: Application data and configuration storage
    • db_data: PostgreSQL database files
    "},{"location":"services/nocodb/#getting-started","title":"Getting Started","text":"
    1. Access NocoDB: Navigate to http://localhost:8090
    2. Initial Setup: Complete the onboarding process
    3. Create Project: Start with a new project or connect existing databases
    4. Add Tables: Import data or create new tables
    5. Configure Views: Set up different views (Grid, Form, Gallery, etc.)
    6. Set Permissions: Configure user access and sharing settings
    "},{"location":"services/nocodb/#common-use-cases","title":"Common Use Cases","text":""},{"location":"services/nocodb/#content-management","title":"Content Management","text":"
    • Create content databases for blogs and websites
    • Manage product catalogs and inventories
    • Track customer information and interactions
    "},{"location":"services/nocodb/#project-management","title":"Project Management","text":"
    • Task and project tracking systems
    • Team collaboration workspaces
    • Resource and timeline management
    "},{"location":"services/nocodb/#data-collection","title":"Data Collection","text":"
    • Custom forms for surveys and feedback
    • Event registration and management
    • Lead capture and CRM systems
    "},{"location":"services/nocodb/#integration-with-other-services","title":"Integration with Other Services","text":"

    NocoDB can integrate well with other Changemaker Lite services:

    • n8n Integration: Use NocoDB as a data source/destination in automation workflows
    • Listmonk Integration: Manage subscriber lists and campaign data
    • Documentation: Store and manage documentation metadata
    "},{"location":"services/nocodb/#api-usage","title":"API Usage","text":"

    NocoDB automatically generates REST APIs for all your tables:

    # Get all records from a table\nGET http://localhost:8090/api/v1/db/data/v1/{project}/table/{table}\n\n# Create a new record\nPOST http://localhost:8090/api/v1/db/data/v1/{project}/table/{table}\n\n# Update a record\nPATCH http://localhost:8090/api/v1/db/data/v1/{project}/table/{table}/{id}\n
    "},{"location":"services/nocodb/#backup-and-data-management","title":"Backup and Data Management","text":""},{"location":"services/nocodb/#database-backup","title":"Database Backup","text":"

    Since NocoDB uses PostgreSQL, you can backup the database:

    # Backup NocoDB database\ndocker exec root_db pg_dump -U postgres root_db > nocodb_backup.sql\n\n# Restore from backup\ndocker exec -i root_db psql -U postgres root_db < nocodb_backup.sql\n
    "},{"location":"services/nocodb/#application-data","title":"Application Data","text":"

    Application settings and metadata are stored in the nc_data volume.

    "},{"location":"services/nocodb/#security-considerations","title":"Security Considerations","text":"
    • Change default database credentials in production
    • Configure proper access controls within NocoDB
    • Use HTTPS for production deployments
    • Regularly backup both database and application data
    • Monitor access logs and user activities
    "},{"location":"services/nocodb/#performance-tips","title":"Performance Tips","text":"
    • Regular database maintenance and optimization
    • Monitor memory usage for large datasets
    • Use appropriate indexing for frequently queried fields
    • Consider database connection pooling for high-traffic scenarios
    "},{"location":"services/nocodb/#troubleshooting","title":"Troubleshooting","text":""},{"location":"services/nocodb/#common-issues","title":"Common Issues","text":"

    Service won't start: Check if the PostgreSQL database is healthy

    docker logs root_db\n

    Database connection errors: Verify database credentials and network connectivity

    docker exec nocodb nc_data nc\n

    Performance issues: Monitor resource usage and optimize queries

    docker stats nocodb root_db\n
    "},{"location":"services/nocodb/#official-documentation","title":"Official Documentation","text":"

    For comprehensive guides and advanced features:

    • NocoDB Documentation
    • GitHub Repository
    • Community Forum
    "},{"location":"services/postgresql/","title":"PostgreSQL Database","text":"

    Reliable database backend for applications.

    "},{"location":"services/postgresql/#overview","title":"Overview","text":"

    PostgreSQL is a powerful, open-source relational database system. In Changemaker Lite, it serves as the backend database for Listmonk and can be used by other applications requiring persistent data storage.

    "},{"location":"services/postgresql/#features","title":"Features","text":"
    • ACID compliance
    • Advanced SQL features
    • JSON/JSONB support
    • Full-text search
    • Extensibility
    • High performance
    • Reliability and data integrity
    "},{"location":"services/postgresql/#access","title":"Access","text":"
    • Default Port: 5432
    • Host: listmonk-db (internal container name)
    • Database: Set via POSTGRES_DB environment variable
    • Username: Set via POSTGRES_USER environment variable
    • Password: Set via POSTGRES_PASSWORD environment variable
    "},{"location":"services/postgresql/#configuration","title":"Configuration","text":""},{"location":"services/postgresql/#environment-variables","title":"Environment Variables","text":"
    • POSTGRES_USER: Database username
    • POSTGRES_PASSWORD: Database password
    • POSTGRES_DB: Database name
    "},{"location":"services/postgresql/#health-checks","title":"Health Checks","text":"

    The PostgreSQL container includes health checks to ensure the database is ready before dependent services start.

    "},{"location":"services/postgresql/#data-persistence","title":"Data Persistence","text":"

    Database data is stored in a Docker volume (listmonk-data) to ensure persistence across container restarts.

    "},{"location":"services/postgresql/#connecting-to-the-database","title":"Connecting to the Database","text":""},{"location":"services/postgresql/#from-host-machine","title":"From Host Machine","text":"

    You can connect to PostgreSQL from your host machine using:

    psql -h localhost -p 5432 -U [username] -d [database]\n
    "},{"location":"services/postgresql/#from-other-containers","title":"From Other Containers","text":"

    Other containers can connect using the internal hostname listmonk-db on port 5432.

    "},{"location":"services/postgresql/#backup-and-restore","title":"Backup and Restore","text":""},{"location":"services/postgresql/#backup","title":"Backup","text":"
    docker exec listmonk-db pg_dump -U [username] [database] > backup.sql\n
    "},{"location":"services/postgresql/#restore","title":"Restore","text":"
    docker exec -i listmonk-db psql -U [username] [database] < backup.sql\n
    "},{"location":"services/postgresql/#monitoring","title":"Monitoring","text":"

    Monitor database health and performance through: - Container logs: docker logs listmonk-db - Database metrics and queries - Connection monitoring

    "},{"location":"services/postgresql/#security-considerations","title":"Security Considerations","text":"
    • Use strong passwords
    • Regularly update PostgreSQL version
    • Monitor access logs
    • Implement regular backups
    • Consider network isolation
    "},{"location":"services/postgresql/#official-documentation","title":"Official Documentation","text":"

    For comprehensive PostgreSQL documentation: - PostgreSQL Documentation - Docker PostgreSQL Image

    "},{"location":"services/static-server/","title":"Static Site Server","text":"

    Nginx-powered static site server for hosting built documentation and websites.

    "},{"location":"services/static-server/#overview","title":"Overview","text":"

    The Static Site Server uses Nginx to serve your built documentation and static websites. It's configured to serve the built MkDocs site and other static content with high performance and reliability.

    "},{"location":"services/static-server/#features","title":"Features","text":"
    • High-performance static file serving
    • Automatic index file handling
    • Gzip compression
    • Caching headers
    • Security headers
    • Custom error pages
    • URL rewriting support
    "},{"location":"services/static-server/#access","title":"Access","text":"
    • Default Port: 4001
    • URL: http://localhost:4001
    • Document Root: /config/www (mounted from ./mkdocs/site)
    "},{"location":"services/static-server/#configuration","title":"Configuration","text":""},{"location":"services/static-server/#environment-variables","title":"Environment Variables","text":"
    • PUID: User ID for file permissions (default: 1000)
    • PGID: Group ID for file permissions (default: 1000)
    • TZ: Timezone setting (default: Etc/UTC)
    "},{"location":"services/static-server/#volumes","title":"Volumes","text":"
    • ./mkdocs/site:/config/www: Static site files
    • Built MkDocs site is automatically served
    "},{"location":"services/static-server/#usage","title":"Usage","text":"
    1. Build your MkDocs site: docker exec mkdocs-changemaker mkdocs build
    2. The built site is automatically available at http://localhost:4001
    3. Any files in ./mkdocs/site/ will be served statically
    "},{"location":"services/static-server/#file-structure","title":"File Structure","text":"
    mkdocs/site/           # Served at /\n\u251c\u2500\u2500 index.html         # Homepage\n\u251c\u2500\u2500 assets/           # CSS, JS, images\n\u251c\u2500\u2500 services/         # Service documentation\n\u2514\u2500\u2500 search/           # Search functionality\n
    "},{"location":"services/static-server/#performance-features","title":"Performance Features","text":"
    • Gzip Compression: Automatic compression for text files
    • Browser Caching: Optimized cache headers
    • Fast Static Serving: Nginx optimized for static content
    • Security Headers: Basic security header configuration
    "},{"location":"services/static-server/#custom-configuration","title":"Custom Configuration","text":"

    For advanced Nginx configuration, you can: 1. Create custom Nginx config files 2. Mount them as volumes 3. Restart the container

    "},{"location":"services/static-server/#monitoring","title":"Monitoring","text":"

    Monitor the static site server through: - Container logs: docker logs mkdocs-site-server-changemaker - Access logs for traffic analysis - Performance metrics

    "},{"location":"services/static-server/#troubleshooting","title":"Troubleshooting","text":""},{"location":"services/static-server/#common-issues","title":"Common Issues","text":"
    • 404 Errors: Ensure MkDocs site is built and files exist in ./mkdocs/site/
    • Permission Issues: Check PUID and PGID settings
    • File Not Found: Verify file paths and case sensitivity
    "},{"location":"services/static-server/#debugging","title":"Debugging","text":"
    # Check container logs\ndocker logs mkdocs-site-server-changemaker\n\n# Verify files are present\ndocker exec mkdocs-site-server-changemaker ls -la /config/www\n\n# Test file serving\ncurl -I http://localhost:4001\n
    "},{"location":"services/static-server/#official-documentation","title":"Official Documentation","text":"

    For more information about the underlying Nginx server: - LinuxServer.io Nginx - Nginx Documentation

    "},{"location":"blog/archive/2025/","title":"2025","text":""}]} \ No newline at end of file diff --git a/mkdocs/site/sitemap.xml b/mkdocs/site/sitemap.xml index 65955fa..fa233b9 100644 --- a/mkdocs/site/sitemap.xml +++ b/mkdocs/site/sitemap.xml @@ -2,118 +2,122 @@ https://cmlite.org/ - 2025-07-03 + 2025-07-04 + + + https://cmlite.org/test/ + 2025-07-04 https://cmlite.org/adv/ - 2025-07-03 + 2025-07-04 https://cmlite.org/adv/ansible/ - 2025-07-03 + 2025-07-04 https://cmlite.org/adv/vscode-ssh/ - 2025-07-03 + 2025-07-04 https://cmlite.org/blog/ - 2025-07-03 + 2025-07-04 https://cmlite.org/blog/2025/07/03/blog-1/ - 2025-07-03 + 2025-07-04 https://cmlite.org/build/ - 2025-07-03 + 2025-07-04 https://cmlite.org/build/map/ - 2025-07-03 + 2025-07-04 https://cmlite.org/build/server/ - 2025-07-03 + 2025-07-04 https://cmlite.org/build/site/ - 2025-07-03 + 2025-07-04 https://cmlite.org/config/ - 2025-07-03 + 2025-07-04 https://cmlite.org/config/cloudflare-config/ - 2025-07-03 + 2025-07-04 https://cmlite.org/config/coder/ - 2025-07-03 + 2025-07-04 https://cmlite.org/config/mkdocs/ - 2025-07-03 + 2025-07-04 https://cmlite.org/phil/ - 2025-07-03 + 2025-07-04 https://cmlite.org/phil/cost-comparison/ - 2025-07-03 + 2025-07-04 https://cmlite.org/services/ - 2025-07-03 + 2025-07-04 https://cmlite.org/services/code-server/ - 2025-07-03 + 2025-07-04 https://cmlite.org/services/gitea/ - 2025-07-03 + 2025-07-04 https://cmlite.org/services/homepage/ - 2025-07-03 + 2025-07-04 https://cmlite.org/services/listmonk/ - 2025-07-03 + 2025-07-04 https://cmlite.org/services/map/ - 2025-07-03 + 2025-07-04 https://cmlite.org/services/mini-qr/ - 2025-07-03 + 2025-07-04 https://cmlite.org/services/mkdocs/ - 2025-07-03 + 2025-07-04 https://cmlite.org/services/n8n/ - 2025-07-03 + 2025-07-04 https://cmlite.org/services/nocodb/ - 2025-07-03 + 2025-07-04 https://cmlite.org/services/postgresql/ - 2025-07-03 + 2025-07-04 https://cmlite.org/services/static-server/ - 2025-07-03 + 2025-07-04 https://cmlite.org/blog/archive/2025/ - 2025-07-03 + 2025-07-04 \ No newline at end of file diff --git a/mkdocs/site/sitemap.xml.gz b/mkdocs/site/sitemap.xml.gz index dddbabdec35dce000d499ef54557ef90fa2e05f7..621ee72737f1f50287a7a144be8609d7e16bc1b6 100644 GIT binary patch literal 378 zcmV-=0fqh_iwFpS8E0q$|8r?{Wo=<_E_iKh0L9nMa)Tfc0N{I`!tsufw4J0KV{Uzd z_5lb|WWtYOiRt5a(M;N7r-v;U1$Xv4$S&F*KE10ZoxsMhuh)&JD;-qqZ7}=#{q2?Q z>O;3`FUf(<6$S^`*F(&8mm@SW84hZ|3Gmw@7tM3sttuQP!E!f`)XnA??GfqPGvF|ow^TfoKiAM~%tu2Z9J@YS(tRa&?vY*Ht8NeQ$Ci5o1 zJ)#-FKtdi}G;~nO$HkV5hk4G{H1x%~o=_?UN~eKN*kvd|oRV-Vh7W5fDdpm&|8O#C z_76DLeWC>YsgDXs#Bs2W4pI>^zCb_9WFZC;xRjw)8fdZQtf1=vci7;Hq$P*w^(c*| zRh=z)!iiR;Izqld8!S5$Zz945bT`9}xF3XwMS7$)M{Iy5X*fGt7qZM&Q8uLcvr;BC Y*hw#+mw#603;v6BUzRT@y1NYk01Jq+TL1t6 literal 374 zcmV-+0g3(}iwFn+$Yp2(|8r?{Wo=<_E_iKh0L9nMa)Tfc0N{I{!tsufWI9PZ#@zY@ z?E?@b$b=um64S@;qM5YEP7hly3hwN8z+JRGe0o<+I)RO0U#}WbS30QJ+hF$f$NL-G z)ran>y(R}bR~Q^%Uk^Etubkg*w+3w1UXIYjWH_h+C&2HETr@9r_f+9136{Hgv@WWy zWC2X0yut`mmOl&aZzP2RhkIcU`WIvHPGJrigP3BF2Tc;Vo zKtdi}G;~nO$HkV5%{*r-8v1HoPbihTq0>MoEPhH5rzD(;;baXZrChxBCnu9;|A1rN zCrZ$t`>23K90%*@AQd6w2KrGZ3o($ur3|goK#MJB1ziVtzy?<&EjdK5M`<*z>TJmq z&a^7k5%LY%VA+NEB_eD<4>RnD`$33Uq(@qF#0F@RhKr+hA + + + + + + + + + + + + + + + + + + + + + + + Test - Changemaker Lite + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    + + + + + +

    Test

    +

    lololol

    + + + + + + + + + + + + + + + + +
    +
    + + + +
    + + + +
    + + + +
    +
    +
    +
    + +
    + + + + + + + + + + + + + + + + + + \ No newline at end of file