<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Spoljarevic's Knowledgebase</title><link>https://kb-migration.spoljarevic.sh/</link><description>Recent content on Spoljarevic's Knowledgebase</description><generator>Hugo</generator><language>en-US</language><lastBuildDate>Fri, 23 Oct 2026 13:15:02 +0200</lastBuildDate><atom:link href="https://kb-migration.spoljarevic.sh/index.xml" rel="self" type="application/rss+xml"/><item><title>Impressum</title><link>https://kb-migration.spoljarevic.sh/legal/impressum/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/legal/impressum/</guid><description>&lt;h3 id="inhalte-gemäß--5-ddg"&gt;Inhalte gemäß § 5 DDG&#10;&lt;/h3&gt;&#10;&lt;p&gt;&lt;strong&gt;Luca Matteo Špoljarević&lt;/strong&gt;&lt;br&gt;&#10;c/o IP-Management #12320&lt;br&gt;&#10;Ludwig-Erhard-Straße 18&lt;br&gt;&#10;20459 Hamburg&lt;/p&gt;&#10;&lt;h5 id="kontaktdaten"&gt;Kontaktdaten:&#10;&lt;/h5&gt;&#10;&lt;p&gt;E-Mail: &lt;a href="mailto:webadmin@info.spoljarevic.sh"&gt;webadmin@info.spoljarevic.sh&lt;/a&gt;&lt;br&gt;&#10;Telefon: +49 7141 493 34 21&lt;/p&gt;&#10;&lt;h5 id="umsatzsteuer-identifikationsnummer-gemäß--27a-ustg"&gt;Umsatzsteuer-Identifikationsnummer gemäß § 27a UStG:&#10;&lt;/h5&gt;&#10;&lt;p&gt;DE457678112&lt;/p&gt;&#10;&lt;h5 id="redaktionell-verantwortlich"&gt;Redaktionell verantwortlich:&#10;&lt;/h5&gt;&#10;&lt;p&gt;Luca Matteo Špoljarević&lt;/p&gt;</description></item><item><title>Introduction</title><link>https://kb-migration.spoljarevic.sh/Big-Projects/Arch-Linux-Post-Install-Automation/Introduction/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/Big-Projects/Arch-Linux-Post-Install-Automation/Introduction/</guid><description>&lt;p&gt;&lt;strong&gt;Arch Linux Post-Install Automation&lt;/strong&gt; is an &lt;a href="https://www.ansible.com/"&gt;Ansible&lt;/a&gt; playbook that takes a fresh&#10;Arch Linux (or Arch-based, e.g. &lt;a href="https://cachyos.org/"&gt;CachyOS&lt;/a&gt;) install and turns it into a fully configured&#10;daily-driver machine — without manually installing packages, enabling services, or configuring your shell one&#10;by one.&lt;/p&gt;&#10;&lt;h2 id="what-it-does"&gt;What it does&#10;&lt;/h2&gt;&#10;&lt;p&gt;Run against a target host, the playbook will:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Bootstrap the &lt;strong&gt;CachyOS&lt;/strong&gt; and &lt;strong&gt;BlackArch&lt;/strong&gt; pacman repositories&lt;/li&gt;&#10;&lt;li&gt;Install a full package set via &lt;code&gt;pacman&lt;/code&gt;, the AUR (via &lt;code&gt;yay&lt;/code&gt;), Flatpak, and Snap&lt;/li&gt;&#10;&lt;li&gt;Apply basic &lt;strong&gt;system hardening&lt;/strong&gt; (firewalld, fail2ban, &lt;code&gt;doas&lt;/code&gt;, a non-default SSH port, disabled password&#10;authentication)&lt;/li&gt;&#10;&lt;li&gt;Create a standard set of user directories (&lt;code&gt;Documents&lt;/code&gt;, &lt;code&gt;Downloads&lt;/code&gt;, &lt;code&gt;Pictures/wallpaper&lt;/code&gt;, &lt;code&gt;git&lt;/code&gt;, &amp;hellip;)&lt;/li&gt;&#10;&lt;li&gt;Install and configure &lt;strong&gt;Zsh&lt;/strong&gt; with Oh My Zsh, Powerlevel10k, and a Nerd Font&lt;/li&gt;&#10;&lt;li&gt;Generate SSH and GPG keys and configure &lt;code&gt;git&lt;/code&gt; for signed commits&lt;/li&gt;&#10;&lt;li&gt;Clone a set of personal repositories (dotfiles, wallpapers, other projects)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="why-it-exists"&gt;Why it exists&#10;&lt;/h2&gt;&#10;&lt;p&gt;Re-installing Arch (or setting up a new machine) used to mean an hour or more of repetitive manual setup.&#10;This playbook exists so that process is a single command: point Ansible at a host, get a coffee, and come&#10;back to a fully configured system.&lt;/p&gt;</description></item><item><title>Introduction</title><link>https://kb-migration.spoljarevic.sh/Big-Projects/FreePBX-17-Docker-Setup/Introduction/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/Big-Projects/FreePBX-17-Docker-Setup/Introduction/</guid><description>&lt;h2 id="what-is-freepbx"&gt;What is FreePBX?&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;a href="https://www.freepbx.org/"&gt;FreePBX&lt;/a&gt; is an open-source web GUI for &lt;a href="https://www.asterisk.org/"&gt;Asterisk&lt;/a&gt;, the&#10;PBX/VoIP engine that underpins it. Asterisk on its own is configured through plain-text dialplan files;&#10;FreePBX wraps it in a web interface for managing extensions, trunks, inbound/outbound routes, IVRs,&#10;voicemail, and the rest of what a phone system needs, without hand-editing Asterisk config. Version 17 is&#10;the current release line, built on Asterisk 22 and PHP 8.2.&lt;/p&gt;</description></item><item><title>Introduction</title><link>https://kb-migration.spoljarevic.sh/Big-Projects/Zammad-Podman-Quadlets/Introduction/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/Big-Projects/Zammad-Podman-Quadlets/Introduction/</guid><description>&lt;h2 id="what-is-zammad"&gt;What is Zammad?&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;a href="https://zammad.org/"&gt;Zammad&lt;/a&gt; is an open-source ticket system. A ticket system is essential for any IT&#10;sysadmin — it organizes user problems into tickets and lets you document everything you did to solve them,&#10;instead of losing that history in email or chat.&lt;/p&gt;&#10;&lt;h2 id="what-are-quadlets"&gt;What are Quadlets?&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;a href="https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html"&gt;Quadlets&lt;/a&gt; are a Podman feature that&#10;lets you describe containers, pods, networks, and volumes as native &lt;strong&gt;systemd unit files&lt;/strong&gt;. &lt;code&gt;systemd&lt;/code&gt;&#10;generates the actual &lt;code&gt;.service&lt;/code&gt; units from them at boot/login, so Podman containers get managed exactly&#10;like any other systemd service — restarted on failure, started in dependency order, and started&#10;automatically without a separate compose daemon running in the background.&lt;/p&gt;</description></item><item><title>Introduction</title><link>https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/Introduction/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/Introduction/</guid><description>&lt;h2 id="what-is-lazynvim"&gt;What is lazy.nvim?&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;a href="https://github.com/folke/lazy.nvim"&gt;lazy.nvim&lt;/a&gt; is a plugin manager for Neovim. It handles cloning,&#10;updating, and lazy-loading plugins from a set of declarative &amp;ldquo;specs&amp;rdquo; — Lua tables that say which plugin to&#10;install, what triggers it to load (a command, a keymap, a filetype, an event), and how to configure it once&#10;loaded.&lt;/p&gt;&#10;&lt;h2 id="what-this-is"&gt;What this is&#10;&lt;/h2&gt;&#10;&lt;p&gt;A Neovim configuration written entirely from scratch on top of &lt;code&gt;lazy.nvim&lt;/code&gt; — every option, keymap, and&#10;plugin spec here was written by hand, plugin by plugin. It is &lt;strong&gt;not&lt;/strong&gt; the &lt;a href="https://www.lazyvim.org/"&gt;LazyVim&lt;/a&gt;&#10;distribution, and doesn&amp;rsquo;t depend on it. Distributions like LazyVim or kickstart.nvim ship pre-built,&#10;opinionated defaults (LSP presets via &lt;code&gt;nvim-lspconfig&lt;/code&gt;&amp;rsquo;s setup functions, a formatter framework, a fixed&#10;plugin set); this config instead wires each piece directly, which means more to write, but nothing hidden&#10;behind a distribution&amp;rsquo;s abstractions.&lt;/p&gt;</description></item><item><title>Datenschutzerklärung</title><link>https://kb-migration.spoljarevic.sh/legal/privacy/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/legal/privacy/</guid><description>&lt;p&gt;&lt;em&gt;&lt;a href="https://kb-migration.spoljarevic.sh/legal/privacy-en/"&gt;English version&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&#10;&lt;h2 id="1-verantwortlicher"&gt;1. Verantwortlicher&#10;&lt;/h2&gt;&#10;&lt;p&gt;Verantwortlich für die Datenverarbeitung auf dieser Website im Sinne der Datenschutz-Grundverordnung (DSGVO) ist:&lt;/p&gt;&#10;&lt;p&gt;Luca Matteo Špoljarević&lt;br&gt;&#10;c/o IP-Management #12320&lt;br&gt;&#10;Ludwig-Erhard-Straße 18&lt;br&gt;&#10;20459 Hamburg&lt;br&gt;&#10;E-Mail: &lt;a href="mailto:webadmin@info.spoljarevic.sh"&gt;webadmin@info.spoljarevic.sh&lt;/a&gt;&lt;/p&gt;&#10;&lt;h2 id="2-das-wichtigste-in-kürze"&gt;2. Das Wichtigste in Kürze&#10;&lt;/h2&gt;&#10;&lt;p&gt;Diese Website ist eine rein statische Website. Es gibt &lt;strong&gt;keine&lt;/strong&gt; Benutzerkonten, &lt;strong&gt;keine&lt;/strong&gt; Kontaktformulare, &lt;strong&gt;keinen&lt;/strong&gt; Newsletter, &lt;strong&gt;keine&lt;/strong&gt; Analyse- oder Tracking-Tools, &lt;strong&gt;keine&lt;/strong&gt; Werbung und diese Website setzt &lt;strong&gt;keine&lt;/strong&gt; Cookies. Schriftarten und Skripte werden nicht von fremden Servern nachgeladen.&lt;/p&gt;</description></item><item><title>Usage</title><link>https://kb-migration.spoljarevic.sh/Big-Projects/Arch-Linux-Post-Install-Automation/Usage/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/Big-Projects/Arch-Linux-Post-Install-Automation/Usage/</guid><description>&lt;h2 id="prerequisites"&gt;Prerequisites&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;A control machine with &lt;a href="https://docs.ansible.com/"&gt;Ansible&lt;/a&gt; installed.&lt;/li&gt;&#10;&lt;li&gt;A target host running Arch Linux (or an Arch-based distro such as CachyOS), reachable over SSH with a user&#10;that can &lt;code&gt;become&lt;/code&gt; root (sudo).&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="td-callout td-callout--warning" role="note"&gt;&#10; &lt;div class="td-callout__title"&gt;&lt;i class="td-callout__icon fa-solid fa-triangle-exclamation" aria-hidden="true"&gt;&lt;/i&gt;&lt;span class="td-callout__label"&gt;Warning&lt;/span&gt;&lt;/div&gt;&#10; &lt;div class="td-callout__body"&gt;&#10;&lt;p&gt;This playbook is built for Arch Linux specifically — it uses &lt;code&gt;pacman&lt;/code&gt;, and adds CachyOS/BlackArch&#10;repositories. Running it against a different distribution will fail.&lt;/p&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&lt;h2 id="1-install-required-ansible-collections"&gt;1. Install required Ansible collections&#10;&lt;/h2&gt;&#10;&lt;p&gt;The playbook depends on a few community Ansible collections:&lt;/p&gt;</description></item><item><title>Usage</title><link>https://kb-migration.spoljarevic.sh/Big-Projects/FreePBX-17-Docker-Setup/Usage/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/Big-Projects/FreePBX-17-Docker-Setup/Usage/</guid><description>&lt;h2 id="prerequisites"&gt;Prerequisites&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Docker and Docker Compose (&lt;code&gt;docker-compose&lt;/code&gt; or the &lt;code&gt;docker compose&lt;/code&gt; plugin) on the host.&lt;/li&gt;&#10;&lt;li&gt;A host willing to run a &lt;strong&gt;privileged&lt;/strong&gt; container — this setup needs &lt;code&gt;--privileged&lt;/code&gt; and an unconfined&#10;seccomp profile for systemd to manage services inside the container.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="1-clone-the-repository-and-build-the-image"&gt;1. Clone the repository and build the image&#10;&lt;/h2&gt;&#10;&lt;div class="td-code td-code--untitled" id="td-code-72d861c2-fence-0" data-td-code data-td-code-auto-id&#10; data-td-language="sh" data-td-line-count="3"&gt;&#10; &lt;div class="td-code__viewport" id="td-code-72d861c2-fence-0-viewport" data-td-code-viewport&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://codeberg.org/Spoljarevic/FreePBX-17-Container.git&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; FreePBX-17-Container&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo docker-compose build&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;The build stage (see &lt;a href="https://kb-migration.spoljarevic.sh/Big-Projects/FreePBX-17-Docker-Setup/Code-Explanation/"&gt;Code Explanation&lt;/a&gt;) only installs the OS-level prerequisites and&#10;copies in the install script — FreePBX itself is &lt;strong&gt;not&lt;/strong&gt; installed at build time.&lt;/p&gt;</description></item><item><title>Usage</title><link>https://kb-migration.spoljarevic.sh/Big-Projects/Zammad-Podman-Quadlets/Usage/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/Big-Projects/Zammad-Podman-Quadlets/Usage/</guid><description>&lt;h2 id="prerequisites"&gt;Prerequisites&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;A recent &lt;a href="https://podman.io/"&gt;Podman&lt;/a&gt; version with Quadlet support (Podman 4.4+; check with &lt;code&gt;podman --version&lt;/code&gt;).&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;systemd&lt;/code&gt; (used both as the rootless user&amp;rsquo;s &lt;code&gt;systemd --user&lt;/code&gt; instance and, optionally, system-wide).&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="1-configure-your-environment"&gt;1. Configure your environment&#10;&lt;/h2&gt;&#10;&lt;p&gt;Copy the example environment file and fill in your own values:&lt;/p&gt;&#10;&lt;div class="td-code td-code--untitled" id="td-code-7d2906f7-fence-0" data-td-code data-td-code-auto-id&#10; data-td-language="sh" data-td-line-count="2"&gt;&#10; &lt;div class="td-code__viewport" id="td-code-7d2906f7-fence-0-viewport" data-td-code-viewport&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cp .env.example .env&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$EDITOR&lt;/span&gt; .env&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;At minimum, review and change the database/Elasticsearch credentials (&lt;code&gt;POSTGRES_PASS&lt;/code&gt;, &lt;code&gt;ELASTICSEARCH_PASS&lt;/code&gt;),&#10;&lt;code&gt;ZAMMAD_FQDN&lt;/code&gt;, &lt;code&gt;TZ&lt;/code&gt;, and the backup schedule (&lt;code&gt;BACKUP_TIME&lt;/code&gt;, &lt;code&gt;HOLD_DAYS&lt;/code&gt;). Everything under &amp;ldquo;PROXY / EXTERNAL&#10;ACCESS&amp;rdquo; and &amp;ldquo;Cloudflare Tunnel&amp;rdquo; in &lt;code&gt;.env.example&lt;/code&gt; is optional and commented out by default.&lt;/p&gt;</description></item><item><title>Usage</title><link>https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/Usage/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/Usage/</guid><description>&lt;h2 id="deployment"&gt;Deployment&#10;&lt;/h2&gt;&#10;&lt;p&gt;There&amp;rsquo;s no separate install step for this config specifically — it&amp;rsquo;s deployed as part of the&#10;&lt;a href="https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/"&gt;Dotfiles&lt;/a&gt; monorepo. &lt;code&gt;~/.config&lt;/code&gt; is a symlink to the root of that repository, so &lt;code&gt;nvim/&lt;/code&gt; inside it&#10;automatically becomes &lt;code&gt;~/.config/nvim&lt;/code&gt;, which is where Neovim looks for its config by default.&lt;/p&gt;&#10;&lt;div class="td-callout td-callout--note" role="note"&gt;&#10; &lt;div class="td-callout__title"&gt;&lt;i class="td-callout__icon fa-solid fa-circle-info" aria-hidden="true"&gt;&lt;/i&gt;&lt;span class="td-callout__label"&gt;Note&lt;/span&gt;&lt;/div&gt;&#10; &lt;div class="td-callout__body"&gt;&#10;&lt;p&gt;This means editing &lt;code&gt;~/.config/nvim/lua/plugins/foo.lua&lt;/code&gt; and editing this repo&amp;rsquo;s &lt;code&gt;nvim/lua/plugins/foo.lua&lt;/code&gt;&#10;are the same file.&lt;/p&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&lt;h2 id="first-launch"&gt;First launch&#10;&lt;/h2&gt;&#10;&lt;div class="td-code td-code--untitled" id="td-code-7e57618a-fence-0" data-td-code data-td-code-auto-id&#10; data-td-language="sh" data-td-line-count="1"&gt;&#10; &lt;div class="td-code__viewport" id="td-code-7e57618a-fence-0-viewport" data-td-code-viewport&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nvim&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;On the very first run, &lt;code&gt;lua/config/lazy.lua&lt;/code&gt; detects that &lt;code&gt;lazy.nvim&lt;/code&gt; itself isn&amp;rsquo;t installed yet, clones it&#10;into Neovim&amp;rsquo;s data directory, and then installs every plugin declared under &lt;code&gt;lua/plugins/*.lua&lt;/code&gt;. Subsequent&#10;launches just load already-installed plugins.&lt;/p&gt;</description></item><item><title>Code Explanation</title><link>https://kb-migration.spoljarevic.sh/Big-Projects/Arch-Linux-Post-Install-Automation/Code-Explanation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/Big-Projects/Arch-Linux-Post-Install-Automation/Code-Explanation/</guid><description>&lt;h2 id="repository-layout"&gt;Repository layout&#10;&lt;/h2&gt;&#10;&lt;div class="td-code td-code--untitled" id="td-code-f3e344f0-fence-0" data-td-code data-td-code-auto-id&#10; data-td-language="" data-td-line-count="5"&gt;&#10; &lt;div class="td-code__viewport" id="td-code-f3e344f0-fence-0-viewport" data-td-code-viewport&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;archPostInstall.yml the full playbook — every play, in order&#10;spo-pc-ls.yml ansible-vault encrypted secrets (not usable by others as-is)&#10;inventory.ini example Ansible inventory&#10;requirenments.yml Ansible Galaxy collection dependencies&#10;snippets/ the same plays, split into standalone, individually runnable playbooks&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="td-callout td-callout--note" role="note"&gt;&#10; &lt;div class="td-callout__title"&gt;&lt;i class="td-callout__icon fa-solid fa-circle-info" aria-hidden="true"&gt;&lt;/i&gt;&lt;span class="td-callout__label"&gt;Note&lt;/span&gt;&lt;/div&gt;&#10; &lt;div class="td-callout__body"&gt;&#10;&lt;p&gt;The dependencies file is named &lt;code&gt;requirenments.yml&lt;/code&gt; (not &lt;code&gt;requirements.yml&lt;/code&gt;) — use that exact filename&#10;when installing collections.&lt;/p&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&lt;h2 id="archpostinstallyml"&gt;&lt;code&gt;archPostInstall.yml&lt;/code&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;This is the &amp;ldquo;run everything&amp;rdquo; entrypoint. It&amp;rsquo;s a sequence of independent Ansible plays, executed top to&#10;bottom:&lt;/p&gt;</description></item><item><title>Code Explanation</title><link>https://kb-migration.spoljarevic.sh/Big-Projects/FreePBX-17-Docker-Setup/Code-Explanation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/Big-Projects/FreePBX-17-Docker-Setup/Code-Explanation/</guid><description>&lt;h2 id="dockerfile"&gt;&lt;code&gt;Dockerfile&lt;/code&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="td-code td-code--untitled" id="td-code-d22fed7b-fence-0" data-td-code data-td-code-auto-id&#10; data-td-language="dockerfile" data-td-line-count="12"&gt;&#10; &lt;div class="td-code__viewport" id="td-code-d22fed7b-fence-0-viewport" data-td-code-viewport&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dockerfile" data-lang="dockerfile"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;debian:bookworm&lt;/span&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;...&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get install -y &lt;span class="se"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; wget curl gnupg2 sudo git vim ca-certificates lsb-release software-properties-common &lt;span class="se"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; systemd systemd-sysv dbus net-tools openssh-client &lt;span class="se"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get clean&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/usr/src&lt;/span&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; sng_freepbx_debian_install.sh .&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; chmod +x ./sng_freepbx_debian_install.sh&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; ln -s /var/lib/asterisk/bin/fwconsole /usr/sbin/fwconsole &lt;span class="o"&gt;||&lt;/span&gt; true&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;80&lt;/span&gt; &lt;span class="m"&gt;443&lt;/span&gt; 5060/udp 5160/udp 18000-18100/udp&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CMD&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/bin/bash&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;The image is deliberately thin:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Base&lt;/strong&gt;: &lt;code&gt;debian:bookworm&lt;/code&gt; — Sangoma&amp;rsquo;s install script hard-codes support for Debian 12 only (it checks&#10;&lt;code&gt;VERSION_CODENAME&lt;/code&gt;/&lt;code&gt;/etc/debian_version&lt;/code&gt; and exits if it isn&amp;rsquo;t &lt;code&gt;bookworm&lt;/code&gt;).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Installed at build time&lt;/strong&gt;: only &lt;code&gt;systemd&lt;/code&gt;/&lt;code&gt;systemd-sysv&lt;/code&gt;/&lt;code&gt;dbus&lt;/code&gt; (so the container can boot like a real&#10;init system) plus generic tooling the install script or an admin would want (&lt;code&gt;wget&lt;/code&gt;, &lt;code&gt;curl&lt;/code&gt;, &lt;code&gt;git&lt;/code&gt;, &lt;code&gt;vim&lt;/code&gt;,&#10;etc). FreePBX, Asterisk, MariaDB, Apache, and PHP are &lt;strong&gt;not&lt;/strong&gt; installed here — that all happens later, at&#10;container &lt;em&gt;runtime&lt;/em&gt;, by running the copied-in script manually.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;The &lt;code&gt;fwconsole&lt;/code&gt; symlink&lt;/strong&gt;: &lt;code&gt;fwconsole&lt;/code&gt; is FreePBX&amp;rsquo;s CLI (module management, restarts, etc). The install&#10;script normally expects it at a path that isn&amp;rsquo;t always on &lt;code&gt;PATH&lt;/code&gt; yet immediately after install in a fresh&#10;container; the symlink into &lt;code&gt;/usr/sbin&lt;/code&gt; pre-empts that so &lt;code&gt;fwconsole&lt;/code&gt; works without extra steps once&#10;FreePBX is installed. The &lt;code&gt;|| true&lt;/code&gt; makes the build tolerant of the target not existing yet at build time.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;&lt;code&gt;CMD [&amp;quot;/bin/bash&amp;quot;]&lt;/code&gt;&lt;/strong&gt;: the image&amp;rsquo;s default command is just a shell — the actual PID 1 process is&#10;overridden by &lt;code&gt;docker-compose.yml&lt;/code&gt;&amp;rsquo;s &lt;code&gt;command: [&amp;quot;/sbin/init&amp;quot;]&lt;/code&gt;, not this line.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Installing FreePBX at &lt;em&gt;build&lt;/em&gt; time isn&amp;rsquo;t possible here: the installer needs a running init system managing&#10;services (&lt;code&gt;systemctl&lt;/code&gt;), which only exists once the container is actually started, not while &lt;code&gt;docker build&lt;/code&gt;&#10;is assembling image layers.&lt;/p&gt;</description></item><item><title>Code Explanation</title><link>https://kb-migration.spoljarevic.sh/Big-Projects/Zammad-Podman-Quadlets/Code-Explanation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/Big-Projects/Zammad-Podman-Quadlets/Code-Explanation/</guid><description>&lt;h2 id="anatomy-of-a-quadlet-unit"&gt;Anatomy of a Quadlet unit&#10;&lt;/h2&gt;&#10;&lt;p&gt;Every &lt;code&gt;.container&lt;/code&gt; file in this repo follows the same shape:&lt;/p&gt;&#10;&lt;div class="td-code td-code--untitled" id="td-code-9f43d6d1-fence-0" data-td-code data-td-code-auto-id&#10; data-td-language="ini" data-td-line-count="18"&gt;&#10; &lt;div class="td-code__viewport" id="td-code-9f43d6d1-fence-0-viewport" data-td-code-viewport&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Unit]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;After&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;zammad.pod ... # start order&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Requires&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;zammad.pod ... # hard dependency&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;PartOf&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;zammad.pod # stop/restart together with the pod&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Container]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;...&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ContainerName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;...&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Pod&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;zammad.pod # joins the shared pod network namespace&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Exec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;... # command run inside the Zammad image for this role&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;EnvironmentFile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;.env&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Service]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;always&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;RestartSec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;...&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Install]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;default.target # lets systemctl enable start it at boot/login&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;&lt;code&gt;PartOf=zammad.pod&lt;/code&gt; means stopping or restarting the pod stops/restarts the container with it.&#10;&lt;code&gt;Pod=zammad.pod&lt;/code&gt; puts every container in the same network namespace, so they can reach each other over&#10;&lt;code&gt;localhost&lt;/code&gt; instead of needing container-to-container DNS.&lt;/p&gt;</description></item><item><title>Code Explanation</title><link>https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/Code-Explanation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/Code-Explanation/</guid><description>&lt;h2 id="load-order"&gt;Load order&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;init.lua&lt;/code&gt; is four requires, executed in order:&lt;/p&gt;&#10;&lt;div class="td-code td-code--untitled" id="td-code-6d9202fb-fence-0" data-td-code data-td-code-auto-id&#10; data-td-language="lua" data-td-line-count="4"&gt;&#10; &lt;div class="td-code__viewport" id="td-code-6d9202fb-fence-0-viewport" data-td-code-viewport&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-lua" data-lang="lua"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;config.options&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;config.lazy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;config.keymaps&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;config.autocmds&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;&lt;code&gt;config/options.lua&lt;/code&gt;&lt;/strong&gt; — plain &lt;code&gt;vim.o.*&lt;/code&gt; settings (line numbers, relative numbers, mouse support,&#10;split direction, 2-space indentation, etc). No plugins involved.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;&lt;code&gt;config/lazy.lua&lt;/code&gt;&lt;/strong&gt; — bootstraps &lt;code&gt;lazy.nvim&lt;/code&gt; itself: if it isn&amp;rsquo;t already cloned into Neovim&amp;rsquo;s data&#10;directory, &lt;code&gt;git clone&lt;/code&gt;s it, prepends it to the runtimepath, then calls&#10;&lt;code&gt;require(&amp;quot;lazy&amp;quot;).setup(&amp;quot;plugins&amp;quot;, { change_detection = { notify = false } })&lt;/code&gt;. That call auto-discovers&#10;and loads every spec file under &lt;code&gt;lua/plugins/*.lua&lt;/code&gt; — adding a new plugin is just adding a new file&#10;there, no manual registration step.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;&lt;code&gt;config/keymaps.lua&lt;/code&gt;&lt;/strong&gt; — global keymaps, centralized here rather than scattered per-plugin file (see&#10;&lt;a href="https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/Usage/"&gt;Usage&lt;/a&gt; for the full table).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;&lt;code&gt;config/autocmds.lua&lt;/code&gt;&lt;/strong&gt; — currently just the format-on-save autocmd.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="plugin-spec-files"&gt;Plugin spec files&#10;&lt;/h2&gt;&#10;&lt;p&gt;Each file under &lt;code&gt;lua/plugins/&lt;/code&gt; returns a &lt;code&gt;lazy.nvim&lt;/code&gt; spec table (or a list of tables), and filenames map&#10;roughly 1:1 to the plugin they configure:&lt;/p&gt;</description></item><item><title>Privacy Policy</title><link>https://kb-migration.spoljarevic.sh/legal/privacy-en/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/legal/privacy-en/</guid><description>&lt;p&gt;&lt;em&gt;This is a translation for convenience. The &lt;a href="https://kb-migration.spoljarevic.sh/legal/privacy/"&gt;German version&lt;/a&gt; is legally binding.&lt;/em&gt;&lt;/p&gt;&#10;&lt;h2 id="1-controller"&gt;1. Controller&#10;&lt;/h2&gt;&#10;&lt;p&gt;The controller responsible for data processing on this website under the General Data Protection Regulation (GDPR) is:&lt;/p&gt;&#10;&lt;p&gt;Luca Matteo Špoljarević&lt;br&gt;&#10;c/o IP-Management #12320&lt;br&gt;&#10;Ludwig-Erhard-Straße 18&lt;br&gt;&#10;20459 Hamburg, Germany&lt;br&gt;&#10;Email: &lt;a href="mailto:webadmin@info.spoljarevic.sh"&gt;webadmin@info.spoljarevic.sh&lt;/a&gt;&lt;/p&gt;&#10;&lt;h2 id="2-summary"&gt;2. Summary&#10;&lt;/h2&gt;&#10;&lt;p&gt;This is a purely static website. There are &lt;strong&gt;no&lt;/strong&gt; user accounts, &lt;strong&gt;no&lt;/strong&gt; contact forms, &lt;strong&gt;no&lt;/strong&gt; newsletter, &lt;strong&gt;no&lt;/strong&gt; analytics or tracking tools, &lt;strong&gt;no&lt;/strong&gt; advertising, and this website sets &lt;strong&gt;no&lt;/strong&gt; cookies. Fonts and scripts are not loaded from third-party servers.&lt;/p&gt;</description></item><item><title>FAQ</title><link>https://kb-migration.spoljarevic.sh/Big-Projects/Arch-Linux-Post-Install-Automation/FAQ/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/Big-Projects/Arch-Linux-Post-Install-Automation/FAQ/</guid><description>&lt;h3 id="can-i-run-this-on-a-different-distro"&gt;Can I run this on a different distro?&#10;&lt;/h3&gt;&#10;&lt;p&gt;No. It relies on &lt;code&gt;pacman&lt;/code&gt;, and specifically bootstraps the CachyOS and BlackArch pacman repositories. It&#10;will not work on Debian/Fedora/etc.&lt;/p&gt;&#10;&lt;h3 id="do-i-have-to-run-the-entire-playbook"&gt;Do I have to run the entire playbook?&#10;&lt;/h3&gt;&#10;&lt;p&gt;No — run only what you need via the standalone playbooks in &lt;code&gt;snippets/&lt;/code&gt;. See&#10;&lt;a href="https://kb-migration.spoljarevic.sh/Big-Projects/Arch-Linux-Post-Install-Automation/Code-Explanation/#snippets"&gt;Code Explanation&lt;/a&gt; for the full list, and &lt;a href="https://kb-migration.spoljarevic.sh/Big-Projects/Arch-Linux-Post-Install-Automation/Usage/"&gt;Usage&lt;/a&gt; for an example&#10;command.&lt;/p&gt;</description></item><item><title>FAQ</title><link>https://kb-migration.spoljarevic.sh/Big-Projects/FreePBX-17-Docker-Setup/FAQ/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/Big-Projects/FreePBX-17-Docker-Setup/FAQ/</guid><description>&lt;h3 id="why-does-the-container-need-privileged-true"&gt;Why does the container need &lt;code&gt;privileged: true&lt;/code&gt;?&#10;&lt;/h3&gt;&#10;&lt;p&gt;Because it runs &lt;code&gt;systemd&lt;/code&gt; as PID 1, and systemd needs privileges Docker doesn&amp;rsquo;t grant by default (managing&#10;cgroups, mounting filesystems, controlling devices) to supervise the services FreePBX depends on — Apache,&#10;MariaDB, Asterisk. Without it, &lt;code&gt;/sbin/init&lt;/code&gt; won&amp;rsquo;t boot cleanly inside the container. See&#10;&lt;a href="https://kb-migration.spoljarevic.sh/Big-Projects/FreePBX-17-Docker-Setup/Introduction/"&gt;Introduction&lt;/a&gt; for the trade-off this implies.&lt;/p&gt;&#10;&lt;h3 id="why-isnt-freepbx-installed-automatically-when-i-build-the-image"&gt;Why isn&amp;rsquo;t FreePBX installed automatically when I build the image?&#10;&lt;/h3&gt;&#10;&lt;p&gt;Sangoma&amp;rsquo;s install script assumes it&amp;rsquo;s running on an already-booted system with a working init system&#10;managing services — that&amp;rsquo;s only true once the container is actually &lt;em&gt;running&lt;/em&gt;, not while &lt;code&gt;docker build&lt;/code&gt; is&#10;assembling layers. So the build stage only prepares the environment (Debian + systemd + the script itself);&#10;you run the installer yourself after &lt;code&gt;docker-compose up -d&lt;/code&gt;. See &lt;a href="https://kb-migration.spoljarevic.sh/Big-Projects/FreePBX-17-Docker-Setup/Usage/"&gt;Usage&lt;/a&gt; for the exact steps.&lt;/p&gt;</description></item><item><title>FAQ</title><link>https://kb-migration.spoljarevic.sh/Big-Projects/Zammad-Podman-Quadlets/FAQ/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/Big-Projects/Zammad-Podman-Quadlets/FAQ/</guid><description>&lt;h3 id="why-quadlets-instead-of-docker-compose--podman-compose"&gt;Why Quadlets instead of &lt;code&gt;docker-compose&lt;/code&gt; / &lt;code&gt;podman-compose&lt;/code&gt;?&#10;&lt;/h3&gt;&#10;&lt;p&gt;Quadlets translate directly into native systemd units, so Podman containers get systemd&amp;rsquo;s process&#10;supervision, dependency ordering, and boot/login integration for free — no separate compose daemon needs to&#10;keep running in the background, and it works cleanly rootless.&lt;/p&gt;&#10;&lt;h3 id="can-i-really-run-this-rootless"&gt;Can I really run this rootless?&#10;&lt;/h3&gt;&#10;&lt;p&gt;Yes — that&amp;rsquo;s the point of this setup. Place the unit files in &lt;code&gt;~/.config/containers/systemd/&lt;/code&gt;, run&#10;&lt;code&gt;systemctl --user daemon-reload&lt;/code&gt;, and use &lt;code&gt;loginctl enable-linger &amp;lt;user&amp;gt;&lt;/code&gt; so the services keep running even&#10;when you&amp;rsquo;re logged out. See &lt;a href="https://kb-migration.spoljarevic.sh/Big-Projects/Zammad-Podman-Quadlets/Usage/"&gt;Usage&lt;/a&gt; for the full steps.&lt;/p&gt;</description></item><item><title>FAQ</title><link>https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/FAQ/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/FAQ/</guid><description>&lt;h3 id="why-not-just-use-lazyvim-or-kickstartnvim"&gt;Why not just use LazyVim or kickstart.nvim?&#10;&lt;/h3&gt;&#10;&lt;p&gt;This config predates/deliberately avoids adopting a distribution. Writing every option, keymap, and plugin&#10;spec by hand keeps each piece traceable to a single file instead of hidden behind a distribution&amp;rsquo;s&#10;abstractions and defaults — at the cost of not getting features &amp;ldquo;for free.&amp;rdquo; See&#10;&lt;a href="https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/Introduction/"&gt;Introduction&lt;/a&gt; for the full reasoning.&lt;/p&gt;&#10;&lt;h3 id="why-hand-roll-lsp-instead-of-using-nvim-lspconfigs-setup-presets"&gt;Why hand-roll LSP instead of using &lt;code&gt;nvim-lspconfig&lt;/code&gt;&amp;rsquo;s &lt;code&gt;setup{}&lt;/code&gt; presets?&#10;&lt;/h3&gt;&#10;&lt;p&gt;Same reasoning as above, applied specifically to LSP: &lt;code&gt;lua/plugins/lsp.lua&lt;/code&gt; calls &lt;code&gt;vim.lsp.start()&lt;/code&gt;&#10;directly through a small &lt;code&gt;setup_lsp()&lt;/code&gt; helper instead of &lt;code&gt;require(&amp;quot;lspconfig&amp;quot;).&amp;lt;server&amp;gt;.setup{}&lt;/code&gt;. It also&#10;means the executable-existence guard (&lt;code&gt;vim.fn.executable(...)&lt;/code&gt;) is explicit and visible, rather than&#10;depending on &lt;code&gt;nvim-lspconfig&lt;/code&gt;&amp;rsquo;s own defaults. See &lt;a href="https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/Code-Explanation/"&gt;Code Explanation&lt;/a&gt; for the code.&lt;/p&gt;</description></item></channel></rss>