[{"content":"","date":"2 July 2026","externalUrl":null,"permalink":"/","section":"Christian Lempa","summary":"","title":"Christian Lempa","type":"page"},{"content":"","date":"2 July 2026","externalUrl":null,"permalink":"/videos/","section":"Videos","summary":"","title":"Videos","type":"videos"},{"content":" Cockpit Tutorial Commands and Notes # Short companion notes for the video. This is not a full article — just the main commands, config snippets, notes, and links.\nWhat this setup does # Install Cockpit as a lightweight Linux server dashboard. Open Cockpit on the default port 9090 for the first test. Restrict Cockpit to 127.0.0.1:9090. Put Caddy in front of Cockpit for a trusted HTTPS certificate. Add a few optional Cockpit applications. Use Cockpit’s remote login flow to connect to another server over SSH. Install Cockpit # Commands vary by distribution. Check the official installation page first:\nhttps://cockpit-project.org/running.html For Ubuntu LTS releases, Cockpit usually recommends installing from backports:\n. /etc/os-release sudo apt install -t ${VERSION_CODENAME}-backports cockpit On my Ubuntu 26.04 test VM, Cockpit was available from the normal universe repository, so this was enough:\nsudo apt update sudo apt install cockpit Enable the Cockpit socket:\nsudo systemctl enable --now cockpit.socket Open Cockpit in the browser:\nhttps://\u0026lt;server-ip\u0026gt;:9090 Login with a normal Linux user account.\nMake Cockpit listen only on localhost # Create a systemd socket override:\nsudo mkdir -p /etc/systemd/system/cockpit.socket.d sudo nano /etc/systemd/system/cockpit.socket.d/listen.conf /etc/systemd/system/cockpit.socket.d/listen.conf\n[Socket] ListenStream= ListenStream=127.0.0.1:9090 Notes:\nThe empty ListenStream= line clears the default listener. Without it, systemd may keep the original Cockpit listener as well. This only makes sense when the reverse proxy runs on the same server as Cockpit. Apply and verify:\nsudo systemctl daemon-reload sudo systemctl restart cockpit.socket sudo systemctl status cockpit.socket sudo ss -ltnp | grep 9090 Cockpit reverse proxy settings # Create or edit the Cockpit config:\nsudo nano /etc/cockpit/cockpit.conf /etc/cockpit/cockpit.conf\n[WebService] Origins = https://cockpit.example.com wss://cockpit.example.com ProtocolHeader = X-Forwarded-Proto Replace cockpit.example.com with the real DNS name you use for the dashboard.\nNotes:\nCockpit uses WebSockets, so the external browser origin must be allowed. ProtocolHeader = X-Forwarded-Proto tells Cockpit that the browser-facing connection is HTTPS. Restart Cockpit:\nsudo systemctl restart cockpit.socket Caddy reverse proxy example # Example Caddyfile with DNS-01 through Cloudflare:\n/etc/caddy/Caddyfile\ncockpit.example.com { tls { dns cloudflare {env.CF_API_TOKEN} resolvers 1.1.1.1 } reverse_proxy https://127.0.0.1:9090 { header_up Host {host} transport http { tls_insecure_skip_verify } } } Apply the Caddy config:\nsudo caddy fmt --overwrite /etc/caddy/Caddyfile sudo systemctl reload caddy sudo journalctl -u caddy -f Notes:\ntls_insecure_skip_verify is acceptable here only because the upstream connection is local: Caddy → 127.0.0.1:9090. For a remote upstream, use a proper certificate or internal CA instead. If Caddy runs as a systemd service, make sure CF_API_TOKEN is available to the service environment. Be careful with commands like caddy run --environ while recording or sharing logs, because they can print environment variables. Ubuntu / PackageKit offline workaround # If Cockpit’s Software Updates page shows something like Cannot refresh cache whilst offline, this can happen on Ubuntu/Debian when NetworkManager is not managing the main interface.\nCockpit FAQ:\nhttps://cockpit-project.org/faq#error-message-about-being-offline Workaround from the Cockpit FAQ:\nsudo mkdir -p /etc/NetworkManager/conf.d sudo nano /etc/NetworkManager/conf.d/10-globally-managed-devices.conf /etc/NetworkManager/conf.d/10-globally-managed-devices.conf\n[keyfile] unmanaged-devices=none Add a dummy NetworkManager interface:\nsudo nmcli con add type dummy con-name fake ifname fake0 ip4 192.0.2.2/24 gw4 192.0.2.1 sudo reboot Verify after reboot:\nnmcli general status nmcli device status Optional Cockpit applications # Official Cockpit applications:\nhttps://cockpit-project.org/applications.html For optional Cockpit applications, follow the installation instructions from the linked project or GitHub repository, because the setup can vary depending on the operating system, distribution version, and packaging method.\nRemote server management # Cockpit can connect to another Linux server over SSH from the login page.\nBasic flow:\nLogout → Connect to → \u0026lt;remote-server-ip-or-hostname\u0026gt; → Login Notes:\nThe remote server needs SSH access. The remote server needs Cockpit or at least the Cockpit bridge available. The remote server does not need to expose Cockpit on port 9090. The old multi-host/host-switching feature is deprecated, so I would not use Cockpit as a central management platform for random or untrusted servers. Links # Video: https://youtu.be/5BPaupqbFfg Cockpit: https://cockpit-project.org/ Cockpit installation: https://cockpit-project.org/running.html Cockpit applications: https://cockpit-project.org/applications.html Cockpit multiple machines: https://cockpit-project.org/guide/latest/feature-machines.html Cockpit 322 release notes: https://cockpit-project.org/blog/cockpit-322.html Caddy: https://caddyserver.com/ Caddy tutorial video: https://youtu.be/AjWonyr8nxI ","date":"19 June 2026","externalUrl":null,"permalink":"/videos/cockpit-tutorial/","section":"Videos","summary":"","title":"Cockpit: The Easiest Way to Manage Linux Servers","type":"videos"},{"content":" Dockhand: A Smarter, Safer Docker Manager # If you manage Docker containers across multiple hosts, the hard part is not only starting containers or editing Compose files. The hard part is keeping updates, security, logs, remote access, and day-to-day operations under control without exposing a risky Docker admin surface.\nInstall Dockhand # You can follow the official Dockhand documentation, or use the Boilerplates setup if you are using my template workflow.\nLinks:\nDockhand: https://dockhand.pro/ Dockhand manual: https://dockhand.pro/manual Boilerplates: https://github.com/christianlempa/boilerplates In my setup, I generated the Dockhand Compose stack with Boilerplates:\nboilerplates repo update boilerplates compose list boilerplates compose show dockhand boilerplates compose generate dockhand Then deploy it on the Docker host:\nssh srv-test-1 cd ~/dockhand docker compose up -d After the containers are running, open the Dockhand web interface and finish the initial setup.\nAdd Your First Docker Environment # Inside Dockhand, go to:\nEnvironments -\u0026gt; Add -\u0026gt; Local This connects Dockhand to the local Docker environment. Once connected, you can inspect the running containers and stacks.\nConnect Remote Environments with Hawser # Dockhand can also manage remote Docker environments through Hawser.\nHawser is the remote agent used to connect Docker hosts back to Dockhand. This is useful when the Docker host is behind NAT, behind a firewall, or does not have a stable public IP.\nLinks:\nHawser: https://github.com/Finsys/hawser Dockhand Hawser manual: https://dockhand.pro/manual/#hawser-quick-install Install Hawser on the remote Docker host:\ncurl -fsSL https://raw.githubusercontent.com/Finsys/hawser/main/scripts/install.sh | bash Then configure the Hawser token:\nsudo vim /etc/hawser/config Restart the service:\nsudo systemctl stop hawser sudo systemctl start hawser Then add the remote environment in Dockhand:\nEnvironments -\u0026gt; Add -\u0026gt; Hawser Agent This allows Dockhand to manage another Docker host without exposing the Docker socket or admin UI directly to the internet.\n","date":"8 May 2026","externalUrl":null,"permalink":"/videos/dockhand-tutorial/","section":"Videos","summary":"","title":"Dockhand: A Smarter, Safer Docker Manager","type":"videos"},{"content":" Boilerplates CLI v0.2.0 is here, and this update changes the foundation of how templates are structured, rendered, and generated.\nThe short version: Boilerplates is no longer just one repository with everything in one place. The CLI app and the template library are now split, templates use the new template.json runtime, template files live in a dedicated files/ directory, and the generator now supports remote generation over SSH.\nIf you already used Boilerplates for Docker Compose templates, this is the update to pay attention to.\nRepositories # Boilerplates is now split into two separate projects:\nBoilerplates CLI Boilerplates template library The CLI is the app you install and run. The library is where the actual templates live.\nThis makes the project easier to maintain because the runtime and the template content can evolve separately. It also makes it clearer where to look when something is related to the CLI itself, and where to look when something is related to a specific template.\nTry a template # For a quick first look, generate a template in dry-run mode and show the resulting files before writing anything to disk:\nboilerplates compose generate gitea --dry-run --show-files That is still the main idea behind Boilerplates: instead of copying a static Docker Compose file and editing every domain, port, database, and secret manually, you generate a stack that already matches your choices.\nNew template runtime # The biggest internal change in v0.2.0 is the new template runtime.\nTemplates are now built around a template.json manifest. This replaces the older template structure and makes templates more explicit, easier to validate, and easier to maintain over time.\nRenderable template content now lives inside a dedicated files/ directory.\nConceptually, a template now looks like this:\ntemplate-name/ |-- template.json `-- files/ |-- compose.yaml `-- .env The important part is the separation:\ntemplate.json describes the template files/ contains the files that get rendered and generated That may sound like a small structural change, but it makes a big difference for long-term template maintenance. Template authors get a clearer format, and users get templates that are easier to validate before generation.\nCustom template delimiters # Boilerplates no longer uses the default Jinja-style delimiters.\nThe new runtime uses:\n\u0026lt;\u0026lt; \u0026gt;\u0026gt; for variables \u0026lt;% %\u0026gt; for blocks \u0026lt;# #\u0026gt; for comments Example:\nservices: app: image: \u0026lt;\u0026lt; app_image \u0026gt;\u0026gt; environment: TZ: \u0026lt;\u0026lt; timezone \u0026gt;\u0026gt; \u0026lt;% if traefik_enabled %\u0026gt; labels: - \u0026#34;traefik.enable=true\u0026#34; - \u0026#34;traefik.http.routers.\u0026lt;\u0026lt; app_name \u0026gt;\u0026gt;.rule=Host(`\u0026lt;\u0026lt; app_domain \u0026gt;\u0026gt;`)\u0026#34; \u0026lt;% endif %\u0026gt; This is especially useful in infrastructure files.\nDocker Compose files, Kubernetes manifests, Terraform files, Ansible files, and other config formats often already use curly braces somewhere. Moving Boilerplates to custom delimiters makes templates easier to read and reduces conflicts with other tools.\nBetter variables # Variables are also more structured in v0.2.0.\nThe new model supports:\nmore explicit variable configuration a dedicated secret variable type placeholders sliders textarea-style input autogenerated secrets This matters because templates are not just static files with a few replacements anymore. The variable model controls the generation experience.\nFor example, a database password should not behave like a normal text value. It should be treated as a secret, and in many cases it should be generated automatically if you do not provide one manually.\nThat makes templates cleaner for authors and safer for users.\nRemote generation over SSH # This is probably the most practical new feature for everyday use: Boilerplates can now generate templates directly on a remote server over SSH.\nInstead of generating a stack locally, copying it to your server, checking paths, and then deploying it, you can generate directly to the target machine.\nCheck the available options:\nboilerplates compose generate --help The important new flags are:\n--remote --remote-path Example flow:\nboilerplates compose generate gitea \\ --remote homelab-server \\ --remote-path /opt/stacks/gitea Use your own SSH host and target path here. The goal is simple: generate the template where it will actually run.\nDedicated Swarm module # v0.2.0 also adds the first standalone swarm module with its own validation flow.\nThis is not meant to be oversold as a finished Swarm platform yet. It is the groundwork for a cleaner split between Compose workflows and Swarm workflows.\nThat matters because Compose and Swarm look similar in some places, but they are not the same deployment target. Having a dedicated module gives Boilerplates room to validate and generate Swarm-specific templates properly in the future.\nWhat changed in v0.2.0 # The main changes are:\nthe CLI app and template library are now separate repositories templates now use template.json renderable files now live in a dedicated files/ directory templates use custom delimiters instead of default Jinja syntax variables have a more structured configuration model secret variables and autogenerated secrets are better supported templates can be generated directly on remote servers over SSH Swarm now has an initial dedicated module Final thoughts # Boilerplates v0.2.0 is mostly a foundation release.\nSome of the changes are not flashy at first glance, especially the new manifest format and delimiter syntax. But they make the project much easier to maintain, and they make it easier to build better templates later.\nFor users, remote generation over SSH is the most immediately useful feature. For template authors, template.json, the files/ directory, custom delimiters, and better variable modeling are the big improvements.\nIf you are using Boilerplates already, this is a good release to update to and test with your existing workflows.\nReferences # Boilerplates CLI Boilerplates template library ","date":"24 April 2026","externalUrl":null,"permalink":"/videos/boilerplates-0-2-0/","section":"Videos","summary":"","title":"Boilerplates 0.2.0 is HERE // Big Update","type":"videos"},{"content":" If you want to understand why so many people call Caddy the easiest web server and reverse proxy, the best way is to go in order: install it, serve a simple site, then put an app behind it. That is exactly the flow this write-up follows.\nInstallation # The official installation instructions live here:\nInstall Caddy Caddy Documentation Home Caddy supports multiple install paths, including native packages, Docker, and static binaries. For a quick Linux setup, Ubuntu is one of the easiest ways to start because Caddy has an official package.\nQuick Ubuntu example # sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl curl -1sLf \u0026#39;https://dl.cloudsmith.io/public/caddy/stable/gpg.key\u0026#39; | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf \u0026#39;https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt\u0026#39; | sudo tee /etc/apt/sources.list.d/caddy-stable.list sudo chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg sudo chmod o+r /etc/apt/sources.list.d/caddy-stable.list sudo apt update sudo apt install caddy On Ubuntu, the package install also sets up the caddy systemd service. That makes it a nice fit for a simple VPS or homelab VM.\nUseful next step after install:\nsudo systemctl status caddy Configure the web server # Before touching reverse proxying, start with the simplest possible win: serve a static page.\nUpload your demo website to /var/www/html.\nsudo mkdir -p /var/www/html Then replace the default config in /etc/caddy/Caddyfile with a minimal site:\ndemo.domain.tld { root * /var/www/html file_server } Format and reload the config:\nsudo systemctl reload caddy Configure the reverse proxy # Once the static site works, the next step is to proxy an app through Caddy.\nFor a more practical backend example, start Portainer and expose port 9000:\ndocker run -d \\ --name portainer \\ --restart=always \\ -p 9000:9000 \\ -v /var/run/docker.sock:/var/run/docker.sock \\ -v portainer_data:/data \\ portainer/portainer-ce:latest Warning: if you expose Portainer on 9000, it is recommended to add protection so that port 9000 is not reachable directly from outside. A good real-world setup is to bind it only locally or block it with your firewall or security group, then let Caddy be the public entry point.\nNow extend the Caddyfile so one hostname serves files and the other proxies requests:\nportainer-example.domain.tld { reverse_proxy localhost:9000 } Where it gets less easy # This is the honest part: Caddy is super easy on the happy path, but more advanced setups are where the story changes.\nDNS challenge # If you need wildcard certificates or you cannot use the normal HTTP challenge on port 80, the DNS challenge is the usual next step.\nUseful docs:\nCaddy tls directive docs How to use DNS provider modules in Caddy 2 Find DNS provider modules Cloudflare DNS provider module One practical Ubuntu example is to install Go with apt, install xcaddy from the official package repo, and then build a custom Caddy binary with the Cloudflare DNS provider plugin.\nFor other systems, see the official xcaddy install instructions.\nsudo apt update sudo apt install -y golang-go sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl curl -1sLf \u0026#39;https://dl.cloudsmith.io/public/caddy/xcaddy/gpg.key\u0026#39; | sudo gpg --dearmor -o /usr/share/keyrings/caddy-xcaddy-archive-keyring.gpg curl -1sLf \u0026#39;https://dl.cloudsmith.io/public/caddy/xcaddy/debian.deb.txt\u0026#39; | sudo tee /etc/apt/sources.list.d/caddy-xcaddy.list sudo apt update sudo apt install -y xcaddy xcaddy build --with github.com/caddy-dns/cloudflare Replace github.com/caddy-dns/cloudflare with your DNS provider module if you are not using Cloudflare. The result is a custom caddy binary in the current folder. How you roll that into your actual service depends on whether you run Caddy from a package, a container, or a manual binary install.\nFor Cloudflare specifically, the recommended auth method is a scoped API token with at least:\nZone.Zone:Read Zone.DNS:Edit Then configure your Caddyfile to use the DNS challenge:\nexample.com, *.example.com { tls { dns cloudflare {env.CF_API_TOKEN} resolvers 1.1.1.1 } reverse_proxy 127.0.0.1:9000 } If you want to apply the same DNS challenge provider globally for all sites, you can also do it at the top of the Caddyfile:\n{ acme_dns cloudflare {env.CF_API_TOKEN} } Important: if Caddy runs as a systemd service, make sure CF_API_TOKEN is available to that service, not just your current shell.\nDocker labels # If you want Docker metadata and labels to generate proxy configuration automatically instead of maintaining a Caddyfile by hand, the most common community project is:\nlucaslorentz/caddy-docker-proxy That project watches Docker labels, generates an in-memory Caddyfile, and reloads Caddy automatically when containers change. This can be really convenient, but it is also one of the places where the setup becomes less \u0026ldquo;super easy\u0026rdquo; and more opinionated.\n","date":"21 April 2026","externalUrl":null,"permalink":"/videos/caddy-tutorial/","section":"Videos","summary":"","title":"Caddy: Everyone Says It’s the EASIEST… I Tested It","type":"videos"},{"content":" Secure access to your homelab can get messy fast — multiple tools, configs, and workarounds just to get basic access working. In this video, I’ll show you how to set up NetBird using the new simplified architecture, and how you can use it to securely access your infrastructure and expose services to the internet — all in one system.\nRequirements # Linux VM (1 CPU / 2GB RAM) Open ports: 80, 443, 3478/UDP Public domain → pointing to your server Installed: Docker, curl, jq Installation # curl -fsSL https://github.com/netbirdio/netbird/releases/latest/download/getting-started.sh | bash During setup:\nDomain → your public domain Reverse proxy → Traefik (default) Enable proxy → yes References # NetBird Docs: https://docs.netbird.io Self-hosted Guide: https://docs.netbird.io/selfhosted/selfhosted-quickstart ","date":"10 April 2026","externalUrl":null,"permalink":"/videos/netbird-tutorial-2/","section":"Videos","summary":"","title":"NetBird Setup Guide (New \u0026 Simplified)","type":"videos"},{"content":" Migrate from nginx to Angie in Docker, set up built-in ACME for automatic TLS certificates, enable native Prometheus metrics, and configure Docker upstream discovery.\nPrerequisites # Docker and Docker Compose installed Existing nginx config you want to migrate (optional) A public domain name pointing to your server (for ACME / TLS) References # Angie Web Server Angie Docker Installation Angie Migration Guide ACME Module Docs Prometheus Module Docs Docker Upstream Module Docs Angie Grafana Dashboard Angie Ingress Controller (ANIC) Instructions # Migrate from nginx to Angie # Swap the image from nginx to docker.angie.software/angie and update the config mount path from /etc/nginx/conf.d/ to /etc/angie/http.d/.\nYour existing nginx config syntax works as-is.\nBuilt-in ACME (TLS without certbot) # Register an ACME client and reference it in your server block:\nacme_client letsencrypt https://acme-v02.api.letsencrypt.org/directory email=your@email.com; server { listen 443 ssl; server_name your.domain.com; ssl_certificate $acme_cert_letsencrypt; ssl_certificate_key $acme_cert_key_letsencrypt; acme letsencrypt; # ... your existing config } Persist certificates by mounting a volume to /var/lib/angie/acme.\nImportant: HTTP validation requires ports 80 and 443 open to the internet and a public domain pointing to your server.\nPrometheus Metrics # Enable native metrics with a single directive — no exporter sidecar needed:\ninclude prometheus_all.conf; server { listen 9091; location = /metrics { prometheus all; } } Docker Upstream Discovery # Point Angie at the Docker socket and add a label to your upstream container:\nlabels: - \u0026#34;angie.http.upstreams.whoami.port=80\u0026#34; Declare the Docker endpoint and upstream in your config:\ndocker_endpoint unix:/var/run/docker.sock; upstream whoami { zone whoami 1m; } server { listen 80; location /whoami/ { proxy_pass http://whoami/; } } Angie watches Docker events in real time — no reload needed when containers start or stop.\nKubernetes: Angie Ingress Controller (ANIC) # If you are running ingress-nginx, the main alternatives are:\nAngie Ingress Controller (ANIC) — drop-in replacement for ingress-nginx Traefik — alternative with built-in Let\u0026rsquo;s Encrypt and CRD support ","date":"27 March 2026","externalUrl":null,"permalink":"/videos/angie-tutorial/","section":"Videos","summary":"","title":"NGINX is Dead? // Angie Web Server Migration Guide","type":"videos"},{"content":" Self-host OpenClaw on a Hostinger VPS, connect a messaging channel, add skills, and avoid the security and cost traps most people hit.\nPrerequisites # A VPS with Docker (Hostinger one-click template recommended) A domain name with DNS access A messaging account (Telegram, WhatsApp, or Discord) References # OpenClaw Docs Hostinger OpenClaw VPS Template ClaWHub — Skills Directory Instructions # Deploy OpenClaw on Hostinger VPS # Order a KVM 2 VPS using the OpenClaw Docker template at hostinger.com/vps/docker/openclaw. Use promo code LEMPA for a discount.\nImportant: Do NOT open port forwarding — the template configures HTTPS via Traefik automatically. Access OpenClaw through the Access button in the Hostinger panel.\nOnce deployed, retrieve your Gateway Token from the OpenClaw dashboard.\nSSH into the VPS and run onboarding # ssh root@YOUR_HOSTINGER_VPS_IP # Find the running OpenClaw container name docker ps # Open a shell inside the container docker exec -it \u0026lt;container-name\u0026gt; sh # Run the onboarding wizard openclaw onboard Security warning: OpenClaw is a beta project with real tool access (files, commands, tools). A bad prompt can do real damage — never give it more access than necessary.\nConfigure OpenClaw (LLM, channels, skills) # openclaw configure This interactive wizard covers everything: LLM provider, messaging channels, skills, and more.\nLLM options:\nHostinger Nexos AI — pre-integrated, no separate API key. New users get 2x AI credits on first VPS purchase (use promo LEMPA). OpenAI / Anthropic — bring your own API key Ollama / LM Studio — local models, full privacy Warning: OpenClaw is token-hungry on agentic tasks. Monitor usage if you\u0026rsquo;re on a pay-per-token plan.\nMessaging channels — follow the in-wizard instructions for your channel:\nTelegram / Discord: Create a bot → get the bot token → paste it in WhatsApp: Scan the QR code (same as WhatsApp Web) Add Skills # Skills are plain Markdown files that give your agent new capabilities. Browse built-in skills via openclaw configure or find community skills at clawhub.ai.\nInstall community skills\nclawhub search xyz clawhub install xyz ... ","date":"24 March 2026","externalUrl":null,"permalink":"/videos/openclaw-tutorial/","section":"Videos","summary":"","title":"Is OpenClaw Actually Worth It? // Self-Hosted AI Assistant Setup","type":"videos"},{"content":" In this tutorial, I’ll walk you through a no-drama Uptime Kuma v2 upgrade checklist for Docker and Docker Compose: backup first, upgrade safely, wait for the migration, and verify everything (monitors + notifications)\nPrerequisites # A working Uptime Kuma v1 install running in Docker Compose References # Before touching anything, skim the official v1 → v2 migration guide:\nhttps://github.com/louislam/uptime-kuma/wiki/Migration-From-v1-To-v2 Key takeaways:\nStop Uptime Kuma before upgrading. Back up /app/data (seriously: do not skip this). The first start of v2 triggers a one-time migration. Migration time depends on how much history you have. Do not interrupt it. Important Docker tag gotcha (:latest is still v1):\nlouislam/uptime-kuma:latest stays on v1 To upgrade to v2, you must explicitly use :2 Also:\nDo not use :2-rootless for the migration. Rootless images are not recommended for upgrading from v1. Instructions # If you are doing a fresh install (new setup) # If you are not upgrading and you are starting from scratch:\nStart directly on v2. Decide whether to stay on SQLite (simple) or use MariaDB (better for larger installs). If you use my Boilerplates templates:\nboilerplates compose list boilerplates compose show uptimekuma boilerplates compose generate uptimekuma -o /tmp/uptimekuma Upgrade an existing Docker Compose install (v1 → v2) # Below is a minimal example of a v1 compose service (this is what many setups look like):\n--- services: uptimekuma: image: docker.io/louislam/uptime-kuma:1 environment: - TZ=Europe/Berlin ports: - 3001:3001 volumes: - uptimekuma-data:/app/data healthcheck: test: [\u0026#34;CMD\u0026#34;, \u0026#34;curl\u0026#34;, \u0026#34;-f\u0026#34;, \u0026#34;\u0026lt;http://localhost:3001\u0026gt;\u0026#34;] interval: 30s retries: 3 start_period: 10s timeout: 5s restart: unless-stopped volumes: uptimekuma-data: driver: local Stop the Stack:\ndocker compose down Create a backup tarball of /app/data:\ndocker run --rm \\ --volume uptimekuma_uptimekuma-data:/app/data \\ --volume $(pwd):/backup \\ busybox tar czf /backup/backup-v1.tar.gz -C /app/data . Quick sanity check by extracting it:\nmkdir -p backup-v1 tar xfz backup-v1.tar.gz -C backup-v1 ls -la backup-v1 Switch the image tag to v2\nChange:\nlouislam/uptime-kuma:1 → louislam/uptime-kuma:2 Then start it again:\ndocker compose up -d Watch logs and let the migration finish\nWarning: Do not stop the container while it is migrating.\n(Optional) Move from SQLite to MariaDB # If your instance is growing, MariaDB can be worth it. A practical approach is:\nUpgrade to v2 first (let the migration finish). Take another backup. Then switch your deployment to a MariaDB-backed setup. Take a post-migration backup\ndocker compose down docker volume ls | grep uptime docker run --rm \\\\ --volume uptimekuma_uptimekuma-data:/app/data \\\\ --volume $(pwd):/backup \\\\ busybox tar czf /backup/backup-v2.tar.gz -C /app/data . mkdir -p backup-v2 tar xfz backup-v2.tar.gz -C backup-v2 Generate a new compose stack with MariaDB\nIf you use Boilerplates:\nmv compose.yaml old.compose.yaml boilerplates compose generate uptimekuma -o /tmp/uptimekuma Expose MariaDB temporarily if you need to import data:\nAdd ports: - 3306:3306 to the MariaDB service. Start only the database first:\ndocker compose up -d uptimekuma_db Import the SQLite database into MariaDB\nOne option is sqlite3-to-mysql:\nhttps://github.com/techouse/sqlite3-to-mysql Example import:\nsqlite3mysql \\\\ --sqlite-file ./backup-v2/kuma.db \\\\ --mysql-user uptimekuma \\\\ --mysql-password YOUR_PASSWORD \\\\ --mysql-database uptimekuma \\\\ --mysql-host localhost \\\\ --mysql-port 3306 Then start everything:\n# Optional if you are rebuilding from scratch: # docker volume rm uptimekuma_uptimekuma-data docker compose up -d Verification # After the upgrade, validate the important stuff:\nYou can log in and the UI loads Existing monitors are present History and uptime stats are visible Notifications still fire A simple test is to:\nAdd a temporary monitor (or stop a test container) Confirm the alert arrives in your notification provider Troubleshooting / common gotchas # Pulled :latest and nothing changed: that is expected. Use :2 for v2. Migration seems stuck: large instances can take a long time. Keep logs open and be patient. Interrupted migration: restore the /app/data backup and start over. Rootless image issues: avoid :2-rootless during migration. ","date":"6 March 2026","externalUrl":null,"permalink":"/videos/uptimekuma-version-2/","section":"Videos","summary":"","title":"Uptime Kuma v2 is HERE // Breaking Changes \u0026 Safe Upgrade Checklist","type":"videos"},{"content":" In this video, I\u0026rsquo;ll show you how to build a custom Grafana monitoring dashboard for your OPNSense firewall from scratch. We\u0026rsquo;ll dive into PromQL basics, explore the difference between counters and gauges, and create beautiful visualization panels for CPU, memory, disk, network traffic, and firewall statistics. If you\u0026rsquo;ve ever struggled to find the perfect pre-built dashboard or wanted to understand how to craft your own custom queries and styles, this tutorial will guide you through the entire process step by step.\nReferences:\nPart 1 - OPNSense Monitoring Stack Setup: https://youtu.be/F3mvWIPTPjY Prometheus Documentation: https://prometheus.io/docs/ Grafana Documentation: https://grafana.com/docs/ OPNSense Exporter by AthenasMind: https://github.com/AthenasMind/opnsense-exporter My Grafana Dashboard JSON # { \u0026#34;__inputs\u0026#34;: [ { \u0026#34;name\u0026#34;: \u0026#34;DS_PROMETHEUS\u0026#34;, \u0026#34;label\u0026#34;: \u0026#34;Prometheus\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;datasource\u0026#34;, \u0026#34;pluginId\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;pluginName\u0026#34;: \u0026#34;Prometheus\u0026#34; } ], \u0026#34;__elements\u0026#34;: {}, \u0026#34;__requires\u0026#34;: [ { \u0026#34;type\u0026#34;: \u0026#34;panel\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;bargauge\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Bar gauge\u0026#34;, \u0026#34;version\u0026#34;: \u0026#34;\u0026#34; }, { \u0026#34;type\u0026#34;: \u0026#34;panel\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;gauge\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Gauge\u0026#34;, \u0026#34;version\u0026#34;: \u0026#34;\u0026#34; }, { \u0026#34;type\u0026#34;: \u0026#34;grafana\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;grafana\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Grafana\u0026#34;, \u0026#34;version\u0026#34;: \u0026#34;12.1.0\u0026#34; }, { \u0026#34;type\u0026#34;: \u0026#34;panel\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;heatmap\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Heatmap\u0026#34;, \u0026#34;version\u0026#34;: \u0026#34;\u0026#34; }, { \u0026#34;type\u0026#34;: \u0026#34;datasource\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Prometheus\u0026#34;, \u0026#34;version\u0026#34;: \u0026#34;1.0.0\u0026#34; }, { \u0026#34;type\u0026#34;: \u0026#34;panel\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;stat\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Stat\u0026#34;, \u0026#34;version\u0026#34;: \u0026#34;\u0026#34; }, { \u0026#34;type\u0026#34;: \u0026#34;panel\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;status-history\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Status history\u0026#34;, \u0026#34;version\u0026#34;: \u0026#34;\u0026#34; }, { \u0026#34;type\u0026#34;: \u0026#34;panel\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;table\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Table\u0026#34;, \u0026#34;version\u0026#34;: \u0026#34;\u0026#34; }, { \u0026#34;type\u0026#34;: \u0026#34;panel\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;timeseries\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Time series\u0026#34;, \u0026#34;version\u0026#34;: \u0026#34;\u0026#34; } ], \u0026#34;annotations\u0026#34;: { \u0026#34;list\u0026#34;: [ { \u0026#34;builtIn\u0026#34;: 1, \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;enable\u0026#34;: true, \u0026#34;hide\u0026#34;: true, \u0026#34;iconColor\u0026#34;: \u0026#34;rgba(0, 211, 255, 1)\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Annotations \u0026amp; Alerts\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;dashboard\u0026#34; } ] }, \u0026#34;description\u0026#34;: \u0026#34;Comprehensive monitoring dashboard designed for the OPNSense firewall/router operating system. It displays system and network metrics collected from Prometheus.\u0026#34;, \u0026#34;editable\u0026#34;: true, \u0026#34;fiscalYearStartMonth\u0026#34;: 0, \u0026#34;graphTooltip\u0026#34;: 1, \u0026#34;id\u0026#34;: null, \u0026#34;links\u0026#34;: [], \u0026#34;panels\u0026#34;: [ { \u0026#34;collapsed\u0026#34;: false, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 1, \u0026#34;w\u0026#34;: 24, \u0026#34;x\u0026#34;: 0, \u0026#34;y\u0026#34;: 0 }, \u0026#34;id\u0026#34;: 76, \u0026#34;panels\u0026#34;: [], \u0026#34;title\u0026#34;: \u0026#34;System Status\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;row\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;thresholds\u0026#34; }, \u0026#34;fieldMinMax\u0026#34;: false, \u0026#34;mappings\u0026#34;: [], \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;s\u0026#34; }, \u0026#34;overrides\u0026#34;: [] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 3, \u0026#34;w\u0026#34;: 7, \u0026#34;x\u0026#34;: 0, \u0026#34;y\u0026#34;: 1 }, \u0026#34;id\u0026#34;: 75, \u0026#34;options\u0026#34;: { \u0026#34;colorMode\u0026#34;: \u0026#34;value\u0026#34;, \u0026#34;graphMode\u0026#34;: \u0026#34;none\u0026#34;, \u0026#34;justifyMode\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;orientation\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;percentChangeColorMode\u0026#34;: \u0026#34;standard\u0026#34;, \u0026#34;reduceOptions\u0026#34;: { \u0026#34;calcs\u0026#34;: [ \u0026#34;lastNotNull\u0026#34; ], \u0026#34;fields\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;values\u0026#34;: false }, \u0026#34;showPercentChange\u0026#34;: false, \u0026#34;textMode\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;wideLayout\u0026#34;: true }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;(time() - node_boot_time_seconds{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;})\u0026#34;, \u0026#34;legendFormat\u0026#34;: \u0026#34;__auto\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; } } ], \u0026#34;title\u0026#34;: \u0026#34;Uptime\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;stat\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;description\u0026#34;: \u0026#34;Status points of services uptime\\n\\n1 - Available \\n0 - Unavailable\u0026#34;, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;thresholds\u0026#34; }, \u0026#34;custom\u0026#34;: { \u0026#34;axisPlacement\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;fillOpacity\u0026#34;: 59, \u0026#34;hideFrom\u0026#34;: { \u0026#34;legend\u0026#34;: false, \u0026#34;tooltip\u0026#34;: false, \u0026#34;viz\u0026#34;: false }, \u0026#34;lineWidth\u0026#34;: 2 }, \u0026#34;mappings\u0026#34;: [ { \u0026#34;options\u0026#34;: { \u0026#34;0\u0026#34;: { \u0026#34;color\u0026#34;: \u0026#34;semi-dark-red\u0026#34;, \u0026#34;index\u0026#34;: 1, \u0026#34;text\u0026#34;: \u0026#34;Down\u0026#34; }, \u0026#34;1\u0026#34;: { \u0026#34;color\u0026#34;: \u0026#34;semi-dark-green\u0026#34;, \u0026#34;index\u0026#34;: 0, \u0026#34;text\u0026#34;: \u0026#34;Up\u0026#34; } }, \u0026#34;type\u0026#34;: \u0026#34;value\u0026#34; } ], \u0026#34;max\u0026#34;: 1, \u0026#34;min\u0026#34;: 0, \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;none\u0026#34; }, \u0026#34;overrides\u0026#34;: [] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 9, \u0026#34;w\u0026#34;: 17, \u0026#34;x\u0026#34;: 7, \u0026#34;y\u0026#34;: 1 }, \u0026#34;id\u0026#34;: 83, \u0026#34;maxDataPoints\u0026#34;: 100, \u0026#34;options\u0026#34;: { \u0026#34;colWidth\u0026#34;: 1, \u0026#34;legend\u0026#34;: { \u0026#34;displayMode\u0026#34;: \u0026#34;table\u0026#34;, \u0026#34;placement\u0026#34;: \u0026#34;bottom\u0026#34;, \u0026#34;showLegend\u0026#34;: false }, \u0026#34;rowHeight\u0026#34;: 1, \u0026#34;showValue\u0026#34;: \u0026#34;never\u0026#34;, \u0026#34;tooltip\u0026#34;: { \u0026#34;hideZeros\u0026#34;: false, \u0026#34;mode\u0026#34;: \u0026#34;single\u0026#34;, \u0026#34;sort\u0026#34;: \u0026#34;none\u0026#34; } }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;exemplar\u0026#34;: false, \u0026#34;expr\u0026#34;: \u0026#34;opnsense_services_status{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;heatmap\u0026#34;, \u0026#34;instant\u0026#34;: false, \u0026#34;legendFormat\u0026#34;: \u0026#34;{{name}}\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34; } ], \u0026#34;title\u0026#34;: \u0026#34;Services Status History\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;status-history\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;continuous-GrYlRd\u0026#34; }, \u0026#34;custom\u0026#34;: { \u0026#34;axisBorderShow\u0026#34;: false, \u0026#34;axisCenteredZero\u0026#34;: false, \u0026#34;axisColorMode\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;axisLabel\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;axisPlacement\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;barAlignment\u0026#34;: 0, \u0026#34;barWidthFactor\u0026#34;: 0.6, \u0026#34;drawStyle\u0026#34;: \u0026#34;line\u0026#34;, \u0026#34;fillOpacity\u0026#34;: 28, \u0026#34;gradientMode\u0026#34;: \u0026#34;scheme\u0026#34;, \u0026#34;hideFrom\u0026#34;: { \u0026#34;legend\u0026#34;: false, \u0026#34;tooltip\u0026#34;: false, \u0026#34;viz\u0026#34;: false }, \u0026#34;insertNulls\u0026#34;: false, \u0026#34;lineInterpolation\u0026#34;: \u0026#34;smooth\u0026#34;, \u0026#34;lineWidth\u0026#34;: 2, \u0026#34;pointSize\u0026#34;: 1, \u0026#34;scaleDistribution\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;linear\u0026#34; }, \u0026#34;showPoints\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;spanNulls\u0026#34;: false, \u0026#34;stacking\u0026#34;: { \u0026#34;group\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;none\u0026#34; }, \u0026#34;thresholdsStyle\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;off\u0026#34; } }, \u0026#34;mappings\u0026#34;: [], \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 }, { \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;value\u0026#34;: 80 } ] } }, \u0026#34;overrides\u0026#34;: [] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 6, \u0026#34;w\u0026#34;: 7, \u0026#34;x\u0026#34;: 0, \u0026#34;y\u0026#34;: 4 }, \u0026#34;id\u0026#34;: 17, \u0026#34;options\u0026#34;: { \u0026#34;legend\u0026#34;: { \u0026#34;calcs\u0026#34;: [], \u0026#34;displayMode\u0026#34;: \u0026#34;list\u0026#34;, \u0026#34;placement\u0026#34;: \u0026#34;bottom\u0026#34;, \u0026#34;showLegend\u0026#34;: false }, \u0026#34;tooltip\u0026#34;: { \u0026#34;hideZeros\u0026#34;: false, \u0026#34;mode\u0026#34;: \u0026#34;single\u0026#34;, \u0026#34;sort\u0026#34;: \u0026#34;none\u0026#34; } }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;node_cpu_temperature_celsius{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;,cpu=\\\u0026#34;0\\\u0026#34;}\u0026#34;, \u0026#34;legendFormat\u0026#34;: \u0026#34;CPU Temperature\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34; } ], \u0026#34;title\u0026#34;: \u0026#34;Temperature\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;timeseries\u0026#34; }, { \u0026#34;collapsed\u0026#34;: false, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 1, \u0026#34;w\u0026#34;: 24, \u0026#34;x\u0026#34;: 0, \u0026#34;y\u0026#34;: 10 }, \u0026#34;id\u0026#34;: 37, \u0026#34;panels\u0026#34;: [], \u0026#34;title\u0026#34;: \u0026#34;System Health\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;row\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;thresholds\u0026#34; }, \u0026#34;decimals\u0026#34;: 1, \u0026#34;mappings\u0026#34;: [], \u0026#34;max\u0026#34;: 1, \u0026#34;min\u0026#34;: 0, \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 }, { \u0026#34;color\u0026#34;: \u0026#34;yellow\u0026#34;, \u0026#34;value\u0026#34;: 70 }, { \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;value\u0026#34;: 90 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;percentunit\u0026#34; }, \u0026#34;overrides\u0026#34;: [] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 6, \u0026#34;w\u0026#34;: 3, \u0026#34;x\u0026#34;: 0, \u0026#34;y\u0026#34;: 11 }, \u0026#34;id\u0026#34;: 1, \u0026#34;options\u0026#34;: { \u0026#34;minVizHeight\u0026#34;: 75, \u0026#34;minVizWidth\u0026#34;: 75, \u0026#34;orientation\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;reduceOptions\u0026#34;: { \u0026#34;calcs\u0026#34;: [ \u0026#34;lastNotNull\u0026#34; ], \u0026#34;fields\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;values\u0026#34;: false }, \u0026#34;showThresholdLabels\u0026#34;: false, \u0026#34;showThresholdMarkers\u0026#34;: true, \u0026#34;sizing\u0026#34;: \u0026#34;auto\u0026#34; }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;avg without (cpu) (\\n sum without (mode) (\\n rate(node_cpu_seconds_total{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;,mode!=\\\u0026#34;idle\\\u0026#34;}[$__rate_interval])\\n )\\n)\u0026#34;, \u0026#34;legendFormat\u0026#34;: \u0026#34;CPU Usage\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34; } ], \u0026#34;title\u0026#34;: \u0026#34;CPU Usage\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;gauge\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;thresholds\u0026#34;, \u0026#34;seriesBy\u0026#34;: \u0026#34;last\u0026#34; }, \u0026#34;custom\u0026#34;: { \u0026#34;axisBorderShow\u0026#34;: false, \u0026#34;axisCenteredZero\u0026#34;: false, \u0026#34;axisColorMode\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;axisLabel\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;axisPlacement\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;barAlignment\u0026#34;: 0, \u0026#34;barWidthFactor\u0026#34;: 0.6, \u0026#34;drawStyle\u0026#34;: \u0026#34;line\u0026#34;, \u0026#34;fillOpacity\u0026#34;: 43, \u0026#34;gradientMode\u0026#34;: \u0026#34;scheme\u0026#34;, \u0026#34;hideFrom\u0026#34;: { \u0026#34;legend\u0026#34;: false, \u0026#34;tooltip\u0026#34;: false, \u0026#34;viz\u0026#34;: false }, \u0026#34;insertNulls\u0026#34;: false, \u0026#34;lineInterpolation\u0026#34;: \u0026#34;linear\u0026#34;, \u0026#34;lineStyle\u0026#34;: { \u0026#34;fill\u0026#34;: \u0026#34;solid\u0026#34; }, \u0026#34;lineWidth\u0026#34;: 2, \u0026#34;pointSize\u0026#34;: 1, \u0026#34;scaleDistribution\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;linear\u0026#34; }, \u0026#34;showPoints\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;spanNulls\u0026#34;: false, \u0026#34;stacking\u0026#34;: { \u0026#34;group\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;none\u0026#34; }, \u0026#34;thresholdsStyle\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;off\u0026#34; } }, \u0026#34;mappings\u0026#34;: [], \u0026#34;max\u0026#34;: 1, \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;percentage\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 }, { \u0026#34;color\u0026#34;: \u0026#34;#EAB839\u0026#34;, \u0026#34;value\u0026#34;: 30 }, { \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;value\u0026#34;: 60 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;percentunit\u0026#34; }, \u0026#34;overrides\u0026#34;: [] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 6, \u0026#34;w\u0026#34;: 9, \u0026#34;x\u0026#34;: 3, \u0026#34;y\u0026#34;: 11 }, \u0026#34;id\u0026#34;: 73, \u0026#34;options\u0026#34;: { \u0026#34;legend\u0026#34;: { \u0026#34;calcs\u0026#34;: [], \u0026#34;displayMode\u0026#34;: \u0026#34;list\u0026#34;, \u0026#34;placement\u0026#34;: \u0026#34;bottom\u0026#34;, \u0026#34;showLegend\u0026#34;: false }, \u0026#34;tooltip\u0026#34;: { \u0026#34;hideZeros\u0026#34;: false, \u0026#34;mode\u0026#34;: \u0026#34;single\u0026#34;, \u0026#34;sort\u0026#34;: \u0026#34;none\u0026#34; } }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;avg without (cpu) (\\n sum without (mode) (\\n rate(node_cpu_seconds_total{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;,mode!=\\\u0026#34;idle\\\u0026#34;}[$__rate_interval])\\n )\\n)\u0026#34;, \u0026#34;legendFormat\u0026#34;: \u0026#34;{{label_name}}\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; } } ], \u0026#34;title\u0026#34;: \u0026#34;CPU Utilization\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;timeseries\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;palette-classic\u0026#34; }, \u0026#34;custom\u0026#34;: { \u0026#34;axisBorderShow\u0026#34;: false, \u0026#34;axisCenteredZero\u0026#34;: false, \u0026#34;axisColorMode\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;axisLabel\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;axisPlacement\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;barAlignment\u0026#34;: 0, \u0026#34;barWidthFactor\u0026#34;: 0.6, \u0026#34;drawStyle\u0026#34;: \u0026#34;line\u0026#34;, \u0026#34;fillOpacity\u0026#34;: 100, \u0026#34;gradientMode\u0026#34;: \u0026#34;none\u0026#34;, \u0026#34;hideFrom\u0026#34;: { \u0026#34;legend\u0026#34;: false, \u0026#34;tooltip\u0026#34;: false, \u0026#34;viz\u0026#34;: false }, \u0026#34;insertNulls\u0026#34;: false, \u0026#34;lineInterpolation\u0026#34;: \u0026#34;stepBefore\u0026#34;, \u0026#34;lineStyle\u0026#34;: { \u0026#34;fill\u0026#34;: \u0026#34;solid\u0026#34; }, \u0026#34;lineWidth\u0026#34;: 0, \u0026#34;pointSize\u0026#34;: 5, \u0026#34;scaleDistribution\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;linear\u0026#34; }, \u0026#34;showPoints\u0026#34;: \u0026#34;never\u0026#34;, \u0026#34;spanNulls\u0026#34;: true, \u0026#34;stacking\u0026#34;: { \u0026#34;group\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;none\u0026#34; }, \u0026#34;thresholdsStyle\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;off\u0026#34; } }, \u0026#34;mappings\u0026#34;: [], \u0026#34;min\u0026#34;: 0, \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 }, { \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;value\u0026#34;: 80 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;short\u0026#34; }, \u0026#34;overrides\u0026#34;: [ { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;load 1m\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;purple\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;load 5m\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;#5794F2\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;load 15m\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;#77c8d9\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] } ] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 6, \u0026#34;w\u0026#34;: 12, \u0026#34;x\u0026#34;: 12, \u0026#34;y\u0026#34;: 11 }, \u0026#34;id\u0026#34;: 9, \u0026#34;options\u0026#34;: { \u0026#34;legend\u0026#34;: { \u0026#34;calcs\u0026#34;: [], \u0026#34;displayMode\u0026#34;: \u0026#34;list\u0026#34;, \u0026#34;placement\u0026#34;: \u0026#34;bottom\u0026#34;, \u0026#34;showLegend\u0026#34;: false }, \u0026#34;tooltip\u0026#34;: { \u0026#34;hideZeros\u0026#34;: false, \u0026#34;mode\u0026#34;: \u0026#34;multi\u0026#34;, \u0026#34;sort\u0026#34;: \u0026#34;none\u0026#34; } }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;node_load1{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}\u0026#34;, \u0026#34;legendFormat\u0026#34;: \u0026#34;load 1m\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;node_load5{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}\u0026#34;, \u0026#34;hide\u0026#34;: false, \u0026#34;legendFormat\u0026#34;: \u0026#34;load 5m\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;B\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;node_load15{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}\u0026#34;, \u0026#34;hide\u0026#34;: false, \u0026#34;legendFormat\u0026#34;: \u0026#34;load 15m\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;C\u0026#34; } ], \u0026#34;title\u0026#34;: \u0026#34;Load Average\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;timeseries\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;thresholds\u0026#34; }, \u0026#34;decimals\u0026#34;: 1, \u0026#34;mappings\u0026#34;: [], \u0026#34;max\u0026#34;: 100, \u0026#34;min\u0026#34;: 0, \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 }, { \u0026#34;color\u0026#34;: \u0026#34;yellow\u0026#34;, \u0026#34;value\u0026#34;: 70 }, { \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;value\u0026#34;: 90 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;percent\u0026#34; }, \u0026#34;overrides\u0026#34;: [] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 6, \u0026#34;w\u0026#34;: 3, \u0026#34;x\u0026#34;: 0, \u0026#34;y\u0026#34;: 17 }, \u0026#34;id\u0026#34;: 2, \u0026#34;options\u0026#34;: { \u0026#34;minVizHeight\u0026#34;: 75, \u0026#34;minVizWidth\u0026#34;: 75, \u0026#34;orientation\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;reduceOptions\u0026#34;: { \u0026#34;calcs\u0026#34;: [ \u0026#34;lastNotNull\u0026#34; ], \u0026#34;fields\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;values\u0026#34;: false }, \u0026#34;showThresholdLabels\u0026#34;: false, \u0026#34;showThresholdMarkers\u0026#34;: true, \u0026#34;sizing\u0026#34;: \u0026#34;auto\u0026#34; }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;((node_memory_active_bytes{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;} + \\nnode_memory_wired_bytes{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}) / \\nnode_memory_size_bytes{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}) * 100\u0026#34;, \u0026#34;legendFormat\u0026#34;: \u0026#34;Memory Usage\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34; } ], \u0026#34;title\u0026#34;: \u0026#34;Memory Usage\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;gauge\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;palette-classic\u0026#34; }, \u0026#34;custom\u0026#34;: { \u0026#34;axisBorderShow\u0026#34;: false, \u0026#34;axisCenteredZero\u0026#34;: false, \u0026#34;axisColorMode\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;axisLabel\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;axisPlacement\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;barAlignment\u0026#34;: 0, \u0026#34;barWidthFactor\u0026#34;: 0.6, \u0026#34;drawStyle\u0026#34;: \u0026#34;line\u0026#34;, \u0026#34;fillOpacity\u0026#34;: 40, \u0026#34;gradientMode\u0026#34;: \u0026#34;none\u0026#34;, \u0026#34;hideFrom\u0026#34;: { \u0026#34;legend\u0026#34;: false, \u0026#34;tooltip\u0026#34;: false, \u0026#34;viz\u0026#34;: false }, \u0026#34;insertNulls\u0026#34;: false, \u0026#34;lineInterpolation\u0026#34;: \u0026#34;linear\u0026#34;, \u0026#34;lineWidth\u0026#34;: 2, \u0026#34;pointSize\u0026#34;: 5, \u0026#34;scaleDistribution\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;linear\u0026#34; }, \u0026#34;showPoints\u0026#34;: \u0026#34;never\u0026#34;, \u0026#34;spanNulls\u0026#34;: true, \u0026#34;stacking\u0026#34;: { \u0026#34;group\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;normal\u0026#34; }, \u0026#34;thresholdsStyle\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;off\u0026#34; } }, \u0026#34;mappings\u0026#34;: [], \u0026#34;min\u0026#34;: 0, \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 }, { \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;value\u0026#34;: 80 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;bytes\u0026#34; }, \u0026#34;overrides\u0026#34;: [ { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;System Reserved Memory\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;#77c8d9\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;Active Memory\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;blue\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;File Cache (ZFS ARC)\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;purple\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;Inactive Memory\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] } ] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 6, \u0026#34;w\u0026#34;: 9, \u0026#34;x\u0026#34;: 3, \u0026#34;y\u0026#34;: 17 }, \u0026#34;id\u0026#34;: 24, \u0026#34;options\u0026#34;: { \u0026#34;legend\u0026#34;: { \u0026#34;calcs\u0026#34;: [], \u0026#34;displayMode\u0026#34;: \u0026#34;list\u0026#34;, \u0026#34;placement\u0026#34;: \u0026#34;bottom\u0026#34;, \u0026#34;showLegend\u0026#34;: true }, \u0026#34;tooltip\u0026#34;: { \u0026#34;hideZeros\u0026#34;: false, \u0026#34;mode\u0026#34;: \u0026#34;multi\u0026#34;, \u0026#34;sort\u0026#34;: \u0026#34;desc\u0026#34; } }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;node_memory_wired_bytes{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}\u0026#34;, \u0026#34;hide\u0026#34;: false, \u0026#34;instant\u0026#34;: false, \u0026#34;legendFormat\u0026#34;: \u0026#34;System Reserved Memory\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;node_memory_active_bytes{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}\u0026#34;, \u0026#34;hide\u0026#34;: false, \u0026#34;instant\u0026#34;: false, \u0026#34;legendFormat\u0026#34;: \u0026#34;Active Memory\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;B\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;node_zfs_arcstats_size_bytes{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}\u0026#34;, \u0026#34;hide\u0026#34;: false, \u0026#34;instant\u0026#34;: false, \u0026#34;legendFormat\u0026#34;: \u0026#34;File Cache (ZFS ARC)\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;C\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;node_memory_inactive_bytes{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}\u0026#34;, \u0026#34;hide\u0026#34;: false, \u0026#34;instant\u0026#34;: false, \u0026#34;legendFormat\u0026#34;: \u0026#34;Inactive Memory\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;D\u0026#34; } ], \u0026#34;title\u0026#34;: \u0026#34;Memory Usage\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;timeseries\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;thresholds\u0026#34; }, \u0026#34;decimals\u0026#34;: 1, \u0026#34;mappings\u0026#34;: [], \u0026#34;max\u0026#34;: 100, \u0026#34;min\u0026#34;: 0, \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 }, { \u0026#34;color\u0026#34;: \u0026#34;yellow\u0026#34;, \u0026#34;value\u0026#34;: 50 }, { \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;value\u0026#34;: 80 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;percent\u0026#34; }, \u0026#34;overrides\u0026#34;: [] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 6, \u0026#34;w\u0026#34;: 3, \u0026#34;x\u0026#34;: 12, \u0026#34;y\u0026#34;: 17 }, \u0026#34;id\u0026#34;: 3, \u0026#34;options\u0026#34;: { \u0026#34;minVizHeight\u0026#34;: 75, \u0026#34;minVizWidth\u0026#34;: 75, \u0026#34;orientation\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;reduceOptions\u0026#34;: { \u0026#34;calcs\u0026#34;: [ \u0026#34;lastNotNull\u0026#34; ], \u0026#34;fields\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;values\u0026#34;: false }, \u0026#34;showThresholdLabels\u0026#34;: false, \u0026#34;showThresholdMarkers\u0026#34;: true, \u0026#34;sizing\u0026#34;: \u0026#34;auto\u0026#34; }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;(node_memory_swap_used_bytes{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;} / node_memory_swap_size_bytes{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}) * 100\u0026#34;, \u0026#34;legendFormat\u0026#34;: \u0026#34;Swap Usage\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34; } ], \u0026#34;title\u0026#34;: \u0026#34;Swap Usage\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;gauge\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;palette-classic\u0026#34; }, \u0026#34;custom\u0026#34;: { \u0026#34;axisBorderShow\u0026#34;: false, \u0026#34;axisCenteredZero\u0026#34;: false, \u0026#34;axisColorMode\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;axisLabel\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;axisPlacement\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;barAlignment\u0026#34;: 0, \u0026#34;barWidthFactor\u0026#34;: 0.6, \u0026#34;drawStyle\u0026#34;: \u0026#34;line\u0026#34;, \u0026#34;fillOpacity\u0026#34;: 25, \u0026#34;gradientMode\u0026#34;: \u0026#34;opacity\u0026#34;, \u0026#34;hideFrom\u0026#34;: { \u0026#34;legend\u0026#34;: false, \u0026#34;tooltip\u0026#34;: false, \u0026#34;viz\u0026#34;: false }, \u0026#34;insertNulls\u0026#34;: false, \u0026#34;lineInterpolation\u0026#34;: \u0026#34;linear\u0026#34;, \u0026#34;lineStyle\u0026#34;: { \u0026#34;fill\u0026#34;: \u0026#34;solid\u0026#34; }, \u0026#34;lineWidth\u0026#34;: 2, \u0026#34;pointSize\u0026#34;: 1, \u0026#34;scaleDistribution\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;linear\u0026#34; }, \u0026#34;showPoints\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;spanNulls\u0026#34;: false, \u0026#34;stacking\u0026#34;: { \u0026#34;group\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;none\u0026#34; }, \u0026#34;thresholdsStyle\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;off\u0026#34; } }, \u0026#34;mappings\u0026#34;: [], \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 }, { \u0026#34;color\u0026#34;: \u0026#34;#EAB839\u0026#34;, \u0026#34;value\u0026#34;: 30 }, { \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;value\u0026#34;: 60 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;percent\u0026#34; }, \u0026#34;overrides\u0026#34;: [] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 6, \u0026#34;w\u0026#34;: 9, \u0026#34;x\u0026#34;: 15, \u0026#34;y\u0026#34;: 17 }, \u0026#34;id\u0026#34;: 74, \u0026#34;options\u0026#34;: { \u0026#34;legend\u0026#34;: { \u0026#34;calcs\u0026#34;: [], \u0026#34;displayMode\u0026#34;: \u0026#34;list\u0026#34;, \u0026#34;placement\u0026#34;: \u0026#34;bottom\u0026#34;, \u0026#34;showLegend\u0026#34;: false }, \u0026#34;tooltip\u0026#34;: { \u0026#34;hideZeros\u0026#34;: false, \u0026#34;mode\u0026#34;: \u0026#34;single\u0026#34;, \u0026#34;sort\u0026#34;: \u0026#34;none\u0026#34; } }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;(node_memory_swap_used_bytes{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;} / node_memory_swap_size_bytes{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;})\u0026#34;, \u0026#34;legendFormat\u0026#34;: \u0026#34;CPU Usage\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; } } ], \u0026#34;title\u0026#34;: \u0026#34;Swap Usage\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;timeseries\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;purple\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; }, \u0026#34;custom\u0026#34;: { \u0026#34;axisBorderShow\u0026#34;: false, \u0026#34;axisCenteredZero\u0026#34;: false, \u0026#34;axisColorMode\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;axisLabel\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;axisPlacement\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;barAlignment\u0026#34;: 0, \u0026#34;barWidthFactor\u0026#34;: 1, \u0026#34;drawStyle\u0026#34;: \u0026#34;bars\u0026#34;, \u0026#34;fillOpacity\u0026#34;: 100, \u0026#34;gradientMode\u0026#34;: \u0026#34;hue\u0026#34;, \u0026#34;hideFrom\u0026#34;: { \u0026#34;legend\u0026#34;: false, \u0026#34;tooltip\u0026#34;: false, \u0026#34;viz\u0026#34;: false }, \u0026#34;insertNulls\u0026#34;: false, \u0026#34;lineInterpolation\u0026#34;: \u0026#34;linear\u0026#34;, \u0026#34;lineWidth\u0026#34;: 0, \u0026#34;pointSize\u0026#34;: 5, \u0026#34;scaleDistribution\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;linear\u0026#34; }, \u0026#34;showPoints\u0026#34;: \u0026#34;never\u0026#34;, \u0026#34;spanNulls\u0026#34;: true, \u0026#34;stacking\u0026#34;: { \u0026#34;group\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;none\u0026#34; }, \u0026#34;thresholdsStyle\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;off\u0026#34; } }, \u0026#34;mappings\u0026#34;: [], \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 }, { \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;value\u0026#34;: 80 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;short\u0026#34; }, \u0026#34;overrides\u0026#34;: [] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 4, \u0026#34;w\u0026#34;: 12, \u0026#34;x\u0026#34;: 0, \u0026#34;y\u0026#34;: 23 }, \u0026#34;id\u0026#34;: 19, \u0026#34;options\u0026#34;: { \u0026#34;legend\u0026#34;: { \u0026#34;calcs\u0026#34;: [], \u0026#34;displayMode\u0026#34;: \u0026#34;list\u0026#34;, \u0026#34;placement\u0026#34;: \u0026#34;bottom\u0026#34;, \u0026#34;showLegend\u0026#34;: false }, \u0026#34;tooltip\u0026#34;: { \u0026#34;hideZeros\u0026#34;: false, \u0026#34;mode\u0026#34;: \u0026#34;multi\u0026#34;, \u0026#34;sort\u0026#34;: \u0026#34;none\u0026#34; } }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;irate(node_exec_device_interrupts_total{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}[$__rate_interval])\u0026#34;, \u0026#34;legendFormat\u0026#34;: \u0026#34;interrupts\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34; } ], \u0026#34;title\u0026#34;: \u0026#34;Interrupts\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;timeseries\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;#5765f2\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; }, \u0026#34;custom\u0026#34;: { \u0026#34;axisBorderShow\u0026#34;: false, \u0026#34;axisCenteredZero\u0026#34;: false, \u0026#34;axisColorMode\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;axisLabel\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;axisPlacement\u0026#34;: \u0026#34;left\u0026#34;, \u0026#34;barAlignment\u0026#34;: 0, \u0026#34;barWidthFactor\u0026#34;: 1, \u0026#34;drawStyle\u0026#34;: \u0026#34;bars\u0026#34;, \u0026#34;fillOpacity\u0026#34;: 100, \u0026#34;gradientMode\u0026#34;: \u0026#34;hue\u0026#34;, \u0026#34;hideFrom\u0026#34;: { \u0026#34;legend\u0026#34;: false, \u0026#34;tooltip\u0026#34;: false, \u0026#34;viz\u0026#34;: false }, \u0026#34;insertNulls\u0026#34;: false, \u0026#34;lineInterpolation\u0026#34;: \u0026#34;linear\u0026#34;, \u0026#34;lineWidth\u0026#34;: 0, \u0026#34;pointSize\u0026#34;: 5, \u0026#34;scaleDistribution\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;linear\u0026#34; }, \u0026#34;showPoints\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;spanNulls\u0026#34;: false, \u0026#34;stacking\u0026#34;: { \u0026#34;group\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;none\u0026#34; }, \u0026#34;thresholdsStyle\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;off\u0026#34; } }, \u0026#34;mappings\u0026#34;: [], \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 }, { \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;value\u0026#34;: 80 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;short\u0026#34; }, \u0026#34;overrides\u0026#34;: [] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 4, \u0026#34;w\u0026#34;: 12, \u0026#34;x\u0026#34;: 12, \u0026#34;y\u0026#34;: 23 }, \u0026#34;id\u0026#34;: 18, \u0026#34;options\u0026#34;: { \u0026#34;legend\u0026#34;: { \u0026#34;calcs\u0026#34;: [], \u0026#34;displayMode\u0026#34;: \u0026#34;list\u0026#34;, \u0026#34;placement\u0026#34;: \u0026#34;bottom\u0026#34;, \u0026#34;showLegend\u0026#34;: false }, \u0026#34;tooltip\u0026#34;: { \u0026#34;hideZeros\u0026#34;: false, \u0026#34;mode\u0026#34;: \u0026#34;single\u0026#34;, \u0026#34;sort\u0026#34;: \u0026#34;none\u0026#34; } }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;irate(node_exec_context_switches_total{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}[$__rate_interval])\u0026#34;, \u0026#34;legendFormat\u0026#34;: \u0026#34;__auto\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34; } ], \u0026#34;title\u0026#34;: \u0026#34;Context Switches\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;timeseries\u0026#34; }, { \u0026#34;collapsed\u0026#34;: false, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 1, \u0026#34;w\u0026#34;: 24, \u0026#34;x\u0026#34;: 0, \u0026#34;y\u0026#34;: 27 }, \u0026#34;id\u0026#34;: 41, \u0026#34;panels\u0026#34;: [], \u0026#34;title\u0026#34;: \u0026#34;Disk \u0026amp; Storage\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;row\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;thresholds\u0026#34; }, \u0026#34;decimals\u0026#34;: 1, \u0026#34;mappings\u0026#34;: [], \u0026#34;max\u0026#34;: 100, \u0026#34;min\u0026#34;: 0, \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 }, { \u0026#34;color\u0026#34;: \u0026#34;yellow\u0026#34;, \u0026#34;value\u0026#34;: 70 }, { \u0026#34;color\u0026#34;: \u0026#34;orange\u0026#34;, \u0026#34;value\u0026#34;: 85 }, { \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;value\u0026#34;: 95 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;percent\u0026#34; }, \u0026#34;overrides\u0026#34;: [ { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;zroot/ROOT/default\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;displayName\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;/ Root\u0026#34; } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;zroot/home\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;displayName\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;Home\u0026#34; } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;zroot/var/log\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;displayName\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;Log\u0026#34; } ] } ] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 6, \u0026#34;w\u0026#34;: 6, \u0026#34;x\u0026#34;: 0, \u0026#34;y\u0026#34;: 28 }, \u0026#34;id\u0026#34;: 57, \u0026#34;options\u0026#34;: { \u0026#34;displayMode\u0026#34;: \u0026#34;gradient\u0026#34;, \u0026#34;legend\u0026#34;: { \u0026#34;calcs\u0026#34;: [], \u0026#34;displayMode\u0026#34;: \u0026#34;list\u0026#34;, \u0026#34;placement\u0026#34;: \u0026#34;bottom\u0026#34;, \u0026#34;showLegend\u0026#34;: false }, \u0026#34;maxVizHeight\u0026#34;: 300, \u0026#34;minVizHeight\u0026#34;: 16, \u0026#34;minVizWidth\u0026#34;: 8, \u0026#34;namePlacement\u0026#34;: \u0026#34;left\u0026#34;, \u0026#34;orientation\u0026#34;: \u0026#34;horizontal\u0026#34;, \u0026#34;reduceOptions\u0026#34;: { \u0026#34;calcs\u0026#34;: [ \u0026#34;lastNotNull\u0026#34; ], \u0026#34;fields\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;values\u0026#34;: false }, \u0026#34;showUnfilled\u0026#34;: true, \u0026#34;sizing\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;valueMode\u0026#34;: \u0026#34;color\u0026#34; }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;exemplar\u0026#34;: false, \u0026#34;expr\u0026#34;: \u0026#34;(1 - (node_filesystem_avail_bytes{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;,device=~\\\u0026#34;zroot/ROOT/default|zroot/home|zroot/var/log\\\u0026#34;} / node_filesystem_size_bytes{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;,fstype!=\\\u0026#34;nullfs\\\u0026#34;})) * 100 \u0026#34;, \u0026#34;instant\u0026#34;: true, \u0026#34;legendFormat\u0026#34;: \u0026#34;{{device}}\u0026#34;, \u0026#34;range\u0026#34;: false, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34; } ], \u0026#34;title\u0026#34;: \u0026#34;Filesystem Utilization\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;bargauge\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; }, \u0026#34;custom\u0026#34;: { \u0026#34;axisBorderShow\u0026#34;: false, \u0026#34;axisCenteredZero\u0026#34;: false, \u0026#34;axisColorMode\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;axisLabel\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;axisPlacement\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;barAlignment\u0026#34;: 0, \u0026#34;barWidthFactor\u0026#34;: 0.6, \u0026#34;drawStyle\u0026#34;: \u0026#34;line\u0026#34;, \u0026#34;fillOpacity\u0026#34;: 47, \u0026#34;gradientMode\u0026#34;: \u0026#34;opacity\u0026#34;, \u0026#34;hideFrom\u0026#34;: { \u0026#34;legend\u0026#34;: false, \u0026#34;tooltip\u0026#34;: false, \u0026#34;viz\u0026#34;: false }, \u0026#34;insertNulls\u0026#34;: false, \u0026#34;lineInterpolation\u0026#34;: \u0026#34;linear\u0026#34;, \u0026#34;lineStyle\u0026#34;: { \u0026#34;fill\u0026#34;: \u0026#34;solid\u0026#34; }, \u0026#34;lineWidth\u0026#34;: 3, \u0026#34;pointSize\u0026#34;: 5, \u0026#34;scaleDistribution\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;linear\u0026#34; }, \u0026#34;showPoints\u0026#34;: \u0026#34;never\u0026#34;, \u0026#34;spanNulls\u0026#34;: false, \u0026#34;stacking\u0026#34;: { \u0026#34;group\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;normal\u0026#34; }, \u0026#34;thresholdsStyle\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;off\u0026#34; } }, \u0026#34;mappings\u0026#34;: [], \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 }, { \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;value\u0026#34;: 80 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;Bps\u0026#34; }, \u0026#34;overrides\u0026#34;: [ { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;Read\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;blue\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;Write\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;purple\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] } ] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 6, \u0026#34;w\u0026#34;: 9, \u0026#34;x\u0026#34;: 6, \u0026#34;y\u0026#34;: 28 }, \u0026#34;id\u0026#34;: 42, \u0026#34;options\u0026#34;: { \u0026#34;legend\u0026#34;: { \u0026#34;calcs\u0026#34;: [ \u0026#34;mean\u0026#34;, \u0026#34;max\u0026#34; ], \u0026#34;displayMode\u0026#34;: \u0026#34;list\u0026#34;, \u0026#34;placement\u0026#34;: \u0026#34;bottom\u0026#34;, \u0026#34;showLegend\u0026#34;: true }, \u0026#34;tooltip\u0026#34;: { \u0026#34;hideZeros\u0026#34;: false, \u0026#34;mode\u0026#34;: \u0026#34;multi\u0026#34;, \u0026#34;sort\u0026#34;: \u0026#34;none\u0026#34; } }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;sum(rate(node_devstat_bytes_total{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;,type=\\\u0026#34;read\\\u0026#34;}[$__rate_interval]))\u0026#34;, \u0026#34;legendFormat\u0026#34;: \u0026#34;Read\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;sum(rate(node_devstat_bytes_total{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;,type=\\\u0026#34;write\\\u0026#34;}[$__rate_interval]))\u0026#34;, \u0026#34;hide\u0026#34;: false, \u0026#34;instant\u0026#34;: false, \u0026#34;legendFormat\u0026#34;: \u0026#34;Write\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;B\u0026#34; } ], \u0026#34;title\u0026#34;: \u0026#34;Disk I/O\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;timeseries\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; }, \u0026#34;custom\u0026#34;: { \u0026#34;axisBorderShow\u0026#34;: false, \u0026#34;axisCenteredZero\u0026#34;: false, \u0026#34;axisColorMode\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;axisLabel\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;axisPlacement\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;barAlignment\u0026#34;: 0, \u0026#34;barWidthFactor\u0026#34;: 1, \u0026#34;drawStyle\u0026#34;: \u0026#34;bars\u0026#34;, \u0026#34;fillOpacity\u0026#34;: 100, \u0026#34;gradientMode\u0026#34;: \u0026#34;none\u0026#34;, \u0026#34;hideFrom\u0026#34;: { \u0026#34;legend\u0026#34;: false, \u0026#34;tooltip\u0026#34;: false, \u0026#34;viz\u0026#34;: false }, \u0026#34;insertNulls\u0026#34;: false, \u0026#34;lineInterpolation\u0026#34;: \u0026#34;linear\u0026#34;, \u0026#34;lineWidth\u0026#34;: 0, \u0026#34;pointSize\u0026#34;: 5, \u0026#34;scaleDistribution\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;linear\u0026#34; }, \u0026#34;showPoints\u0026#34;: \u0026#34;never\u0026#34;, \u0026#34;spanNulls\u0026#34;: false, \u0026#34;stacking\u0026#34;: { \u0026#34;group\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;normal\u0026#34; }, \u0026#34;thresholdsStyle\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;off\u0026#34; } }, \u0026#34;mappings\u0026#34;: [], \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 }, { \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;value\u0026#34;: 80 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;iops\u0026#34; }, \u0026#34;overrides\u0026#34;: [ { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;Read\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;orange\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;Write\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;yellow\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] } ] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 6, \u0026#34;w\u0026#34;: 9, \u0026#34;x\u0026#34;: 15, \u0026#34;y\u0026#34;: 28 }, \u0026#34;id\u0026#34;: 43, \u0026#34;options\u0026#34;: { \u0026#34;legend\u0026#34;: { \u0026#34;calcs\u0026#34;: [ \u0026#34;mean\u0026#34;, \u0026#34;max\u0026#34; ], \u0026#34;displayMode\u0026#34;: \u0026#34;list\u0026#34;, \u0026#34;placement\u0026#34;: \u0026#34;bottom\u0026#34;, \u0026#34;showLegend\u0026#34;: true }, \u0026#34;tooltip\u0026#34;: { \u0026#34;hideZeros\u0026#34;: false, \u0026#34;mode\u0026#34;: \u0026#34;multi\u0026#34;, \u0026#34;sort\u0026#34;: \u0026#34;none\u0026#34; } }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;sum(rate(node_devstat_transfers_total{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;,type=\\\u0026#34;read\\\u0026#34;}[$__rate_interval]))\u0026#34;, \u0026#34;legendFormat\u0026#34;: \u0026#34;Read\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;sum(rate(node_devstat_transfers_total{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;,type=\\\u0026#34;write\\\u0026#34;}[$__rate_interval]))\u0026#34;, \u0026#34;hide\u0026#34;: false, \u0026#34;instant\u0026#34;: false, \u0026#34;legendFormat\u0026#34;: \u0026#34;Write\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;B\u0026#34; } ], \u0026#34;title\u0026#34;: \u0026#34;Disk IOPS\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;timeseries\u0026#34; }, { \u0026#34;collapsed\u0026#34;: false, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 1, \u0026#34;w\u0026#34;: 24, \u0026#34;x\u0026#34;: 0, \u0026#34;y\u0026#34;: 34 }, \u0026#34;id\u0026#34;: 88, \u0026#34;panels\u0026#34;: [], \u0026#34;repeat\u0026#34;: \u0026#34;gateway\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Gateway $gateway\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;row\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;thresholds\u0026#34; }, \u0026#34;custom\u0026#34;: { \u0026#34;axisPlacement\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;fillOpacity\u0026#34;: 33, \u0026#34;hideFrom\u0026#34;: { \u0026#34;legend\u0026#34;: false, \u0026#34;tooltip\u0026#34;: false, \u0026#34;viz\u0026#34;: false }, \u0026#34;lineWidth\u0026#34;: 3 }, \u0026#34;mappings\u0026#34;: [ { \u0026#34;options\u0026#34;: { \u0026#34;0\u0026#34;: { \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;index\u0026#34;: 0, \u0026#34;text\u0026#34;: \u0026#34;Down\u0026#34; }, \u0026#34;1\u0026#34;: { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;index\u0026#34;: 1, \u0026#34;text\u0026#34;: \u0026#34;Up\u0026#34; }, \u0026#34;2\u0026#34;: { \u0026#34;color\u0026#34;: \u0026#34;yellow\u0026#34;, \u0026#34;index\u0026#34;: 2, \u0026#34;text\u0026#34;: \u0026#34;Ukwn\u0026#34; } }, \u0026#34;type\u0026#34;: \u0026#34;value\u0026#34; } ], \u0026#34;max\u0026#34;: 2, \u0026#34;min\u0026#34;: 0, \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;none\u0026#34; }, \u0026#34;overrides\u0026#34;: [] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 3, \u0026#34;w\u0026#34;: 24, \u0026#34;x\u0026#34;: 0, \u0026#34;y\u0026#34;: 35 }, \u0026#34;id\u0026#34;: 81, \u0026#34;maxDataPoints\u0026#34;: 100, \u0026#34;options\u0026#34;: { \u0026#34;colWidth\u0026#34;: 1, \u0026#34;legend\u0026#34;: { \u0026#34;displayMode\u0026#34;: \u0026#34;list\u0026#34;, \u0026#34;placement\u0026#34;: \u0026#34;bottom\u0026#34;, \u0026#34;showLegend\u0026#34;: false }, \u0026#34;rowHeight\u0026#34;: 1, \u0026#34;showValue\u0026#34;: \u0026#34;never\u0026#34;, \u0026#34;tooltip\u0026#34;: { \u0026#34;hideZeros\u0026#34;: false, \u0026#34;mode\u0026#34;: \u0026#34;single\u0026#34;, \u0026#34;sort\u0026#34;: \u0026#34;none\u0026#34; } }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;exemplar\u0026#34;: false, \u0026#34;expr\u0026#34;: \u0026#34;max by (name) (opnsense_gateways_status{opnsense_instance=\\\u0026#34;$opnsense_instance\\\u0026#34;,name=\\\u0026#34;$gateway\\\u0026#34;})\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;heatmap\u0026#34;, \u0026#34;instant\u0026#34;: false, \u0026#34;legendFormat\u0026#34;: \u0026#34;{{name}}\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; } } ], \u0026#34;title\u0026#34;: \u0026#34;Gateway Status\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;status-history\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;palette-classic\u0026#34; }, \u0026#34;custom\u0026#34;: { \u0026#34;axisBorderShow\u0026#34;: false, \u0026#34;axisCenteredZero\u0026#34;: false, \u0026#34;axisColorMode\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;axisLabel\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;axisPlacement\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;barAlignment\u0026#34;: 0, \u0026#34;barWidthFactor\u0026#34;: 0.6, \u0026#34;drawStyle\u0026#34;: \u0026#34;line\u0026#34;, \u0026#34;fillOpacity\u0026#34;: 0, \u0026#34;gradientMode\u0026#34;: \u0026#34;none\u0026#34;, \u0026#34;hideFrom\u0026#34;: { \u0026#34;legend\u0026#34;: false, \u0026#34;tooltip\u0026#34;: false, \u0026#34;viz\u0026#34;: false }, \u0026#34;insertNulls\u0026#34;: false, \u0026#34;lineInterpolation\u0026#34;: \u0026#34;linear\u0026#34;, \u0026#34;lineWidth\u0026#34;: 1, \u0026#34;pointSize\u0026#34;: 5, \u0026#34;scaleDistribution\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;linear\u0026#34; }, \u0026#34;showPoints\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;spanNulls\u0026#34;: false, \u0026#34;stacking\u0026#34;: { \u0026#34;group\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;none\u0026#34; }, \u0026#34;thresholdsStyle\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;off\u0026#34; } }, \u0026#34;mappings\u0026#34;: [], \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 }, { \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;value\u0026#34;: 80 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;percent\u0026#34; }, \u0026#34;overrides\u0026#34;: [] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 5, \u0026#34;w\u0026#34;: 8, \u0026#34;x\u0026#34;: 0, \u0026#34;y\u0026#34;: 38 }, \u0026#34;id\u0026#34;: 87, \u0026#34;options\u0026#34;: { \u0026#34;legend\u0026#34;: { \u0026#34;calcs\u0026#34;: [], \u0026#34;displayMode\u0026#34;: \u0026#34;list\u0026#34;, \u0026#34;placement\u0026#34;: \u0026#34;bottom\u0026#34;, \u0026#34;showLegend\u0026#34;: true }, \u0026#34;tooltip\u0026#34;: { \u0026#34;hideZeros\u0026#34;: false, \u0026#34;mode\u0026#34;: \u0026#34;single\u0026#34;, \u0026#34;sort\u0026#34;: \u0026#34;none\u0026#34; } }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;max by (name) (opnsense_gateways_loss_percentage{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;,name=\\\u0026#34;$gateway\\\u0026#34;})\u0026#34;, \u0026#34;legendFormat\u0026#34;: \u0026#34;{{name}}\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; } } ], \u0026#34;title\u0026#34;: \u0026#34;Packet loss\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;timeseries\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;palette-classic\u0026#34; }, \u0026#34;custom\u0026#34;: { \u0026#34;axisBorderShow\u0026#34;: false, \u0026#34;axisCenteredZero\u0026#34;: false, \u0026#34;axisColorMode\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;axisLabel\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;axisPlacement\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;barAlignment\u0026#34;: 0, \u0026#34;barWidthFactor\u0026#34;: 0.6, \u0026#34;drawStyle\u0026#34;: \u0026#34;line\u0026#34;, \u0026#34;fillOpacity\u0026#34;: 30, \u0026#34;gradientMode\u0026#34;: \u0026#34;opacity\u0026#34;, \u0026#34;hideFrom\u0026#34;: { \u0026#34;legend\u0026#34;: false, \u0026#34;tooltip\u0026#34;: false, \u0026#34;viz\u0026#34;: false }, \u0026#34;insertNulls\u0026#34;: false, \u0026#34;lineInterpolation\u0026#34;: \u0026#34;linear\u0026#34;, \u0026#34;lineWidth\u0026#34;: 1, \u0026#34;pointSize\u0026#34;: 5, \u0026#34;scaleDistribution\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;linear\u0026#34; }, \u0026#34;showPoints\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;spanNulls\u0026#34;: false, \u0026#34;stacking\u0026#34;: { \u0026#34;group\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;none\u0026#34; }, \u0026#34;thresholdsStyle\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;off\u0026#34; } }, \u0026#34;mappings\u0026#34;: [], \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;ms\u0026#34; }, \u0026#34;overrides\u0026#34;: [] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 5, \u0026#34;w\u0026#34;: 8, \u0026#34;x\u0026#34;: 8, \u0026#34;y\u0026#34;: 38 }, \u0026#34;id\u0026#34;: 85, \u0026#34;options\u0026#34;: { \u0026#34;legend\u0026#34;: { \u0026#34;calcs\u0026#34;: [], \u0026#34;displayMode\u0026#34;: \u0026#34;list\u0026#34;, \u0026#34;placement\u0026#34;: \u0026#34;bottom\u0026#34;, \u0026#34;showLegend\u0026#34;: true }, \u0026#34;tooltip\u0026#34;: { \u0026#34;hideZeros\u0026#34;: false, \u0026#34;mode\u0026#34;: \u0026#34;single\u0026#34;, \u0026#34;sort\u0026#34;: \u0026#34;none\u0026#34; } }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;max by (name) (opnsense_gateways_rtt_milliseconds{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;,name=\\\u0026#34;$gateway\\\u0026#34;})\u0026#34;, \u0026#34;legendFormat\u0026#34;: \u0026#34;{{name}}\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; } } ], \u0026#34;title\u0026#34;: \u0026#34;RTT (latency)\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;timeseries\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;thresholds\u0026#34; }, \u0026#34;custom\u0026#34;: { \u0026#34;axisBorderShow\u0026#34;: false, \u0026#34;axisCenteredZero\u0026#34;: false, \u0026#34;axisColorMode\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;axisLabel\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;axisPlacement\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;barAlignment\u0026#34;: 0, \u0026#34;barWidthFactor\u0026#34;: 0.6, \u0026#34;drawStyle\u0026#34;: \u0026#34;line\u0026#34;, \u0026#34;fillOpacity\u0026#34;: 20, \u0026#34;gradientMode\u0026#34;: \u0026#34;scheme\u0026#34;, \u0026#34;hideFrom\u0026#34;: { \u0026#34;legend\u0026#34;: false, \u0026#34;tooltip\u0026#34;: false, \u0026#34;viz\u0026#34;: false }, \u0026#34;insertNulls\u0026#34;: false, \u0026#34;lineInterpolation\u0026#34;: \u0026#34;linear\u0026#34;, \u0026#34;lineWidth\u0026#34;: 1, \u0026#34;pointSize\u0026#34;: 5, \u0026#34;scaleDistribution\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;linear\u0026#34; }, \u0026#34;showPoints\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;spanNulls\u0026#34;: false, \u0026#34;stacking\u0026#34;: { \u0026#34;group\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;none\u0026#34; }, \u0026#34;thresholdsStyle\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;off\u0026#34; } }, \u0026#34;mappings\u0026#34;: [], \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 }, { \u0026#34;color\u0026#34;: \u0026#34;#EAB839\u0026#34;, \u0026#34;value\u0026#34;: 10 }, { \u0026#34;color\u0026#34;: \u0026#34;orange\u0026#34;, \u0026#34;value\u0026#34;: 30 }, { \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;value\u0026#34;: 50 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;ms\u0026#34; }, \u0026#34;overrides\u0026#34;: [] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 5, \u0026#34;w\u0026#34;: 8, \u0026#34;x\u0026#34;: 16, \u0026#34;y\u0026#34;: 38 }, \u0026#34;id\u0026#34;: 86, \u0026#34;options\u0026#34;: { \u0026#34;legend\u0026#34;: { \u0026#34;calcs\u0026#34;: [], \u0026#34;displayMode\u0026#34;: \u0026#34;list\u0026#34;, \u0026#34;placement\u0026#34;: \u0026#34;bottom\u0026#34;, \u0026#34;showLegend\u0026#34;: true }, \u0026#34;tooltip\u0026#34;: { \u0026#34;hideZeros\u0026#34;: false, \u0026#34;mode\u0026#34;: \u0026#34;single\u0026#34;, \u0026#34;sort\u0026#34;: \u0026#34;none\u0026#34; } }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;avg_over_time(opnsense_gateways_rttd_milliseconds{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;,name=\\\u0026#34;$gateway\\\u0026#34;}[$__rate_interval])\u0026#34;, \u0026#34;legendFormat\u0026#34;: \u0026#34;{{name}}\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; } } ], \u0026#34;title\u0026#34;: \u0026#34;Jitter (RTTd)\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;timeseries\u0026#34; }, { \u0026#34;collapsed\u0026#34;: false, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 1, \u0026#34;w\u0026#34;: 24, \u0026#34;x\u0026#34;: 0, \u0026#34;y\u0026#34;: 43 }, \u0026#34;id\u0026#34;: 79, \u0026#34;panels\u0026#34;: [], \u0026#34;title\u0026#34;: \u0026#34;Network\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;row\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;thresholds\u0026#34; }, \u0026#34;custom\u0026#34;: { \u0026#34;align\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;cellOptions\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;auto\u0026#34; }, \u0026#34;filterable\u0026#34;: false, \u0026#34;inspect\u0026#34;: false }, \u0026#34;mappings\u0026#34;: [], \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 }, { \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;value\u0026#34;: 80 } ] } }, \u0026#34;overrides\u0026#34;: [ { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;Received Rate\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;unit\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;Bps\u0026#34; } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;Transmitted Rate\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;unit\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;Bps\u0026#34; } ] } ] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 9, \u0026#34;w\u0026#34;: 9, \u0026#34;x\u0026#34;: 0, \u0026#34;y\u0026#34;: 44 }, \u0026#34;id\u0026#34;: 80, \u0026#34;maxDataPoints\u0026#34;: 600, \u0026#34;options\u0026#34;: { \u0026#34;cellHeight\u0026#34;: \u0026#34;sm\u0026#34;, \u0026#34;footer\u0026#34;: { \u0026#34;countRows\u0026#34;: false, \u0026#34;enablePagination\u0026#34;: false, \u0026#34;fields\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;reducer\u0026#34;: [ \u0026#34;sum\u0026#34; ], \u0026#34;show\u0026#34;: false }, \u0026#34;frameIndex\u0026#34;: 0, \u0026#34;showHeader\u0026#34;: true }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;exemplar\u0026#34;: false, \u0026#34;expr\u0026#34;: \u0026#34;rate(opnsense_interfaces_received_bytes_total{opnsense_instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}[$__rate_interval])\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;table\u0026#34;, \u0026#34;instant\u0026#34;: true, \u0026#34;legendFormat\u0026#34;: \u0026#34;RX Rate\u0026#34;, \u0026#34;range\u0026#34;: false, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; } }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;exemplar\u0026#34;: false, \u0026#34;expr\u0026#34;: \u0026#34;rate(opnsense_interfaces_transmitted_bytes_total{opnsense_instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}[$__rate_interval])\\n\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;table\u0026#34;, \u0026#34;hide\u0026#34;: false, \u0026#34;instant\u0026#34;: true, \u0026#34;legendFormat\u0026#34;: \u0026#34;TX Rate\u0026#34;, \u0026#34;range\u0026#34;: false, \u0026#34;refId\u0026#34;: \u0026#34;B\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;exemplar\u0026#34;: false, \u0026#34;expr\u0026#34;: \u0026#34;opnsense_interfaces_input_errors_total{opnsense_instance=\\\u0026#34;$opnsense_instance\\\u0026#34;} + opnsense_interfaces_output_errors_total{opnsense_instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;table\u0026#34;, \u0026#34;hide\u0026#34;: false, \u0026#34;instant\u0026#34;: true, \u0026#34;legendFormat\u0026#34;: \u0026#34;Errors\u0026#34;, \u0026#34;range\u0026#34;: false, \u0026#34;refId\u0026#34;: \u0026#34;C\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;exemplar\u0026#34;: false, \u0026#34;expr\u0026#34;: \u0026#34;opnsense_interfaces_mtu_bytes{opnsense_instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}\\n\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;table\u0026#34;, \u0026#34;hide\u0026#34;: false, \u0026#34;instant\u0026#34;: true, \u0026#34;legendFormat\u0026#34;: \u0026#34;MTU\u0026#34;, \u0026#34;range\u0026#34;: false, \u0026#34;refId\u0026#34;: \u0026#34;D\u0026#34; } ], \u0026#34;title\u0026#34;: \u0026#34;Interfaces\u0026#34;, \u0026#34;transformations\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;merge\u0026#34;, \u0026#34;options\u0026#34;: {} }, { \u0026#34;id\u0026#34;: \u0026#34;organize\u0026#34;, \u0026#34;options\u0026#34;: { \u0026#34;excludeByName\u0026#34;: { \u0026#34;Time\u0026#34;: true, \u0026#34;__name__\u0026#34;: true, \u0026#34;device\u0026#34;: true, \u0026#34;group\u0026#34;: true, \u0026#34;host\u0026#34;: true, \u0026#34;instance\u0026#34;: true, \u0026#34;job\u0026#34;: true, \u0026#34;opnsense_instance\u0026#34;: true, \u0026#34;type\u0026#34;: true }, \u0026#34;includeByName\u0026#34;: {}, \u0026#34;indexByName\u0026#34;: {}, \u0026#34;renameByName\u0026#34;: { \u0026#34;Value #A\u0026#34;: \u0026#34;Received Rate\u0026#34;, \u0026#34;Value #B\u0026#34;: \u0026#34;Transmitted Rate\u0026#34;, \u0026#34;Value #C\u0026#34;: \u0026#34;Errors\u0026#34;, \u0026#34;Value #D\u0026#34;: \u0026#34;MTU\u0026#34;, \u0026#34;__name__\u0026#34;: \u0026#34;\u0026#34; } } } ], \u0026#34;type\u0026#34;: \u0026#34;table\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;description\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;custom\u0026#34;: { \u0026#34;hideFrom\u0026#34;: { \u0026#34;legend\u0026#34;: false, \u0026#34;tooltip\u0026#34;: false, \u0026#34;viz\u0026#34;: false }, \u0026#34;scaleDistribution\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;linear\u0026#34; } } }, \u0026#34;overrides\u0026#34;: [] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 14, \u0026#34;w\u0026#34;: 15, \u0026#34;x\u0026#34;: 9, \u0026#34;y\u0026#34;: 44 }, \u0026#34;id\u0026#34;: 82, \u0026#34;maxDataPoints\u0026#34;: 100, \u0026#34;options\u0026#34;: { \u0026#34;calculate\u0026#34;: false, \u0026#34;cellGap\u0026#34;: 2, \u0026#34;cellValues\u0026#34;: { \u0026#34;decimals\u0026#34;: 1, \u0026#34;unit\u0026#34;: \u0026#34;none\u0026#34; }, \u0026#34;color\u0026#34;: { \u0026#34;exponent\u0026#34;: 0.1, \u0026#34;fill\u0026#34;: \u0026#34;dark-green\u0026#34;, \u0026#34;max\u0026#34;: 1, \u0026#34;min\u0026#34;: 0, \u0026#34;mode\u0026#34;: \u0026#34;opacity\u0026#34;, \u0026#34;reverse\u0026#34;: false, \u0026#34;scale\u0026#34;: \u0026#34;linear\u0026#34;, \u0026#34;scheme\u0026#34;: \u0026#34;Greens\u0026#34;, \u0026#34;steps\u0026#34;: 2 }, \u0026#34;exemplars\u0026#34;: { \u0026#34;color\u0026#34;: \u0026#34;rgba(255,0,255,0.7)\u0026#34; }, \u0026#34;filterValues\u0026#34;: { \u0026#34;le\u0026#34;: 1e-9 }, \u0026#34;legend\u0026#34;: { \u0026#34;show\u0026#34;: false }, \u0026#34;rowsFrame\u0026#34;: { \u0026#34;layout\u0026#34;: \u0026#34;auto\u0026#34; }, \u0026#34;tooltip\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;single\u0026#34;, \u0026#34;showColorScale\u0026#34;: false, \u0026#34;yHistogram\u0026#34;: false }, \u0026#34;yAxis\u0026#34;: { \u0026#34;axisPlacement\u0026#34;: \u0026#34;left\u0026#34;, \u0026#34;axisWidth\u0026#34;: 124, \u0026#34;reverse\u0026#34;: false, \u0026#34;unit\u0026#34;: \u0026#34;none\u0026#34; } }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;exemplar\u0026#34;: false, \u0026#34;expr\u0026#34;: \u0026#34;opnsense_arp_table_entries{opnsense_instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;time_series\u0026#34;, \u0026#34;instant\u0026#34;: false, \u0026#34;legendFormat\u0026#34;: \u0026#34;{{mac}}\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34; } ], \u0026#34;title\u0026#34;: \u0026#34;ARP Table Entries \u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;heatmap\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;thresholds\u0026#34; }, \u0026#34;mappings\u0026#34;: [], \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 }, { \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;value\u0026#34;: 80 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;short\u0026#34; }, \u0026#34;overrides\u0026#34;: [ { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;ESTABLISHED\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;TIME_WAIT\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;yellow\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;LISTEN\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;blue\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;SYN_SENT\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;orange\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;SYN_RCVD\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;orange\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;FIN_WAIT_1\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;#FF9830\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;FIN_WAIT_2\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;#FF9830\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;CLOSE_WAIT\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;#FFB366\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;CLOSING\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;#FFB366\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;LAST_ACK\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;#FADE2A\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;CLOSED\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;#808080\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] } ] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 5, \u0026#34;w\u0026#34;: 9, \u0026#34;x\u0026#34;: 0, \u0026#34;y\u0026#34;: 53 }, \u0026#34;id\u0026#34;: 65, \u0026#34;options\u0026#34;: { \u0026#34;displayMode\u0026#34;: \u0026#34;basic\u0026#34;, \u0026#34;legend\u0026#34;: { \u0026#34;calcs\u0026#34;: [], \u0026#34;displayMode\u0026#34;: \u0026#34;list\u0026#34;, \u0026#34;placement\u0026#34;: \u0026#34;bottom\u0026#34;, \u0026#34;showLegend\u0026#34;: false }, \u0026#34;maxVizHeight\u0026#34;: 300, \u0026#34;minVizHeight\u0026#34;: 0, \u0026#34;minVizWidth\u0026#34;: 0, \u0026#34;namePlacement\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;orientation\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;reduceOptions\u0026#34;: { \u0026#34;calcs\u0026#34;: [ \u0026#34;lastNotNull\u0026#34; ], \u0026#34;fields\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;values\u0026#34;: false }, \u0026#34;showUnfilled\u0026#34;: true, \u0026#34;sizing\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;valueMode\u0026#34;: \u0026#34;color\u0026#34; }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;opnsense_protocol_tcp_connection_count_by_state{instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}\u0026#34;, \u0026#34;legendFormat\u0026#34;: \u0026#34;{{state}}\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34; } ], \u0026#34;title\u0026#34;: \u0026#34;TCP Connection States\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;bargauge\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;palette-classic-by-name\u0026#34; }, \u0026#34;custom\u0026#34;: { \u0026#34;axisBorderShow\u0026#34;: true, \u0026#34;axisCenteredZero\u0026#34;: false, \u0026#34;axisColorMode\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;axisLabel\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;axisPlacement\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;barAlignment\u0026#34;: 0, \u0026#34;barWidthFactor\u0026#34;: 0.6, \u0026#34;drawStyle\u0026#34;: \u0026#34;line\u0026#34;, \u0026#34;fillOpacity\u0026#34;: 50, \u0026#34;gradientMode\u0026#34;: \u0026#34;opacity\u0026#34;, \u0026#34;hideFrom\u0026#34;: { \u0026#34;legend\u0026#34;: false, \u0026#34;tooltip\u0026#34;: false, \u0026#34;viz\u0026#34;: false }, \u0026#34;insertNulls\u0026#34;: false, \u0026#34;lineInterpolation\u0026#34;: \u0026#34;linear\u0026#34;, \u0026#34;lineStyle\u0026#34;: { \u0026#34;fill\u0026#34;: \u0026#34;solid\u0026#34; }, \u0026#34;lineWidth\u0026#34;: 2, \u0026#34;pointSize\u0026#34;: 5, \u0026#34;scaleDistribution\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;linear\u0026#34; }, \u0026#34;showPoints\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;spanNulls\u0026#34;: false, \u0026#34;stacking\u0026#34;: { \u0026#34;group\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;none\u0026#34; }, \u0026#34;thresholdsStyle\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;off\u0026#34; } }, \u0026#34;mappings\u0026#34;: [], \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 }, { \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;value\u0026#34;: 80 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;Bps\u0026#34; }, \u0026#34;overrides\u0026#34;: [] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 6, \u0026#34;w\u0026#34;: 24, \u0026#34;x\u0026#34;: 0, \u0026#34;y\u0026#34;: 58 }, \u0026#34;id\u0026#34;: 78, \u0026#34;maxPerRow\u0026#34;: 4, \u0026#34;options\u0026#34;: { \u0026#34;legend\u0026#34;: { \u0026#34;calcs\u0026#34;: [], \u0026#34;displayMode\u0026#34;: \u0026#34;list\u0026#34;, \u0026#34;placement\u0026#34;: \u0026#34;bottom\u0026#34;, \u0026#34;showLegend\u0026#34;: true }, \u0026#34;tooltip\u0026#34;: { \u0026#34;hideZeros\u0026#34;: false, \u0026#34;mode\u0026#34;: \u0026#34;single\u0026#34;, \u0026#34;sort\u0026#34;: \u0026#34;none\u0026#34; } }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;repeat\u0026#34;: \u0026#34;interface\u0026#34;, \u0026#34;repeatDirection\u0026#34;: \u0026#34;h\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;rate(opnsense_interfaces_received_bytes_total{interface=~\\\u0026#34;$interface\\\u0026#34;, instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}[$__rate_interval])\u0026#34;, \u0026#34;legendFormat\u0026#34;: \u0026#34;Received Bytes\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; } }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;-rate(opnsense_interfaces_transmitted_bytes_total{interface=~\\\u0026#34;$interface\\\u0026#34;, instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}[$__rate_interval])\u0026#34;, \u0026#34;hide\u0026#34;: false, \u0026#34;instant\u0026#34;: false, \u0026#34;legendFormat\u0026#34;: \u0026#34;Transmitted Bytes\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;B\u0026#34; } ], \u0026#34;title\u0026#34;: \u0026#34;Received / Transmitted for $interface\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;timeseries\u0026#34; }, { \u0026#34;collapsed\u0026#34;: false, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 1, \u0026#34;w\u0026#34;: 24, \u0026#34;x\u0026#34;: 0, \u0026#34;y\u0026#34;: 64 }, \u0026#34;id\u0026#34;: 60, \u0026#34;panels\u0026#34;: [], \u0026#34;title\u0026#34;: \u0026#34;Firewall Statistics\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;row\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;thresholds\u0026#34; }, \u0026#34;custom\u0026#34;: { \u0026#34;align\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;cellOptions\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;auto\u0026#34; }, \u0026#34;inspect\u0026#34;: false }, \u0026#34;mappings\u0026#34;: [], \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 } ] } }, \u0026#34;overrides\u0026#34;: [ { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;Passed\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;custom.cellOptions\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;color-text\u0026#34; } }, { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;Blocked\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;custom.cellOptions\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;color-text\u0026#34; } }, { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;Passed %\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;custom.cellOptions\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;color-text\u0026#34; } }, { \u0026#34;id\u0026#34;: \u0026#34;decimals\u0026#34;, \u0026#34;value\u0026#34;: 2 } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;Blocked %\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;custom.cellOptions\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;color-text\u0026#34; } }, { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } }, { \u0026#34;id\u0026#34;: \u0026#34;decimals\u0026#34;, \u0026#34;value\u0026#34;: 2 } ] } ] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 12, \u0026#34;w\u0026#34;: 10, \u0026#34;x\u0026#34;: 0, \u0026#34;y\u0026#34;: 65 }, \u0026#34;id\u0026#34;: 63, \u0026#34;options\u0026#34;: { \u0026#34;cellHeight\u0026#34;: \u0026#34;sm\u0026#34;, \u0026#34;footer\u0026#34;: { \u0026#34;countRows\u0026#34;: false, \u0026#34;fields\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;reducer\u0026#34;: [ \u0026#34;sum\u0026#34; ], \u0026#34;show\u0026#34;: false }, \u0026#34;showHeader\u0026#34;: true, \u0026#34;sortBy\u0026#34;: [ { \u0026#34;desc\u0026#34;: true, \u0026#34;displayName\u0026#34;: \u0026#34;Blocked %\u0026#34; } ] }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;exemplar\u0026#34;: false, \u0026#34;expr\u0026#34;: \u0026#34;sum by (interface) (opnsense_firewall_in_ipv4_pass_packets{opnsense_instance=\\\u0026#34;$opnsense_instance\\\u0026#34;,interface=~\\\u0026#34;re.*\\\u0026#34;}) / ((sum by (interface) (opnsense_firewall_in_ipv4_pass_packets{opnsense_instance=\\\u0026#34;$opnsense_instance\\\u0026#34;,interface=~\\\u0026#34;re.*\\\u0026#34;}) + sum by (interface) (opnsense_firewall_in_ipv4_block_packets{opnsense_instance=\\\u0026#34;$opnsense_instance\\\u0026#34;,interface=~\\\u0026#34;re.*\\\u0026#34;})) \u0026gt; 0) * 100\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;table\u0026#34;, \u0026#34;instant\u0026#34;: true, \u0026#34;legendFormat\u0026#34;: \u0026#34;Passed %\u0026#34;, \u0026#34;range\u0026#34;: false, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;exemplar\u0026#34;: false, \u0026#34;expr\u0026#34;: \u0026#34;sum by (interface) (opnsense_firewall_in_ipv4_block_packets{opnsense_instance=\\\u0026#34;$opnsense_instance\\\u0026#34;,interface=~\\\u0026#34;re.*\\\u0026#34;}) / ((sum by (interface) (opnsense_firewall_in_ipv4_pass_packets{opnsense_instance=\\\u0026#34;$opnsense_instance\\\u0026#34;,interface=~\\\u0026#34;re.*\\\u0026#34;}) + sum by (interface) (opnsense_firewall_in_ipv4_block_packets{opnsense_instance=\\\u0026#34;$opnsense_instance\\\u0026#34;,interface=~\\\u0026#34;re.*\\\u0026#34;})) \u0026gt; 0) * 100\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;table\u0026#34;, \u0026#34;hide\u0026#34;: false, \u0026#34;instant\u0026#34;: true, \u0026#34;legendFormat\u0026#34;: \u0026#34;Blocked %\u0026#34;, \u0026#34;range\u0026#34;: false, \u0026#34;refId\u0026#34;: \u0026#34;B\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;exemplar\u0026#34;: false, \u0026#34;expr\u0026#34;: \u0026#34;sum by (interface) (opnsense_firewall_in_ipv4_pass_packets{opnsense_instance=\\\u0026#34;$opnsense_instance\\\u0026#34;,interface=~\\\u0026#34;re.*\\\u0026#34;})\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;table\u0026#34;, \u0026#34;hide\u0026#34;: false, \u0026#34;instant\u0026#34;: true, \u0026#34;legendFormat\u0026#34;: \u0026#34;Passed\u0026#34;, \u0026#34;range\u0026#34;: false, \u0026#34;refId\u0026#34;: \u0026#34;C\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;exemplar\u0026#34;: false, \u0026#34;expr\u0026#34;: \u0026#34;sum by (interface) (opnsense_firewall_in_ipv4_block_packets{opnsense_instance=\\\u0026#34;$opnsense_instance\\\u0026#34;,interface=~\\\u0026#34;re.*\\\u0026#34;})\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;table\u0026#34;, \u0026#34;hide\u0026#34;: false, \u0026#34;instant\u0026#34;: true, \u0026#34;legendFormat\u0026#34;: \u0026#34;Blocked\u0026#34;, \u0026#34;range\u0026#34;: false, \u0026#34;refId\u0026#34;: \u0026#34;D\u0026#34; } ], \u0026#34;title\u0026#34;: \u0026#34;Firewall Statistics by Interface\u0026#34;, \u0026#34;transformations\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;merge\u0026#34;, \u0026#34;options\u0026#34;: {} }, { \u0026#34;id\u0026#34;: \u0026#34;organize\u0026#34;, \u0026#34;options\u0026#34;: { \u0026#34;excludeByName\u0026#34;: { \u0026#34;Time\u0026#34;: true, \u0026#34;Value #B\u0026#34;: false }, \u0026#34;includeByName\u0026#34;: {}, \u0026#34;indexByName\u0026#34;: { \u0026#34;Value #A\u0026#34;: 3, \u0026#34;Value #B\u0026#34;: 4, \u0026#34;Value #C\u0026#34;: 1, \u0026#34;Value #D\u0026#34;: 2, \u0026#34;interface\u0026#34;: 0 }, \u0026#34;orderByMode\u0026#34;: \u0026#34;manual\u0026#34;, \u0026#34;renameByName\u0026#34;: { \u0026#34;Time\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;Value #A\u0026#34;: \u0026#34;Passed %\u0026#34;, \u0026#34;Value #B\u0026#34;: \u0026#34;Blocked %\u0026#34;, \u0026#34;Value #C\u0026#34;: \u0026#34;Passed\u0026#34;, \u0026#34;Value #D\u0026#34;: \u0026#34;Blocked\u0026#34;, \u0026#34;interface\u0026#34;: \u0026#34;Interface\u0026#34; } } } ], \u0026#34;type\u0026#34;: \u0026#34;table\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;palette-classic\u0026#34; }, \u0026#34;custom\u0026#34;: { \u0026#34;axisBorderShow\u0026#34;: false, \u0026#34;axisCenteredZero\u0026#34;: false, \u0026#34;axisColorMode\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;axisLabel\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;axisPlacement\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;barAlignment\u0026#34;: 0, \u0026#34;barWidthFactor\u0026#34;: 0.6, \u0026#34;drawStyle\u0026#34;: \u0026#34;line\u0026#34;, \u0026#34;fillOpacity\u0026#34;: 25, \u0026#34;gradientMode\u0026#34;: \u0026#34;none\u0026#34;, \u0026#34;hideFrom\u0026#34;: { \u0026#34;legend\u0026#34;: false, \u0026#34;tooltip\u0026#34;: false, \u0026#34;viz\u0026#34;: false }, \u0026#34;insertNulls\u0026#34;: false, \u0026#34;lineInterpolation\u0026#34;: \u0026#34;linear\u0026#34;, \u0026#34;lineWidth\u0026#34;: 2, \u0026#34;pointSize\u0026#34;: 5, \u0026#34;scaleDistribution\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;linear\u0026#34; }, \u0026#34;showPoints\u0026#34;: \u0026#34;never\u0026#34;, \u0026#34;spanNulls\u0026#34;: false, \u0026#34;stacking\u0026#34;: { \u0026#34;group\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;none\u0026#34; }, \u0026#34;thresholdsStyle\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;off\u0026#34; } }, \u0026#34;mappings\u0026#34;: [], \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 }, { \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;value\u0026#34;: 80 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;pps\u0026#34; }, \u0026#34;overrides\u0026#34;: [ { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;Pass\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;Block\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] } ] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 6, \u0026#34;w\u0026#34;: 14, \u0026#34;x\u0026#34;: 10, \u0026#34;y\u0026#34;: 65 }, \u0026#34;id\u0026#34;: 61, \u0026#34;options\u0026#34;: { \u0026#34;legend\u0026#34;: { \u0026#34;calcs\u0026#34;: [ \u0026#34;mean\u0026#34;, \u0026#34;max\u0026#34;, \u0026#34;lastNotNull\u0026#34; ], \u0026#34;displayMode\u0026#34;: \u0026#34;list\u0026#34;, \u0026#34;placement\u0026#34;: \u0026#34;bottom\u0026#34;, \u0026#34;showLegend\u0026#34;: true }, \u0026#34;tooltip\u0026#34;: { \u0026#34;hideZeros\u0026#34;: false, \u0026#34;mode\u0026#34;: \u0026#34;multi\u0026#34;, \u0026#34;sort\u0026#34;: \u0026#34;desc\u0026#34; } }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;sum(rate(opnsense_firewall_in_ipv4_pass_packets{opnsense_instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}[$__rate_interval]))\u0026#34;, \u0026#34;legendFormat\u0026#34;: \u0026#34;Pass\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;sum(rate(opnsense_firewall_in_ipv4_block_packets{opnsense_instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}[$__rate_interval]))\u0026#34;, \u0026#34;hide\u0026#34;: false, \u0026#34;legendFormat\u0026#34;: \u0026#34;Block\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;B\u0026#34; } ], \u0026#34;title\u0026#34;: \u0026#34;Firewall IPv4 Incoming Traffic\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;timeseries\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;fieldConfig\u0026#34;: { \u0026#34;defaults\u0026#34;: { \u0026#34;color\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;palette-classic\u0026#34; }, \u0026#34;custom\u0026#34;: { \u0026#34;axisBorderShow\u0026#34;: false, \u0026#34;axisCenteredZero\u0026#34;: false, \u0026#34;axisColorMode\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;axisLabel\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;axisPlacement\u0026#34;: \u0026#34;auto\u0026#34;, \u0026#34;barAlignment\u0026#34;: 0, \u0026#34;barWidthFactor\u0026#34;: 0.6, \u0026#34;drawStyle\u0026#34;: \u0026#34;line\u0026#34;, \u0026#34;fillOpacity\u0026#34;: 25, \u0026#34;gradientMode\u0026#34;: \u0026#34;none\u0026#34;, \u0026#34;hideFrom\u0026#34;: { \u0026#34;legend\u0026#34;: false, \u0026#34;tooltip\u0026#34;: false, \u0026#34;viz\u0026#34;: false }, \u0026#34;insertNulls\u0026#34;: false, \u0026#34;lineInterpolation\u0026#34;: \u0026#34;linear\u0026#34;, \u0026#34;lineWidth\u0026#34;: 2, \u0026#34;pointSize\u0026#34;: 5, \u0026#34;scaleDistribution\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;linear\u0026#34; }, \u0026#34;showPoints\u0026#34;: \u0026#34;never\u0026#34;, \u0026#34;spanNulls\u0026#34;: false, \u0026#34;stacking\u0026#34;: { \u0026#34;group\u0026#34;: \u0026#34;A\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;none\u0026#34; }, \u0026#34;thresholdsStyle\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;off\u0026#34; } }, \u0026#34;mappings\u0026#34;: [], \u0026#34;thresholds\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;absolute\u0026#34;, \u0026#34;steps\u0026#34;: [ { \u0026#34;color\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;value\u0026#34;: 0 }, { \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;value\u0026#34;: 80 } ] }, \u0026#34;unit\u0026#34;: \u0026#34;pps\u0026#34; }, \u0026#34;overrides\u0026#34;: [ { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;Pass\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] }, { \u0026#34;matcher\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;byName\u0026#34;, \u0026#34;options\u0026#34;: \u0026#34;Block\u0026#34; }, \u0026#34;properties\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;color\u0026#34;, \u0026#34;value\u0026#34;: { \u0026#34;fixedColor\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;fixed\u0026#34; } } ] } ] }, \u0026#34;gridPos\u0026#34;: { \u0026#34;h\u0026#34;: 6, \u0026#34;w\u0026#34;: 14, \u0026#34;x\u0026#34;: 10, \u0026#34;y\u0026#34;: 71 }, \u0026#34;id\u0026#34;: 62, \u0026#34;options\u0026#34;: { \u0026#34;legend\u0026#34;: { \u0026#34;calcs\u0026#34;: [ \u0026#34;mean\u0026#34;, \u0026#34;max\u0026#34;, \u0026#34;lastNotNull\u0026#34; ], \u0026#34;displayMode\u0026#34;: \u0026#34;list\u0026#34;, \u0026#34;placement\u0026#34;: \u0026#34;bottom\u0026#34;, \u0026#34;showLegend\u0026#34;: true }, \u0026#34;tooltip\u0026#34;: { \u0026#34;hideZeros\u0026#34;: false, \u0026#34;mode\u0026#34;: \u0026#34;multi\u0026#34;, \u0026#34;sort\u0026#34;: \u0026#34;desc\u0026#34; } }, \u0026#34;pluginVersion\u0026#34;: \u0026#34;12.1.0\u0026#34;, \u0026#34;targets\u0026#34;: [ { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;sum(rate(opnsense_firewall_out_ipv4_pass_packets{opnsense_instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}[1m]))\u0026#34;, \u0026#34;legendFormat\u0026#34;: \u0026#34;Pass\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;A\u0026#34; }, { \u0026#34;datasource\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;prometheus\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;${DS_PROMETHEUS}\u0026#34; }, \u0026#34;editorMode\u0026#34;: \u0026#34;code\u0026#34;, \u0026#34;expr\u0026#34;: \u0026#34;sum(rate(opnsense_firewall_out_ipv4_block_packets{opnsense_instance=\\\u0026#34;$opnsense_instance\\\u0026#34;}[1m]))\u0026#34;, \u0026#34;hide\u0026#34;: false, \u0026#34;legendFormat\u0026#34;: \u0026#34;Block\u0026#34;, \u0026#34;range\u0026#34;: true, \u0026#34;refId\u0026#34;: \u0026#34;B\u0026#34; } ], \u0026#34;title\u0026#34;: \u0026#34;Firewall IPv4 Outgoing Traffic\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;timeseries\u0026#34; } ], \u0026#34;refresh\u0026#34;: \u0026#34;1m\u0026#34;, \u0026#34;schemaVersion\u0026#34;: 41, \u0026#34;tags\u0026#34;: [], \u0026#34;templating\u0026#34;: { \u0026#34;list\u0026#34;: [ { \u0026#34;allowCustomValue\u0026#34;: false, \u0026#34;current\u0026#34;: {}, \u0026#34;definition\u0026#34;: \u0026#34;label_values({group=\\\u0026#34;Firewall\\\u0026#34;},instance)\u0026#34;, \u0026#34;includeAll\u0026#34;: false, \u0026#34;label\u0026#34;: \u0026#34;OPNSense Instance\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;opnsense_instance\u0026#34;, \u0026#34;options\u0026#34;: [], \u0026#34;query\u0026#34;: { \u0026#34;qryType\u0026#34;: 1, \u0026#34;query\u0026#34;: \u0026#34;label_values({group=\\\u0026#34;Firewall\\\u0026#34;},instance)\u0026#34;, \u0026#34;refId\u0026#34;: \u0026#34;PrometheusVariableQueryEditor-VariableQuery\u0026#34; }, \u0026#34;refresh\u0026#34;: 1, \u0026#34;regex\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;query\u0026#34; }, { \u0026#34;allValue\u0026#34;: \u0026#34;*\u0026#34;, \u0026#34;current\u0026#34;: {}, \u0026#34;definition\u0026#34;: \u0026#34;label_values(opnsense_interfaces_received_bytes_total,interface)\u0026#34;, \u0026#34;includeAll\u0026#34;: false, \u0026#34;multi\u0026#34;: true, \u0026#34;name\u0026#34;: \u0026#34;interface\u0026#34;, \u0026#34;options\u0026#34;: [], \u0026#34;query\u0026#34;: { \u0026#34;qryType\u0026#34;: 1, \u0026#34;query\u0026#34;: \u0026#34;label_values(opnsense_interfaces_received_bytes_total,interface)\u0026#34;, \u0026#34;refId\u0026#34;: \u0026#34;PrometheusVariableQueryEditor-VariableQuery\u0026#34; }, \u0026#34;refresh\u0026#34;: 1, \u0026#34;regex\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;query\u0026#34; }, { \u0026#34;current\u0026#34;: {}, \u0026#34;definition\u0026#34;: \u0026#34;label_values(opnsense_gateways_info,name)\u0026#34;, \u0026#34;label\u0026#34;: \u0026#34;Gateway\u0026#34;, \u0026#34;multi\u0026#34;: true, \u0026#34;name\u0026#34;: \u0026#34;gateway\u0026#34;, \u0026#34;options\u0026#34;: [], \u0026#34;query\u0026#34;: { \u0026#34;qryType\u0026#34;: 1, \u0026#34;query\u0026#34;: \u0026#34;label_values(opnsense_gateways_info,name)\u0026#34;, \u0026#34;refId\u0026#34;: \u0026#34;PrometheusVariableQueryEditor-VariableQuery\u0026#34; }, \u0026#34;refresh\u0026#34;: 1, \u0026#34;regex\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;query\u0026#34; } ] }, \u0026#34;time\u0026#34;: { \u0026#34;from\u0026#34;: \u0026#34;now-1h\u0026#34;, \u0026#34;to\u0026#34;: \u0026#34;now\u0026#34; }, \u0026#34;timepicker\u0026#34;: {}, \u0026#34;timezone\u0026#34;: \u0026#34;browser\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;OPNSense Monitoring\u0026#34;, \u0026#34;uid\u0026#34;: \u0026#34;test\u0026#34;, \u0026#34;version\u0026#34;: 99, \u0026#34;weekStart\u0026#34;: \u0026#34;\u0026#34; } ","date":"4 February 2026","externalUrl":null,"permalink":"/videos/opnsense-monitoring-2/","section":"Videos","summary":"","title":"Create your own OPNSense Grafana Monitoring Dashboard","type":"videos"},{"content":" Coolify: The Ultimate Self-Hosted Platform as a Service? # In this video, I\u0026rsquo;ll show you how to set up Coolify, the ultimate open-source alternative to Heroku and Vercel. We\u0026rsquo;ll cover the installation on your own hardware, how to configure your first server, and deploy your applications using Docker and Git. If you want to take control of your PaaS infrastructure while keeping the convenience of modern deployment workflows, this tutorial is for you.\nReferences # Coolify Documentation: https://coolify.io/docs/ Coolify Installation Guide: https://coolify.io/docs/get-started/installation Self-hosted GitLab: https://youtu.be/wLmF8jV_0ck Traefik Tutorial: https://youtu.be/-hfejNXqOzA Proxmox LXC Tutorial: https://youtu.be/iIfRchzYSzM Notes # Quick Installation # Run the following command to install Coolify. This will automatically install Docker, Docker Compose, download the docker-compose.yml file, and start the Coolify service.\ncurl -fsSL https://cdn.coollabs.io/coolify/install.sh | sudo bash Optional: If you need to change Docker\u0026rsquo;s default IP range:\nsudo -E env DOCKER_ADDRESS_POOL_BASE=172.16.0.0/12 DOCKER_ADDRESS_POOL_SIZE=20 bash -c \u0026#39;curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash\u0026#39; Accessing Coolify # After installation, access Coolify at http://your-server-ip:8000 and follow the onboarding instructions to set up your admin account and configure your first server.\n","date":"28 January 2026","externalUrl":null,"permalink":"/videos/coolify-tutorial/","section":"Videos","summary":"","title":"Coolify: The Ultimate Self-Hosted Platform as a Service?","type":"videos"},{"content":" In this video, I\u0026rsquo;ll show you how to set up comprehensive monitoring for your OPNSense firewall using Prometheus, Grafana, and Grafana Alloy. We\u0026rsquo;ll collect both basic system metrics and detailed firewall statistics, allowing you to build powerful Grafana dashboards to correlate data and troubleshoot issues effectively.\nReferences # Prometheus Grafana Grafana Alloy OPNsense API Exporter Instructions # Deploy the Monitoring Stack # Create a compose.yaml file with Prometheus and Grafana to store and visualize your metrics.\nyaml # services: grafana: image: docker.io/grafana/grafana-oss:12.3.1 restart: unless-stopped ports: - \u0026ldquo;3000:3000\u0026rdquo; volumes: - grafana_data:/var/lib/grafana\nprometheus: image: docker.io/prom/prometheus:v3.9.1 restart: unless-stopped command: - \u0026ndash;config.file=/etc/prometheus/prometheus.yaml - \u0026ndash;storage.tsdb.retention.time=15d - \u0026ndash;web.enable-remote-write-receiver ports: - \u0026ldquo;9090:9090\u0026rdquo; volumes: - prometheus_data:/prometheus - ./config/prometheus.yaml:/etc/prometheus/prometheus.yaml:ro\nvolumes: prometheus_data: driver: local grafana_data: driver: local\nScrape System Metrics (Node Exporter) # Install the os-node_exporter plugin in System → Firmware → Plugins. Enable it under Services → Node Exporter. Verify the endpoint is active (replace with your OPNsense IP/hostname): bash curl -s http://your-firewall-ip-address:9100/metrics | head\nConfigure Grafana Alloy # Add Grafana Alloy to your compose.yaml to scrape metrics and forward them to Prometheus.\nyaml services:\n\u0026hellip; your other services # alloy: image: docker.io/grafana/alloy:v1.12.2 restart: unless-stopped ports: - \u0026ldquo;12345:12345\u0026rdquo; volumes: - alloy_data:/alloy/data - ./config_alloy/:/etc/alloy.d\nvolumes:\n\u0026hellip; your other volumes # alloy_data: driver: local\nCreate a config_alloy/ directory next to your compose.yaml file.\nconfig_alloy/targets.alloy\nThis configures the destination for your metrics.\nriver prometheus.remote_write \u0026ldquo;default\u0026rdquo; { endpoint { url = \u0026ldquo;http://prometheus:9090/api/v1/write\u0026rdquo; } }\nconfig_alloy/opnsense_node.alloy\nThis scrapes the Node Exporter on your OPNsense firewall. Make sure to use a consistent instance label for your dashboards.\nriver prometheus.scrape \u0026ldquo;opnsense_node\u0026rdquo; { targets = [{ address = \u0026ldquo;your-firewall-ip-address:9100\u0026rdquo;, instance = \u0026ldquo;opnsense-main\u0026rdquo;, job = \u0026ldquo;node_exporter\u0026rdquo;, group = \u0026ldquo;Firewall\u0026rdquo;, host = \u0026ldquo;opnsense\u0026rdquo;, }]\nforward_to = [prometheus.remote_write.default.receiver] scrape_interval = \u0026ldquo;30s\u0026rdquo; scrape_timeout = \u0026ldquo;10s\u0026rdquo; }\nScrape Firewall Metrics (OPNsense API Exporter) # Create API User: In OPNsense, go to System → Access → Users and create a user (e.g., prometheus-exporter) with a /sbin/nologin shell. Generate an API Key and Secret for this user. Assign Permissions: Assign the necessary permissions via System → Access → Users → Edit user → Effective Privileges. Enable Unbound Stats (Recommended): Go to Services → Unbound DNS → Advanced and check Enable Extended Statistics. Enable Gateway Monitoring: Go to System → Gateways → Single, edit your WAN gateways, and enable the Enable Gateway Monitoring option, setting a monitor IP (e.g., 8.8.8.8). Run the Exporter\nAdd the OPNsense exporter to your compose.yaml. Make sure to provide your API credentials.\nyaml services:\n\u0026hellip; your other services # opnsense-exporter: image: ghcr.io/athennamind/opnsense-exporter:latest container_name: opnsense-exporter restart: unless-stopped ports: - \u0026ldquo;8080:8080\u0026rdquo; environment: - OPNSENSE_EXPORTER_OPS_API_KEY=${OPNSENSE_API_KEY} - OPNSENSE_EXPORTER_OPS_API_SECRET=${OPNSENSE_API_SECRET} command: - \u0026ndash;opnsense.protocol=https - \u0026ndash;opnsense.address=your-firewall-ip-address - \u0026ndash;opnsense.insecure - \u0026ndash;exporter.instance-label=opnsense-main\nScrape the Exporter with Alloy\nCreate a new file config_alloy/opnsense_api.alloy.\nriver prometheus.scrape \u0026ldquo;opnsense_exporter\u0026rdquo; { targets = [{ address = \u0026ldquo;opnsense-exporter:8080\u0026rdquo;, instance = \u0026ldquo;opnsense-main\u0026rdquo;, job = \u0026ldquo;opnsense_exporter\u0026rdquo;, group = \u0026ldquo;Firewall\u0026rdquo;, host = \u0026ldquo;opnsense\u0026rdquo;, }]\nforward_to = [prometheus.remote_write.default.receiver] scrape_interval = \u0026ldquo;30s\u0026rdquo; scrape_timeout = \u0026ldquo;10s\u0026rdquo; }\nImport Grafana Dashboards # Once the metrics are flowing into Prometheus, you can import community dashboards into Grafana. Make sure to adjust the dashboard variables (like job or instance) to match the labels you defined in your Alloy scrape configurations.\n","date":"20 January 2026","externalUrl":null,"permalink":"/videos/opnsense-monitoring/","section":"Videos","summary":"","title":"OPNSense Monitoring with Prometheus, Alloy and Grafana","type":"videos"},{"content":" In this video, I show you how to set up Pangolin, a powerful open-source platform that combines a reverse proxy and VPN into a single ZTNA solution. We\u0026rsquo;ll go through the complete installation process, connect a remote site, and securely publish both public and private services, creating a self-hosted alternative to Cloudflare and traditional VPNs.\nNotes # Architecture Overview # Pangolin is composed of several key components that work together:\nPangolin Server: The central control plane with the web dashboard, API, and management system. It coordinates connections, manages access policies, and stores configurations. Traefik: The underlying reverse proxy that handles HTTP/HTTPS routing, SSL termination, and Let\u0026rsquo;s Encrypt certificate management. Badger: A required Traefik middleware plugin that intercepts requests and authenticates them with the Pangolin server before granting access. Gerbil: Manages the WireGuard tunnels between your remote sites and the Pangolin server. This is optional and only required for tunneling features. Newt: The lightweight software connector that runs on your remote networks (Sites). It establishes a WireGuard tunnel back to Gerbil to proxy local resources. Instructions # Follow the instructions on the official Pangolin documentation to set up your server and connect remote sites: https://docs.pangolin.net/self-host/quick-install\n","date":"15 January 2026","externalUrl":null,"permalink":"/videos/pangolin-tutorial/","section":"Videos","summary":"","title":"Self-hosted Cloudflare + VPN replacement! Pangolin Tutorial","type":"videos"},{"content":" In this video, I\u0026rsquo;ll show you how to install AdGuard Home, a powerful open-source alternative to Pi-hole, using Docker. We will deploy it with a simple command and configure DNS-over-HTTPS (DoH) to encrypt your DNS queries, making your network more private and secure.\nReferences # AdGuard Home GitHub Repository: https://github.com/AdguardTeam/AdguardHome Boilerplates CLI: https://github.com/CICDToolbox/boilerplates Instructions # Installation with Boilerplates CLI # First, install the Boilerplates CLI tool and update the repository.\n# Update the repository boilerplates repo update # (Optional) List available compose files boilerplates compose list Generate the Docker Compose file for AdGuard Home. This example enables integration with a Traefik reverse proxy.\nboilerplates compose generate adguardhome \\ -n \\ -o /tmp/bp-testing/adguardhome-1 \\ -v traefik_enabled=true Alternatively, if you prefer to use macvlan to give AdGuard Home its own IP address on your LAN (note: this setup does not support Traefik integration out of the box):\nbp compose generate adguardhome \\ -n \\ -o /tmp/bp-testing/adguardhome-2 \\ -v network_mode=macvlan \\ -v network_macvlan_ipv4_address=10.20.1.99 \\ -v network_macvlan_subnet=10.20.0.0/16 \\ -v network_macvlan_gateway=10.20.0.1 Enabling Local DNS-over-HTTPS (DoH) # To enable encryption between your clients and AdGuard Home (especially when using a reverse proxy), you need to edit its configuration file. We can use the netshoot container to easily access the volume where the configuration is stored.\n# Replace \u0026#39;adguardhome-1-adguardhome-1\u0026#39; with your container name docker run -it --rm \\ --volumes-from adguardhome-1-adguardhome-1 \\ nicolaka/netshoot bash Once inside the container, edit the configuration file located at /opt/adguardhome/conf/AdGuardHome.yaml. The trusted_proxies setting is crucial so AdGuard Home can see the original client IP address.\nvim /opt/adguardhome/conf/AdGuardHome.yaml Add or modify these values in the YAML file:\ntls: enabled: true allow_unencrypted_doh: true dns: trusted_proxies: - 172.16.0.0/12 # Your Docker network for the reverse proxy After saving the file, exit the netshoot container and recreate your AdGuard Home container to apply the changes.\ndocker compose up -d --force-recreate Testing the DoH Setup # Use a DNS client like doggo to test your new DNS-over-HTTPS endpoint. Replace the URL with your own.\ndoggo example.com @https://adguardhome.srv-test-1.home.clcreative.de/dns-query ","date":"19 December 2025","externalUrl":null,"permalink":"/videos/adguardhome-tutorial/","section":"Videos","summary":"","title":"Block stupid Ads and manage DNS // AdguardHome Tutorial","type":"videos"},{"content":" In this video, I show how to connect AI to your HomeLab, DevOps workflows, and external tools using the Model Context Protocol (MCP), including practical examples with GitHub, Cloudflare, n8n, and more.\n","date":"18 November 2025","externalUrl":null,"permalink":"/videos/mcp-tutorial/","section":"Videos","summary":"","title":"MCP Tutorial: Connect AI to your HomeLab (and more…)","type":"videos"},{"content":" In this video, I show my best n8n HomeLab automation workflows built with AI agents, including automated service updates with patchnote analysis and server health monitoring.\nReferences # N8N Tutorial: https://youtu.be/VUmo6AviDxQ Notes # Practical tips: Define strict JSON schema for AI outputs to keep workflows reliable. Use staged rollouts and health checks after automated merges. Keep a human-in-the-loop for high-risk changes (DB migrations, infra changes). Problems encountered: GitLab Free group hook limitations solved via Terraform automation. Some anomalies detected by AI would have been missed by manual monitoring (eg. missing labels, unexpected egress from Prometheus). ","date":"13 November 2025","externalUrl":null,"permalink":"/videos/n8n-workflows/","section":"Videos","summary":"","title":"My BEST N8N HomeLab automations (AI Agents…)","type":"videos"},{"content":" Block annoying ads and trackers across ALL your devices with Pi-hole! In this video, I\u0026rsquo;ll show you how to deploy Pi-hole on Docker with optional Traefik integration. This free, open-source DNS-level ad blocker works on computers, phones, smart TVs - everything on your network - without installing any client software.\nReferences # Pi-Hole Website: https://pi-hole.net/ Pi-Hole GitHub: https://github.com/pi-hole/docker-pi-hole/#running-pi-hole-docker Boilerplates: https://github.com/ChristianLempa/boilerplates/ Docker Tutorial: https://youtu.be/Nm1tfmZDqo8 Traefik Tutorial: https://youtu.be/-hfejNXqOzA Docker Swarm Tutorial: https://youtu.be/_YsPt7dIvqU ","date":"30 October 2025","externalUrl":null,"permalink":"/videos/pihole-tutorial/","section":"Videos","summary":"","title":"Block stupid Ads and manage DNS // Pi-hole Tutorial","type":"videos"},{"content":" In this video, I self-host GitLab in my HomeLab with Docker using my Boilerplates template, apply resource-friendly optimizations, and harden the instance post-install. I also show how I organize deployments and secrets in Projects and Groups, use the glab CLI, and manage updates with pipelines.\nInstructions # Generate a Docker Compose GitLab setup via Boilerplates # boilerplates compose list boilerplates compose generate gitlab cd gitlab docker compose up -d Retrieve the initial root password # docker exec gitlab grep \u0026#39;Password: \u0026#39; /etc/gitlab/initial_root_password Post-install hardening # Deactivate sign-ups (public instances): Admin Area → Settings → General → Sign-up restrictions Change the initial root password: Profile icon → Edit profile → Password Enable two-factor authentication (2FA): Profile icon → Edit profile → Two-Factor Authentication Performance optimizations # The Boilerplates template uses smart defaults and resource-friendly settings to trim memory usage (observed reductions from ~7 GiB down to ~3 GiB in small setups; thanks to nucez from the Discord community). Use the provided defaults first; tune further based on your host resources and workload. GLab CLI quickstart # Install GLab CLI # Check out: https://docs.gitlab.com/editor_extensions/gitlab_cli/#installation\nAuthenticate # Create a Personal Access Token: Profile → Access tokens (for admin/testing, enable all scopes carefully). Login with glab: glab --help glab auth --help glab auth login # Select: GitLab Self-Managed or GitLab Dedicated # Host: your instance (e.g., http://localhost or https://gitlab.example.com) # Use SSH for Git, HTTP for API (when behind Traefik HTTPS) References # Boilerplates (templates): http://github.com/ChristianLempa/boilerplates/ GitLab install options: https://about.gitlab.com/install/ GitLab pricing overview: https://about.gitlab.com/pricing/ GitLab Community Edition: https://gitlab.com/rluna-gitlab/gitlab-ce glab CLI: https://docs.gitlab.com/editor_extensions/gitlab_cli/ Traefik tutorial: https://youtu.be/-hfejNXqOzA Authentik tutorial: https://youtu.be/N5unsATNpJk ","date":"17 October 2025","externalUrl":null,"permalink":"/videos/gitlab-tutorial-2/","section":"Videos","summary":"","title":"Self-hosting GitLab: A complete HomeLab deployment","type":"videos"},{"content":" In this video, I demonstrate my brand-new open-source CLI tool boilerplates, that generates customizable Docker Compose templates with interactive and non-interactive workflows. We cover listing and searching the template library, setting user defaults, handling secrets, and generating Traefik, Authentik, and Portainer stacks.\nInstructions # Install Boilerplates v2 # # Install via script curl -fsSL https://raw.githubusercontent.com/christianlempa/boilerplates/main/scripts/install.sh | bash # Verify installation boilerplates --version Manage the template library # boilerplates repo --help boilerplates repo update # Discover templates boilerplates list boilerplates search \u0026lt;template_id\u0026gt; # Explore modules (Compose is the first module) boilerplates compose --help Inspect a template # boilerplates show portainer Generate a Docker Compose stack (Portainer example) # # Generate interactively boilerplates generate portainer # Generate non-interactively with custom variables boilerplates generate portainer --no-interactive \\ --var traefik_enabled=true \\ --var traefik_network=proxy \\ --var container_timezone=Europe/Berlin Set user default variables # If you repeat the same options (e.g., Traefik network, timezone), set user defaults once:\npython3 -m cli compose defaults --help python3 -m cli compose defaults set traefik_enabled=true python3 -m cli compose defaults set traefik_network=proxy python3 -m cli compose defaults set container_timezone=Europe/Berlin Defaults are applied to future generations and can be overridden per run with \u0026ndash;var.\nReferences # GitHub Repository ","date":"13 October 2025","externalUrl":null,"permalink":"/videos/boilerplates-v2/","section":"Videos","summary":"","title":"My ultimate Docker Compose template toolkit: Boilerplates v2","type":"videos"},{"content":" In this video, I explain why AI won\u0026rsquo;t replace your job, demonstrate agentic AI coding and \u0026lsquo;vibe coding\u0026rsquo; with tools like Warp and GitHub Copilot, and show practical examples and notes on building an AI-driven web app.\nInstructions # Agentic AI vs simple chat # Chat models: prompt -\u0026gt; response Agentic AI: runs tasks autonomously, chains actions, calls external tools/APIs, manipulates files and runs commands. Tools I tried # Warp (excellent for agentic workflows and code generation): https://www.warp.dev/ GitHub Copilot (agentic features inside IDEs): https://docs.github.com/en/copilot Notes # Key takeaway: agentic AI drastically speeds up scaffolding and repetitive work, but it does not replace human creativity, system design, auditing and long-term maintenance. Team impact: expect new tasks (reviewing AI output, securing pipelines, cleaning up \u0026ldquo;vibe-coded\u0026rdquo; artifacts). Roles like \u0026ldquo;vibe-coding cleanup specialist\u0026rdquo; may appear. Practical advice: learn agent tools, add CI checks, require code reviews, create test suites, and instrument monitoring. References # Warp Tutorial: https://www.youtube.com/watch?v=d6QZ1v_J4lI ","date":"4 October 2025","externalUrl":null,"permalink":"/videos/ai-opinion/","section":"Videos","summary":"","title":"Why AI will NOT replace your job! (… my opinion)","type":"videos"},{"content":" In this video, I show how to manage Authentik resources with Terraform, including provider setup, outposts, and applications.\nInstructions # Prerequisites # Set secure variables for AUTHENTIK_URL and AUTHENTIK_TOKEN (do not hardcode tokens). Terraform project initialized for the goauthentik/authentik provider. Provider configuration # terraform { authentik = { source = \u0026#34;goauthentik/authentik\u0026#34; version = \u0026#34;2025.6.0\u0026#34; } } provider \u0026#34;authentik\u0026#34; { url = var.AUTHENTIK_URL token = var.AUTHENTIK_TOKEN } Add AUTHENTIK_URL and AUTHENTIK_TOKEN to your environment/secret manager and reference them as variables.\nCreate a proxy provider (example) # Lookup flows used by the provider via data resources, then create the proxy provider. data \u0026#34;authentik_flow\u0026#34; \u0026#34;default-authorization-flow\u0026#34; { slug = \u0026#34;default-provider-authorization-implicit-consent\u0026#34; } data \u0026#34;authentik_flow\u0026#34; \u0026#34;default-invlidation-flow\u0026#34; { slug = \u0026#34;default-provider-invalidation-flow\u0026#34; } resource \u0026#34;authentik_provider_proxy\u0026#34; \u0026#34;nginx-test-1\u0026#34; { name = \u0026#34;nginx_test_1\u0026#34; mode = \u0026#34;forward_single\u0026#34; # proxy, forward_single, forward_domain access_token_validity = \u0026#34;hours=24\u0026#34; external_host = \u0026#34;https://nginx-test-1.srv-prod-1.home.clcreative.de\u0026#34; authorization_flow = data.authentik_flow.default-authorization-flow.id invalidation_flow = data.authentik_flow.default-invlidation-flow.id } Create an application # resource \u0026#34;authentik_application\u0026#34; \u0026#34;nginx_test_1\u0026#34; { name = \u0026#34;nginx_test_1\u0026#34; slug = \u0026#34;nginx_test_1\u0026#34; protocol_provider = authentik_provider_proxy.nginx-test-1.id } Example Traefik middleware label: traefik.http.routers.nginx-test-1.middlewares=authentik-prod-1-middleware@file References # Authentik Tutorial: https://youtu.be/N5unsATNpJk Authentik Outposts: https://youtu.be/_I3hUI1JQP4 ","date":"30 September 2025","externalUrl":null,"permalink":"/videos/authentik-terraform/","section":"Videos","summary":"","title":"Manage Authentik Resources in Terraform","type":"videos"},{"content":" In this video, we take a deep dive into the latest features of Portainer, the popular Docker and Kubernetes management platform. We\u0026rsquo;ll explore its recent rebranding, new functionalities for managing containers and clusters, and showcase how its Terraform provider can automate your deployments. Join me as we review these exciting updates and uncover some previously unexplored capabilities.\nReferences\nTerraform Tutorial: https://www.youtube.com/watch?v=fEIIxZUf4co OpenTofu Tutorial: https://www.youtube.com/watch?v=xstFUuFt5Q0 Portainer Tutorial: https://www.youtube.com/watch?v=ljDI5jykjE8 Notes # New Portainer UI \u0026amp; Branding # Portainer has rebranded with a fresh purple logo and modern UI, but the core experience remains the same. The CE version is still free and fully functional for most use cases.\nEnvironment Management # You can add multiple environments—Docker Standalone, Swarm, Kubernetes, Podman, or ACI—using the Agent or Edge Agent. Swarm mode is now a first‑class citizen, making it easier to manage services and overlay networks.\nKubernetes Enhancements # Portainer now supports Helm charts with update/rollback, and you can manage native Kubernetes resources such as Services, Ingresses, CronJobs, Jobs, Service Accounts, and ClusterRoles. The UI still lacks some custom resources like Traefik Ingress, but most core objects are covered.\nTerraform Provider # The new Terraform provider lets you provision Portainer stacks and other Docker/Kubernetes resources declaratively. The example in the video uses a simple nginx stack to illustrate stack_file_content, deployment_type, and network configuration.\nVendor Lock Considerations # While the Terraform provider is powerful, it ties you to Portainer for automation. Consider whether you want to rely on a single vendor for your infrastructure code.\n","date":"26 September 2025","externalUrl":null,"permalink":"/videos/portainer-tutorial-2/","section":"Videos","summary":"","title":"Is Portainer still the best Docker and Kubernetes Management Platform?","type":"videos"},{"content":" In this video, I\u0026rsquo;ll show you how to automate nearly anything with n8n, a powerful self-hosted, low-code automation platform. We\u0026rsquo;ll explore how to install it, connect various services, and build advanced workflows using data transformation and JavaScript expressions, including automating social media posting from Notion.\nReferences # n8n Official Website: https://n8n.io/ Docker Tutorial: https://www.youtube.com/watch?v=Nm1tfmZDqo8 Traefik Tutorial: https://www.youtube.com/watch?v=-hfejNXqOzA Notes # n8n Installation with Docker # n8n recommends using Docker for self-hosting, ensuring a clean and isolated environment.\nHere’s a basic docker compose.yaml configuration to get you started:\n--- services: n8n: image: n8nio/n8n:1.110.1 container_name: n8n-test-1 environment: - N8N_LOG_LEVEL=info - GENERIC_TIMEZONE=Europe/Berlin - TZ=Europe/Berlin - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true - N8N_RUNNERS_ENABLED=true - N8N_SECURE_COOKIE=false # Needed when NOT using HTTPS (traefik) # important when using traefik - N8N_EDITOR_BASE_URL=http://n8n-test-1.orb.local:5678 # enable postgres # - DB_TYPE=postgresdb # - DB_POSTGRESDB_HOST=postgres # - DB_POSTGRESDB_PORT=${DB_POSTGRESDB_PORT:-5432} # - DB_POSTGRESDB_DATABASE=${POSTGRES_DB} # - DB_POSTGRESDB_USER=${POSTGRES_USER} # - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD} volumes: - /etc/localtime:/etc/localtime:ro - data:/home/node/.n8n ports: - \u0026#34;5678:5678\u0026#34; # networks: # - proxy # labels: # - \u0026#34;traefik.enable=true\u0026#34; # - \u0026#34;traefik.http.routers.n8n.rule=Host(`http://n8n-test-1.orb.local:5678`)\u0026#34; # - \u0026#34;traefik.http.routers.n8n.entrypoints=websecure\u0026#34; # - \u0026#34;traefik.http.routers.n8n.tls=true\u0026#34; # - \u0026#34;traefik.http.routers.n8n.tls.certresolver=${TRAEFIK_CERTRESOLVER:-le}\u0026#34; # - \u0026#34;traefik.http.services.n8n.loadbalancer.server.port=${N8N_PORT:-5678}\u0026#34; restart: unless-stopped volumes: data: driver: local # networks: # proxy: # external: true Understanding Workflows # Initial Setup: After installation, configure your account (email, name, password) and customize n8n settings. You can get paid features for free forever on your self-hosted instance. Workflow Basics: Workflows process data from left (input) to right (output). Green colored nodes indicate successful execution. The Execution Log on the main page provides detailed information about each run. Templates: Explore the extensive library of pre-built templates to kickstart your automation. Triggers # Triggers initiate your workflows and can be configured in various ways:\nOn App Events: Execute when something specific happens in an integrated application (e.g., a Notion page is updated, a GitLab Merge Request or Issue is created). On Schedule: Run the workflow at specified intervals (e.g., every X seconds, minutes, hours, days) or at a particular timestamp. On Webhook Call: A webhook is an HTTP request sent from one system to another based on an event, allowing real-time data transfer and action processing. Actions # Actions are the core building blocks of your workflows, performing tasks or manipulating data:\nAI Integrations: Connect with AI agents or APIs like OpenAI and Gemini. App Integrations: Leverage over 1,100 integrations with various platforms across Cybersecurity, Data \u0026amp; Storage, Development, and Social Media. Data Transformation: Add, remove, or combine items, and convert data between different formats. Flows: Implement logical operations within your workflow. Core Functions: Execute commands, send webhooks to other platforms, and more. Human Confirmation: Integrate a step to wait for human confirmation via messaging platforms or email. Managing Credentials # To connect to different applications, you need to authenticate using credentials. While some integrations are straightforward (e.g., Discord), others, particularly those using OAuth, can be more complex.\nOAuth Callback URLs: The callback URL is where the authenticated provider sends its response. This should typically be your local n8n instance\u0026rsquo;s address, as it doesn\u0026rsquo;t require external access. Leveraging JavaScript Expressions # JavaScript expressions are invaluable for filtering specific items, retrieving data from previous nodes, and performing custom logic.\nSyntax: Use double curly braces {{ JavaScript Expression }}. n8n\u0026rsquo;s Templating Language: n8n uses a templating language called Tournament, extended with custom methods, variables, and data transformation functions. Example: Use {{ DateTime.now() }} to get the current timestamp. Advanced Flow \u0026amp; Data Transformation # Split Out Node: Select a property to split out and make sure to include \u0026ldquo;All Other Fields\u0026rdquo; to retain necessary data for further transformations. If Node: Use for simple conditional (if/else) logic. Switch Node: Create routing rules for different cases, allowing you to change output names and convert data types as required. An example use case is routing social media posts based on the platform, such as splitting out \u0026ldquo;Discord\u0026rdquo; posts to send via a webhook. Error Handling # Implement error handling within your workflows to manage unexpected issues gracefully. Remember to activate workflows when they are scheduled to run.\n","date":"23 September 2025","externalUrl":null,"permalink":"/videos/n8n-tutorial/","section":"Videos","summary":"","title":"Self-hosted automation for EVERYTHING! // n8n Tutorial","type":"videos"},{"content":" In this video, I\u0026rsquo;ll guide you through setting up Proxmox Backup Server (PBS) to revolutionize your Proxmox backups. We\u0026rsquo;ll explore how to achieve incremental backups, deduplication, and efficient restores, moving beyond basic NFS shares. Discover how to install and configure PBS for both local and remote storage, ensuring your data is protected intelligently.\nReferences # Proxmox Helper Scripts: https://community-scripts.github.io/ProxmoxVE/ Proxmox Best-Practices: https://www.youtube.com/watch?v=VAJWUZ3sTSI Notes # Why Proxmox Backup Server (PBS)? # PBS is a game-changer for Proxmox users, offering significant advantages over traditional backup methods like simple NFS shares. It enables:\nIncremental Backups: Only store changes after an initial full backup, saving significant disk space. Deduplication: Avoids storing identical data blocks multiple times, further optimizing storage. Easy File Recovery: Beyond full VM restores, PBS allows file-level recovery. Flexible Installation: Can run on a separate device, as a VM (with caution), or preferably as an LXC container on your Proxmox host. Installing Proxmox Backup Server # While Proxmox recommends installing PBS on a separate physical device, it can be run as an LXC container on your existing Proxmox host to save on cost and power consumption.\nCheck out Proxmox Helper Scripts: https://community-scripts.github.io/ProxmoxVE/ to simplify the installation process.\nConfiguring Datastores # PBS supports storing backups locally or on remote storage.\nOption 1: Local Storage (Example with LXC) # To use existing disks on your Proxmox host (e.g., ZFS, NVMe) for local storage within an LXC container:\nStop the LXC Container. On Proxmox PVE, select the LXC Container and go to \u0026ldquo;Resources → Add: Mount Point\u0026rdquo;. Select an available disk and specify a path inside the container (e.g., /mnt/backup-local). Crucially, disable \u0026ldquo;Backup\u0026rdquo; for this mount point to prevent recursive backups. Inside the PBS LXC interface, navigate to \u0026ldquo;Datastore → Create: Datastore\u0026rdquo;. Set the \u0026ldquo;Backing Path\u0026rdquo; to match the mount point you created (e.g., /mnt/backup-local). GC Schedule (Garbage Collection): Configures when unused data blocks are removed. Prune Schedule: Defines retention policies for your backups. For a small HomeLab, a good starting point is keep daily: 7, keep weekly: 1, keep monthly: 1. Recommended Settings: In \u0026ldquo;Settings → Options,\u0026rdquo; enable \u0026ldquo;Verify new Snapshots\u0026rdquo; and configure notification settings if desired. Adding Backup Jobs on Proxmox # To integrate your Proxmox hosts with your new Proxmox Backup Server:\nConfigure the PBS Datastore on Proxmox PVE # On your Proxmox Backup Server, create a new backup user under \u0026ldquo;Configuration → Access Control → User Management.\u0026rdquo; Assign permissions to this user in \u0026ldquo;Configuration → Access Control → Permissions.\u0026rdquo; Set the Path to /datastore, select your user, and add the Role DatastoreAdmin. On your Proxmox PVE host, go to \u0026ldquo;Datacenter → Storage\u0026rdquo; and add a new \u0026ldquo;Proxmox Backup Server\u0026rdquo; location. server: Enter the IP address or hostname of your PBS. datastore: Enter the name of the datastore you created on PBS. fingerprint: Find this in your Proxmox Backup Server under \u0026ldquo;Configuration → Certificates → proxy.pem.\u0026rdquo; Do not configure Backup Retention here; it is managed on PBS. (Optional) Set up encryption. Change Your Backup Target # Under \u0026ldquo;Datacenter → Backup\u0026rdquo; on your Proxmox PVE host, create a new backup job or modify an existing one to use your newly configured Proxmox Backup Server storage. Restoring Backups # PBS enhances restore capabilities beyond typical VM restoration:\nVM Restore: Standard full VM restore is available, similar to other storage types. File-Level Restore: You can browse the contents of a backup and restore individual files directly from your Proxmox PVE node. To do this, select the vm-backups storage on your Proxmox node, choose the desired backup, and select \u0026ldquo;File Restore.\u0026rdquo; Files are typically downloaded as a \u0026ldquo;ZIP\u0026rdquo; archive, rather than an \u0026ldquo;in-place\u0026rdquo; restore directly to the VM. Configuring Remote Storage (NFS Example for LXC) # Using remote storage like a NAS (e.g., TrueNAS, Unraid) centralizes data. If running PBS in an LXC, this requires a privileged container and careful configuration:\nSSH into your PBS LXC container. Create the necessary directories and set permissions: mkdir /mnt/vm-nfs-backup chown backup:backup /mnt/vm-nfs-backup chmod 775 /mnt/vm-nfs-backup Install nfs-common if it\u0026rsquo;s not already present: apt list --installed | grep nfs-common sudo apt install nfs-common vim Add an entry to /etc/fstab for persistent mounting (replace 10.20.0.7 with your NFS server IP and /vm-nfs-backup with your NFS export path): echo \u0026#34;10.20.0.7:/vm-nfs-backup /mnt/vm-nfs-backup nfs vers=4,nouser,atime,auto,retrans=2,rw,dev,exec 0 0\u0026#34; \u0026gt;\u0026gt; /etc/fstab Reload systemd daemon to recognize the new fstab entry: systemctl daemon-reload Verify the mount: ls /mnt/vm-nfs-backup/ (or similar). Common Problems Encountered:\nDirectory Not Empty: Ensure the mount point directory (/mnt/vm-nfs-backup) is empty before attempting to mount the NFS share. no_root_squash: On your NFS server, you might need to add the no_root_squash option to the NFS export settings. This allows the root user on the client (your PBS LXC) to have root privileges on the mounted directory, which is often necessary for PBS operations. ","date":"18 September 2025","externalUrl":null,"permalink":"/videos/proxmox-backupserver-tutorial/","section":"Videos","summary":"","title":"Proxmox Backup Server: A Game Changer for HomeLabs!","type":"videos"},{"content":" This video dives deep into Docker Swarm Mode, explaining why it\u0026rsquo;s a powerful and often misunderstood container orchestration tool for those seeking a middle ground between simple Docker setups and complex Kubernetes deployments. I\u0026rsquo;ll guide you through setting up a Swarm cluster, deploying services with Docker Compose, and leveraging crucial features like secrets, configs, and overlay networks to build robust and scalable applications.\nReferences # Docker Tutorial: https://www.youtube.com/watch?v=Nm1tfmZDqo8 Docker Volumes (NFS): https://www.youtube.com/watch?v=eKAQiYu4NyI Notes # What is Docker Swarm Mode? # Docker Swarm Mode is an integrated feature of the Docker Engine that allows you to create and manage a cluster of Docker nodes, orchestrating containers with built-in fault-tolerance, load-balancing, and rolling updates. It\u0026rsquo;s an excellent choice for HomeLab users or smaller teams looking for container orchestration without the complexity of Kubernetes.\nBenefits of Docker Swarm # Built-in clustering and orchestration: Transforms multiple Docker Engines into a single, virtual Docker host. Service discovery and load balancing: Automatic DNS assignment for services and internal load balancing. High availability and fault tolerance: Automatically reschedules failed tasks on healthy nodes. Security by default: Secure node-to-node communication with mutual TLS encryption and integrated secrets management. Rolling updates and rollbacks: Supports declarative updates to services with easy rollback capabilities. Intelligent scheduling: Optimizes cluster resource use and resilience based on resource availability and constraints. Why choose Docker Swarm over Kubernetes? # Docker Swarm offers a simpler setup and ease of use, making it accessible for projects that need straightforward container orchestration. Its seamless integration with Docker, using the same CLI and API, allows teams familiar with Docker to scale from single-node to multi-node clusters without learning new tools.\nbash sudo docker swarm init \u0026ndash;advertise-addr bash docker swarm join \u0026ndash;token :2377 bash # On the Leader sudo docker node ls # Promote workers to leaders sudo docker node promote sudo docker node promote How to set up Docker Swarm # To initialize a Swarm on your leader node:\nsudo docker swarm init --advertise-addr \u0026lt;VM1-IP-address\u0026gt; To join worker nodes to the Swarm:\ndocker swarm join --token \u0026lt;token\u0026gt; \u0026lt;VM1-IP-address\u0026gt;:2377 Verify your nodes and promote workers to managers (optional for high availability):\n# On the Leader sudo docker node ls # Promote workers to leaders sudo docker node promote \u0026lt;VM2\u0026gt; sudo docker node promote \u0026lt;VM3\u0026gt; Create Docker Services # You can create individual services directly via the Docker CLI. Here\u0026rsquo;s an example for an Nginx service:\ndocker service create \\ --name nginx-service-1 \\ --publish 8081:80 \\ --replicas 2 \\ nginx:latest To inspect services and their running tasks:\ndocker service ls docker service ps nginx-service-1 For updates and rollbacks:\ndocker service update --image nginx:1.29.1 nginx-service-1 docker service rollback nginx-service-1 Create Services from a Compose File # Docker Compose files can be used in Swarm Mode to manage services as stacks. Remember to adjust your Compose file for Swarm deployment:\nservices: nginx: image: docker.io/library/nginx:1.28.0-alpine # Remove \u0026#39;container_name\u0026#39; as Swarm manages container naming # container_name: nginx deploy: replicas: 1 # (OPTIONAL) Add constraints to run this service on specific nodes placement: constraints: - node.hostname != vm-test-3 ports: - \u0026#34;8082:80\u0026#34; # Remove \u0026#39;restart\u0026#39; policies as Swarm handles service restarts # restart: unless-stopped Deploy or update your stack:\ndocker stack deploy -c compose.yaml nginx-service-2 Check your deployed stacks and their services:\ndocker stack ls docker stack ps nginx-service-2 Swarm Mode vs. Standalone Containers # When Swarm Mode is enabled, existing standalone containers and Docker Compose stacks (not deployed as Swarm stacks) will continue to run unaffected. They do not automatically become part of the Swarm cluster.\nDocker Volumes in Swarm Mode # By default, volumes are local to each node and are not automatically shared across the Swarm. This means if a task reschedules to another node, its data won\u0026rsquo;t follow. To address this, consider using shared storage solutions or Docker Storage Drivers. Refer to my video on Docker Volumes using NFS for a practical solution.\nbash docker network create \\ \u0026ndash;driver overlay \\ \u0026ndash;attachable \\ # This enables IPsec encryption, which might incur a performance penalty. Test before production. \u0026ndash;opt encrypted \\ proxy\nOverlay Networks # Overlay networks provide a distributed network across all Docker Swarm nodes, allowing services to communicate seamlessly. You can also make them attachable for standalone containers.\ndocker network create \\ --driver overlay \\ --attachable \\ # This enables IPsec encryption, which might incur a performance penalty. Test before production. --opt encrypted \\ proxy Docker Secrets and Configs # Swarm Mode offers built-in management for sensitive data and configuration files, enhancing security and simplifying deployment.\nDocker Secrets # Docker Secrets allow you to securely store and transmit sensitive information (like API tokens, passwords, or certificates) only to the containers that need them.\nTo create a secret:\necho \u0026#34;*****\u0026#34; | docker secret create api_token - Integrate secrets into your Compose file:\nservices: secret_demo: image: ubuntu:latest deploy: mode: replicated replicas: 1 secrets: - api_token environment: - TARGET_API_TOKEN_FILE=/run/secrets/api_token secrets: api_token: external: true docker config create my_config my_config.yaml Integrate configs into your Compose file:\n... configs: - source: my_config target: /etc/myapp/config.yaml ... configs: my_config: external: true Docker Configs # Docker Configs help you manage non-sensitive configuration files centrally, making them available to your services.\nTo create a config from a file (e.g., my_config.yaml):\ndocker config create my_config my_config.yaml Integrate configs into your Compose file:\n... configs: - source: my_config target: /etc/myapp/config.yaml ... configs: my_config: external: true ","date":"12 September 2025","externalUrl":null,"permalink":"/videos/docker-swarm/","section":"Videos","summary":"","title":"Docker Swarm Mode: EASY Tutorial","type":"videos"},{"content":" Check out Twingate and supercharge your security: https://bit.ly/3Y1OaZi\nIn this video, I guide you through structuring your HomeLab network for better security, scalability, and ease of management. Whether you\u0026rsquo;re just starting or looking to optimize an existing setup, you\u0026rsquo;ll find practical examples and tips on network topology, segmentation, VLANs, and IP range management to build a robust and well-organized network.\nReferences # Excalidraw Tutorial: https://youtu.be/Gv9MezPAchI?si=2T1f9uC9gnN7adAe OPNSense Tutorial: https://youtu.be/BsNmzHcK2r4?si=knBhBIAPL69_EuRT Twingate Tutorial: https://youtu.be/iKq15WXdN88?si=2Lt90UvRYASkyjVP BIND9 DNS Tutorial: https://www.youtube.com/watch?v=syzwLwE3Xq4 Notes # Network Diagram Best Practices # Documenting your network structure is crucial for understanding your setup, identifying security gaps, and planning future expansions. Tools like Excalidraw are highly recommended for this. Start simple and incrementally improve your diagram as your HomeLab grows.\nNetwork Zones and Segmentation # Network Zones are logical groupings of network interfaces or devices. They are fundamental for applying specific security policies, configurations, and access controls within your HomeLab.\nHere\u0026rsquo;s my HomeLab Zone Configuration:\nZone Name Purpose / Description Subnet WAN Wide Area Network; represents the connection to the public internet through my home router. 192.168.81.0/24 LAN Local Area Network; my primary private network for general devices. 10.10.0.0/16 PROD Production Zone; dedicated to my critical HomeLab servers and services. 10.20.0.0/16 DMZ Demilitarized Zone; for publicly accessible servers, isolated from my internal network for enhanced security. 10.30.0.0/16 Tip: You can use the ipcalc command-line utility to understand subnet ranges and available host addresses:\nipcalc 192.168.81.0/24 # The /24 (CIDR notation) means the first 24 bits of the IP address # are used for the network portion, leaving 8 bits for host addresses. # This results in 254 usable host addresses (from 192.168.0.1 to 192.168.0.254). ipcalc 10.20.0.0/16 # The /16 (CIDR notation) means the first 16 bits are for the network. VLANs (Virtual Local Area Networks) # VLANs enable you to segment a single physical switch into multiple virtual switches, saving hardware costs and enhancing network security by isolating traffic. Devices on Untagged Ports in different VLANs cannot directly communicate with each other; traffic must pass through a router or firewall.\nUntagged Ports: These ports are assigned to a single VLAN. Network packets are sent normally, and devices connected to these ports can only communicate with other devices in the same VLAN. Tagged Ports: These ports are used to transport traffic for multiple VLANs (often called \u0026ldquo;trunk ports\u0026rdquo;). A small 12-bit VLAN Identifier (tag) is added to each network packet, allowing the receiving device (e.g., a firewall or another switch) to identify which VLAN the packet belongs to. DHCP and IP Range Management # The Dynamic Host Configuration Protocol (DHCP) automatically assigns IP addresses and other network configuration parameters to devices.\nCommon Problem: IP address conflicts can occur if a DHCP server assigns an address that is already statically assigned to another device, especially if the static IP device was offline during the DHCP assignment. Best Practice: To avoid conflicts and improve organization, always create separate IP ranges within your subnets for DHCP-assigned addresses and static IP addresses.\nExample for a /24 subnet (e.g., 192.168.0.0/24):\nStatic IP Range: 192.168.0.1-20 (for servers, network devices, etc.) DHCP Pool: 192.168.0.21-199 (for client devices, temporary connections) Static DHCP Mappings: For devices that need a consistent IP but you prefer to manage through DHCP (e.g., a specific desktop), you can create a static DHCP mapping. This assigns a specific IP address to a device\u0026rsquo;s unique MAC address, ensuring it always receives the same IP from the DHCP server, outside the regular dynamic pool.\n","date":"9 September 2025","externalUrl":null,"permalink":"/videos/network-planning/","section":"Videos","summary":"","title":"How to structure your HomeLab network?","type":"videos"},{"content":" Boost your productivity and organize your tasks and projects with Akiflow: https://akiflow.pro/ChristianLempa\nIn this video, I guide you through building your own HomeLab firewall using the powerful, free, and open-source OPNsense software on a compact Mini-PC. Discover how to install and configure OPNsense, address common driver issues, and set up your network interfaces for a robust and secure home network. Join me as I share my experience and initial setup steps to get you started with this versatile firewall solution.\nReferences # OPNsense Official Website \u0026amp; Download: https://opnsense.org OPNsense Packages: https://pkg.opnsense.org/ My OPNsense Hardware Kit: https://kit.co/christianlempa/my-opnsense-firewall Notes # Why choose OPNsense for your HomeLab? # OPNsense is a free and open-source firewall solution offering extensive features for home network protection. It supports basic routing (DNS, DHCP, VLANs), advanced security (VPN, IDS, IPS, Firewall Rules), and offers greater control over software, plugins, and features, including API and Terraform management, compared to many commercial alternatives. It\u0026rsquo;s an excellent choice for those looking to tinker and build a robust, custom firewall system.\nHardware Considerations for OPNsense # OPNsense is highly flexible regarding hardware, supporting mini PCs, professional appliances, virtual machines, or even old computers. The most crucial hardware requirement is having at least two physical network interfaces: one for the Local Area Network (LAN) to connect your HomeLab switch and one for the Wide Area Network (WAN) to connect to your modem or public internet.\nMy Hardware Setup: MinisForum MS-A1 # For this setup, I used the MinisForum MS-A1 bare-bone mini PC, which allows for custom CPU and memory selection.\nCPU: AMD Ryzen 5 8500G (6 cores, 12 threads, integrated GPU) – chosen for its efficiency. RAM: 16 GB (2x 8 GB Crucial modules). Storage: 1 TB NVMe drive. This configuration provides ample resources for a powerful firewall system and is highly expandable, featuring two 2.5 Gigabit Ethernet ports, excellent cooling, 4x M.2 slots, and fast USB4 ports. Other suitable mini PC brands include Geekom and Zima, but always ensure they have at least two physical network interfaces. OPNsense Installation Process # Download the Full Image: For most regular computer installations, download the VGA image type for USB drives from the OPNsense download page. Avoid the embedded image unless specific conditions apply. Create a Bootable USB Drive: Use tools like Balena Etcher to flash the OPNsense image to a USB stick. Boot and Install: Boot your PC from the USB drive. OPNsense will load into a live environment, allowing you to explore its features without making permanent changes. To install, log in with the username installer and the password opnsense. This will launch a guided installation wizard. Filesystem Choice: The OPNsense documentation recommends ZFS in most cases for its reliability and redundancy capabilities (especially with multiple drives). Disk Selection: Be cautious, as installing OPNsense will erase all data on the selected disk. Post-Installation: After the installation completes and the system reboots, you\u0026rsquo;ll be presented with the OPNsense console, a basic administrative menu. The main configuration is done via the web interface after network setup. Solving Realtek 2.5 Gigabit Network Driver Issues # A common issue with some hardware, like the MinisForum MS-A1, is that OPNsense may not load Realtek 2.5 Gigabit network drivers by default, preventing network interface detection. If you can\u0026rsquo;t access the web interface, you\u0026rsquo;ll need to install these drivers via the OPNsense shell:\nSteps to Install Drivers via Shell: # Download Packages: From pkg.opnsense.org, navigate to the latest FreeBSD version for OPNsense and download the os-realtek-re package and its dependency, realtek-re-kmod. Place these on a separate USB stick. Identify USB Stick: On the OPNsense console, use the command camcontrol devlist to identify your USB stick\u0026rsquo;s device name (e.g., da0p1). Install Packages: Create a mount point: mkdir /mnt/usb Mount the USB stick: mount -t msdosfs /dev/da0p1 /mnt/usb (replace da0p1 with your device name if different) Install the dependency first: pkg add /mnt/usb/realtek-re-kmod.pkg Then install the main package: pkg add /mnt/usb/os-realtek-re.pkg Reboot: After installation, reboot the system for the drivers to be loaded correctly. Initial Network Interface Configuration # After drivers are installed and interfaces are detected, configure your network:\nWAN Interface: Configure for DHCP to obtain an IP address from your existing home router, granting internet access. LAN Interface: Assign a static IPv4 address. This interface will act as the gateway for your HomeLab. DHCP Server: Enable the DHCP server on your LAN interface to automatically assign IP addresses to devices connected to your HomeLab network. VLANs (Optional): If you use VLANs, you can set them up at this stage. Important: Ensure your LAN subnet is different from your WAN subnet to prevent conflicts. Once the basic network configuration is complete, OPNsense will provide the URL to access its main web interface, where all further advanced configurations are performed.\nKey OPNsense Web Interface Configuration Areas # Once logged into the OPNsense web interface, explore these critical sections:\nSystem: For general settings, access control, user management, firmware updates, and logs. System → Settings → General (hostname, domain, theme) Gateways → Configuration Interfaces: To manage and configure your network interfaces, including VLANs, assignments, and specific settings for WAN and LAN. Interfaces → Devices → VLANs Interfaces → Devices → Assignments Interfaces → WAN Interfaces → LAN Services: To configure essential network services. Services → ISC DHCPv4 (for your DHCP server) Services → Unbound DNS → General \u0026amp; Query Forwarding (for DNS resolution) Firewall: To define and manage your network\u0026rsquo;s security rules. Firewall → NAT → Outbound Firewall → Rules → LAN ","date":"29 August 2025","externalUrl":null,"permalink":"/videos/opnsense-tutorial/","section":"Videos","summary":"","title":"Build your own HomeLab Firewall! // OPNSense Tutorial","type":"videos"},{"content":" This video shows how I built a Kestra automation that turns a Notion \u0026ldquo;Published\u0026rdquo; entry into a Hugo markdown post, downloads the thumbnail, and creates a GitLab merge request so my static site (Cloudflare Workers) can publish the new video — all without manual edits to the site. I walk through the webhook trigger, parsing Notion data in Kestra, the Python template script, thumbnail download, and the Docker-based merge-request workflow with glab.\nReferences # Kestra: https://kestra.io Kestra Documentation: https://kestra.io/docs My Kestra Tutorial 1: https://youtu.be/D4cixQ_Ek4Y?si=phFx71A9Bigxe8kJ My Kestra Tutorial 2: https://youtu.be/PJG1-7hMHsE?si=JI_Zd3vejAlPAiil My Hugo Tutorial: https://youtu.be/MX4yy1dTVYg?si=3pwfNIGzm5nc_4Tv My Cloudflare Workers Tutorial: https://youtu.be/FZMgUSlNp-0?si=wQPZpD5fgR59Dzio Notes # Important Kestra tips # Use the Webhook trigger key/secret in the URL path: https://\u0026lt;your-kestra-host\u0026gt;/api/hooks/flows/\u0026lt;namespace\u0026gt;/\u0026lt;flowId\u0026gt;/\u0026lt;secret\u0026gt; Store parsed webhook fields in OutputValues to pass structured variables between tasks. Use the WorkingDirectoy task to keep a single temporary folder across tasks so the cloned repo and generated files are available for subsequent steps. Use the Files (namespace files) tab in Kestra Web UI to bundle scripts and other files with your flow; access them via includes. Task runner choices # Process Runner: runs shell/python directly on the Kestra host (faster; relies on host packages). Good for simple scripts when required tools are already installed. Docker Task Runner: run in a container (isolated, reproducible). I use Docker for the glab CLI step because it simplifies dependencies and authentication. ","date":"15 August 2025","externalUrl":null,"permalink":"/videos/kestra-tutorial-3/","section":"Videos","summary":"","title":"Self-hosted Automation for Git, Webhooks, and more // Kestra #3","type":"videos"},{"content":" In this video, we\u0026rsquo;re diving into Proxmox Linux Containers (LXC)! While Docker has been a popular choice, LXC offers a powerful and often overlooked alternative for creating isolated environments without the overhead of a full-blown operating system. Furthermore, we also cover how to simplify LXC deployment with scripts or infrastructure as code tools like Terraform.\nReferences # Proxmox VE Helper Scripts: https://community-scripts.github.io/ProxmoxVE/ Telmate Terraform Provider: https://registry.terraform.io/providers/Telmate/proxmox/latest/docs Ollama in LXC Tutorial: https://youtu.be/RQFfK7xIL28 ","date":"28 July 2025","externalUrl":null,"permalink":"/videos/proxmox-lxc-tutorial/","section":"Videos","summary":"","title":"The BEST alternative to Docker and VMs! // Proxmox LXC","type":"videos"},{"content":" In this video, we\u0026rsquo;re diving into the latest version 5.3 of the open-source password manager Passbolt! This update brings exciting new features like encrypted metadata, custom fields, icons, and multiple URIs, making it even more secure and customizable for both home and enterprise environments. Join me as we explore these improvements and discuss why Passbolt remains a compelling option for those seeking a privacy-focused password manager.\nReferences\nPassbolt Tutorial: https://christianlempa.de/videos/passbolt-tutorial/ Passbolt Encrypted Metadata Blogpost: https://www.passbolt.com/blog/the-road-to-passbolt-v5-encrypted-metadata-and-other-core-security-changes-2 ","date":"23 July 2025","externalUrl":null,"permalink":"/videos/passbolt-tutorial-3/","section":"Videos","summary":"","title":"Passbolt 5 (Self-Hosted Password Manager) got revamped!","type":"videos"},{"content":" In this video we will explore how to deploy a static website built with Hugo to Cloudflare Workers. We\u0026rsquo;ll cover automating the build and publishing process using a Git mirror and Wrangler, allowing for seamless updates from your self-hosted GitLab instance. This tutorial provides a robust, flexible, and powerful way to host web content with incredible speed and scalability, all without managing servers yourself!\nReferences\nMy new Website: https://christianlempa.de Hugo Tutorial: https://www.youtube.com/watch?v=MX4yy1dTVYg Cloudflare Workers Docs: https://developers.cloudflare.com/workers/ GitLab Repository Mirroring Docs: https://docs.gitlab.com/user/project/repository/mirror/ ","date":"18 July 2025","externalUrl":null,"permalink":"/videos/cloudflare-workers/","section":"Videos","summary":"","title":"Publish a Static Hugo Website the EASY way // Cloudflare Workers","type":"videos"},{"content":"","date":"13 July 2025","externalUrl":null,"permalink":"/tags/devops/","section":"Tags","summary":"","title":"Devops","type":"tags"},{"content":" In this video, I explore the powerful AI features of Warp, demonstrating how it automates tasks, deploys applications, and even writes code fully autonomously. I explain how Warp AI generated new Python functions and built new Docker containers for a Raspberry Pi project, and how to save prompts in Warp Drive. Warp AI is even included in the FREE Plan (no signup required) with some tokens for testing—check it out and experience how it transforms your terminal workflow!\nReferences\nWarp Tutorial: https://youtu.be/NfggT5enF4o ","date":"13 July 2025","externalUrl":null,"permalink":"/videos/warp-tutorial-3/","section":"Videos","summary":"","title":"DevOps Engineer NEED to Use This! // Warp","type":"videos"},{"content":"","date":"13 July 2025","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"13 July 2025","externalUrl":null,"permalink":"/tags/tools/","section":"Tags","summary":"","title":"Tools","type":"tags"},{"content":"","date":"8 July 2025","externalUrl":null,"permalink":"/tags/docker/","section":"Tags","summary":"","title":"Docker","type":"tags"},{"content":" Check out Kestra: https://go.kestra.io/Christian\nIn this video we will explore Grafana Alloy, the new Swiss Army Knife for logs and metrics monitoring. We’ll cover replacing tools like Promtail and how Alloy centralizes telemetry collection and processing. We’ll walk through configuring Alloy for Linux, Docker containers, and sending data to Loki and Prometheus, simplifying your HomeLab setup.\nReferences\nGrafana Alloy: https://grafana.com/docs/alloy/latest/ Grafana Scenarios: https://github.com/grafana/alloy-scenarios My Boilerplates: http://github.com/christianlempa/boilerplates Kestra Tutorial 1: https://youtu.be/D4cixQ_Ek4Y Kestra Tutorial 2: https://youtu.be/PJG1-7hMHsE ","date":"8 July 2025","externalUrl":null,"permalink":"/videos/grafana-alloy/","section":"Videos","summary":"","title":"Grafana Alloy, NEW log + metric collector replaces everything!","type":"videos"},{"content":"","date":"8 July 2025","externalUrl":null,"permalink":"/tags/linux/","section":"Tags","summary":"","title":"Linux","type":"tags"},{"content":"","date":"8 July 2025","externalUrl":null,"permalink":"/tags/monitoring/","section":"Tags","summary":"","title":"Monitoring","type":"tags"},{"content":"","date":"30 June 2025","externalUrl":null,"permalink":"/tags/ansible/","section":"Tags","summary":"","title":"Ansible","type":"tags"},{"content":" In this video we will show you how to automate Checkmk using Ansible. We’ll cover installing and configuring Checkmk with Ansible, adding hosts and services automatically, and managing rules to tailor your monitoring setup. This tutorial provides a complete guide to automating your Checkmk environment for scalability and efficiency.\nReferences\nCheckmk Ansible Collection: https://github.com/Checkmk/ansible-collection-checkmk.general Checkmk Knowledge Base: https://checkmk.atlassian.net/wiki/x/eoiQ My Templates: https://github.com/christianlempa/boilerplates Checkmk Tutorial Video: https://youtu.be/Rb1_7gbgS7k Ansible Tutorial Video: https://youtu.be/uR1_hlHxvhc ","date":"30 June 2025","externalUrl":null,"permalink":"/videos/checkmk-ansible/","section":"Videos","summary":"","title":"Manage Checkmk IT monitoring in Ansible","type":"videos"},{"content":" Check out Twingate and supercharge your security: https://bit.ly/3Y1OaZi\nIn this video, I\u0026rsquo;ll be showing you the new website I\u0026rsquo;m building for my YouTube channel. I\u0026rsquo;m moving away from traditional website CMS like WordPress and exploring a simpler, faster approach using static websites. We’ll be building a demo website using the Hugo Framework, and I’ll guide you through the basics so you can easily create your own beautiful and fast websites. No HTML or CSS expertise is required – we\u0026rsquo;re just using simple Markdown files!\nReferences\nHugo Static Website Framework: https://gohugo.io Blowfish Theme: https://blowfish.page ","date":"24 June 2025","externalUrl":null,"permalink":"/videos/hugo-tutorial/","section":"Videos","summary":"","title":"Building a static website in Markdown with Hugo","type":"videos"},{"content":"","date":"10 June 2025","externalUrl":null,"permalink":"/tags/automation/","section":"Tags","summary":"","title":"Automation","type":"tags"},{"content":"","date":"10 June 2025","externalUrl":null,"permalink":"/tags/gitlab/","section":"Tags","summary":"","title":"Gitlab","type":"tags"},{"content":" Check out Kestra: https://go.kestra.io/Christian\nIn this video we will show you how to simplify your CI/CD pipelines in GitLab using reusable components, a powerful feature introduced in version 17. Learn how to create dynamic, shareable jobs for tasks like Terraform infrastructure management or Docker deployments, and streamline updates across multiple projects. We also briefly introduce Kestra, an open-source workflow orchestrator with extensive plugin support. Whether you\u0026rsquo;re automating DevOps workflows or exploring new tools, this video provides practical insights to enhance your IT automation skills.\nReferences\nGitLab Docs: https://docs.gitlab.com/ci/components/ My Templates: https://github.com/christianlempa/boilerplates GitLab CI / CD Basics: https://youtu.be/qoqtSihN1kU GitLab Terraform Backend: https://youtu.be/X-Amz-Hdy8Q Kestra Tutorial 1: https://youtu.be/D4cixQ_Ek4Y Kestra Tutorial 2: https://youtu.be/PJG1-7hMHsE ","date":"10 June 2025","externalUrl":null,"permalink":"/videos/gitlab-ci-components/","section":"Videos","summary":"","title":"NEW GitLab CI CD components explained","type":"videos"},{"content":" Get started with Notion AI at → https://ntn.so/christianlempa\nEver feel overwhelmed by your tech projects? I do! In this video, I\u0026rsquo;m opening up my Notion workspace to show you exactly how I organize everything - my HomeLab projects, documentation and tasks. Learn how I keep my technical chaos under control and get inspired to optimize your own workflow.\nReferences\nWhy I switched from Obsidian to Notion: https://youtu.be/RXYbkzadwxA?si=fTBIc7WOqlY09zVc ","date":"29 May 2025","externalUrl":null,"permalink":"/videos/notion-tutorial/","section":"Videos","summary":"","title":"Tech project management and documentation in Notion","type":"videos"},{"content":" Ever wondered how I create those hand-drawn visuals you see in my videos? In this video, I\u0026rsquo;ll show you Excalidraw – my absolute favorite whiteboard app. Learn how to create stunning, hand-drawn graphics, quickly visualize ideas, and even build technical diagrams and presentations – all without needing a tablet or pen! It\u0026rsquo;s free, open-source, and works right in your browser (or you can run it locally!). Let’s dive in and unlock your creative potential with Excalidraw!\n","date":"21 May 2025","externalUrl":null,"permalink":"/videos/excalidraw-tutorial/","section":"Videos","summary":"","title":"Excalidraw, my favorite whiteboard / tech diagram app","type":"videos"},{"content":"","date":"25 April 2025","externalUrl":null,"permalink":"/tags/homelab/","section":"Tags","summary":"","title":"Homelab","type":"tags"},{"content":" Project Management made easy! Monday.com: https://bit.ly/4iMXbi0\nFollowing up on my previous HomeLab tour, I\u0026rsquo;m taking you on a deep dive into the applications and software powering my setup! Get a comprehensive overview of the tech I\u0026rsquo;m using, categorized by environment – from operating systems and container orchestration (Docker, Kubernetes) to IoT, network management, AI, automation tools, and much more. See how I\u0026rsquo;m building out my HomeLab and discover the tools and platforms that make it all work. Let’s explore the stack together!\nReferences\nHomeLab Tour 2025: https://youtu.be/4QlawuxRY00 ","date":"25 April 2025","externalUrl":null,"permalink":"/videos/homelab-stack-2025/","section":"Videos","summary":"","title":"What software runs in my HomeLab in 2025?","type":"videos"},{"content":"","date":"23 April 2025","externalUrl":null,"permalink":"/tags/hardware/","section":"Tags","summary":"","title":"Hardware","type":"tags"},{"content":" Ever wondered how I create those hand-drawn visuals you see in my videos? In this video, I\u0026rsquo;ll show you Excalidraw – my absolute favorite whiteboard app. Learn how to create stunning, hand-drawn graphics, quickly visualize ideas, and even build technical diagrams and presentations – all without needing a tablet or pen! It\u0026rsquo;s free, open-source, and works right in your browser (or you can run it locally!). Let’s dive in and unlock your creative potential with Excalidraw!\nResources # ","date":"23 April 2025","externalUrl":null,"permalink":"/videos/zimaboard-2/","section":"Videos","summary":"","title":"NEW ZimaBoard 2, super fast, tiny Home Server","type":"videos"},{"content":"","date":"23 April 2025","externalUrl":null,"permalink":"/tags/zimaboard/","section":"Tags","summary":"","title":"Zimaboard","type":"tags"},{"content":" Remotly: https://remotly.com/download?promo=ChristianLempa\nCurious about what\u0026rsquo;s running behind the scenes of my tech setup? I\u0026rsquo;m giving you a complete tour of my HomeLab – and a lot has changed since my last look!\nJoin me as I reveal the updated network architecture that connects everything, explore the server hardware I\u0026rsquo;ve chosen (and why!), and even get honest about the biggest challenges I\u0026rsquo;m facing. You’ll see what works well, what doesn\u0026rsquo;t, and my vision for future projects.\nIt\u0026rsquo;s not a perfect setup, and I\u0026rsquo;m sharing all the details – the successes, the struggles, and the plans for what’s next.\nSome of my recent projects\nAI Server Hardware: https://youtu.be/7opwGxhOsf0 AI Ollama + OpenWebUI: https://youtu.be/RQFfK7xIL28 Unraid Hardware Updates: https://youtu.be/xMHMkpA5XnM Unraid Server: https://youtu.be/HriJkdgNlKs Raspberry Pi Cluster: https://youtu.be/2cbniIZUpXM ","date":"9 April 2025","externalUrl":null,"permalink":"/videos/homelab-tour-2025/","section":"Videos","summary":"","title":"What hardware runs in my HomeLab in 2025?","type":"videos"},{"content":" Ready to level up your homelab? Check out Checkmk Raw with the link on my description: https://checkmk.io/download-raw\nIn this video, I’m diving deep into Checkmk, a powerful, free, and open-source IT monitoring tool running in my home lab.\nYou’ll see how Checkmk can monitor everything from your physical servers and network devices to virtual machines and even Docker containers – with automatic discovery and tons of customizable plugins. Get ready to see how to unlock the power of comprehensive monitoring and gain control of your entire setup!\nReferences\nTraefik Tutorial: https://youtu.be/-hfejNXqOzA?si=a0GQZL8Pm0drJzm7 ","date":"1 April 2025","externalUrl":null,"permalink":"/videos/checkmk-tutorial/","section":"Videos","summary":"","title":"Checkmk, self-hosted IT monitoring for just EVERYTHING!","type":"videos"},{"content":" Ready to level up your homelab? Check out Checkmk Raw with the link on my description: https://checkmk.io/download-raw\nIn this video, I\u0026rsquo;ll show you how I\u0026rsquo;m automating my home lab with GitLab CI-CD. This allows me to automate deployments and infrastructure provisioning, making my workflow more efficient. I\u0026rsquo;ll also share tips on setting up these tools for your own projects, highlighting the benefits of continuous integration and deployment.\nReferences\nGitLab Tutorial: https://youtu.be/qoqtSihN1kU?si=MvFbANt-bdGpDmcL GitLab Terraform: https://youtu.be/X-Amz-Hdy8Q?si=v5s6kU77I6uexay4 ","date":"25 March 2025","externalUrl":null,"permalink":"/videos/gitlab-ci/","section":"Videos","summary":"","title":"GitLab CI CD automation (Docker, Kubernetes, Terraform, and more…)","type":"videos"},{"content":" In this video, I\u0026rsquo;ll talk about the new hardware upgrades I’ve made to my home server. I needed to upgrade my secondary Proxmox node because of my new AI workloads. Of course, I\u0026rsquo;ll show you how I put everything together, including improvements to the network setup and a new rack server case.\n👇 My recommendations 👇\n✅ 30% OFF with promo-code FLYT30 on the best proxy service – FloppyData: https://bit.ly/floppydata_christian-lempa\n✅ 20% OFF with promo-code YTGL20 on the top multi-accounting browser – GoLogin: https://bit.ly/gologin_christian-lempa\nThese are the tools I trust—check them out! ❤️\nReferences\nAI Server Tutorial (Ollama OpenwebUI): https://youtu.be/RQFfK7xIL28?si=Pp4bveqFtHtt4yQW Hardware Parts\nmATX Homeserver Build: https://kit.co/christianlempa/matx-homeserver-build-minisforum-bd795m My favorite Rack Server Cases: https://kit.co/christianlempa/my-favorite-server-rack-cases My favorite Graphics Cards: https://kit.co/christianlempa/my-favorite-graphic-cards Fast Network Equipment: https://kit.co/christianlempa/fast-network-equipment ","date":"18 March 2025","externalUrl":null,"permalink":"/videos/homeserver-updates/","section":"Videos","summary":"","title":"My NEW Homeserver for AI + Power efficiency","type":"videos"},{"content":" In this Tutorial we set up a free and open-source password manager for your home labs, or professional it teams, such as DevOps, sysadmins, and so on. We will deploy Passbolt on a docker server and configure a mail server and trusted SSL certificates by using Traefik and Letsencrypt.\nInstall Passbolt in Docker # Create a new project directory, and a new compose.yaml file.\n--- services: db: image: library/mariadb:10.3 environment: - MYSQL_RANDOM_ROOT_PASSWORD=true - MYSQL_DATABASE=\u0026#34;passbolt\u0026#34; - MYSQL_USER=\u0026#34;passbolt\u0026#34; - MYSQL_PASSWORD=\u0026#34;P4ssb0lt\u0026#34; volumes: - database_volume:/var/lib/mysql restart: unless-stopped passbolt: image: passbolt/passbolt:latest-ce depends_on: - db ports: - \u0026#34;80:80\u0026#34; - \u0026#34;443:443\u0026#34; environment: - APP_FULL_BASE_URL=https://passbolt.home.arpa - DATASOURCES_DEFAULT_HOST=db - DATASOURCES_DEFAULT_USERNAME=\u0026#34;passbolt\u0026#34; - DATASOURCES_DEFAULT_PASSWORD=\u0026#34;P4ssb0lt\u0026#34; - DATASOURCES_DEFAULT_DATABASE=\u0026#34;passbolt\u0026#34; volumes: - gpg_volume:/etc/passbolt/gpg - jwt_volume:/etc/passbolt/jwt command: [\u0026#34;/usr/bin/wait-for.sh\u0026#34;, \u0026#34;-t\u0026#34;, \u0026#34;0\u0026#34;, \u0026#34;db:3306\u0026#34;, \u0026#34;--\u0026#34;, \u0026#34;/docker-entrypoint.sh\u0026#34;] restart: unless-stopped volumes: database_volume: gpg_volume: jwt_volume: Make sure replace the URL at the APP_FULL_BASE_URL. Change the MYSQL_*, and DATASOURCES_DEFAULT_* environment variables. (optional) Add the credentials to a .env file. Configure a mail server # Add the following environment variables to your compose.yaml file.\nenvironment: - EMAIL_TRANSPORT_DEFAULT_HOST=your-mail-server - EMAIL_TRANSPORT_DEFAULT_PORT=587 - EMAIL_TRANSPORT_DEFAULT_USERNAME=$EMAIL_TRANSPORT_DEFAULT_USERNAME - EMAIL_TRANSPORT_DEFAULT_PASSWORD=$EMAIL_TRANSPORT_DEFAULT_PASSWORD - EMAIL_TRANSPORT_DEFAULT_TLS=true - EMAIL_DEFAULT_FROM=no-reply@home.arpa Replace the variables with your email server config. (optional) Add the credentials to a .env file. Trusted SSL Certs with Traefik # If you\u0026rsquo;re using Traefik, you can remove the ports: section from your compose.yaml file and add the following labels to your compose.yaml file.\nlabels: - traefik.enable=true - traefik.http.services.passbolt.loadbalancer.server.port=80 - traefik.http.routers.passbolt.entrypoints=websecure - traefik.http.routers.passbolt.rule=Host(`passbolt.home.arpa`) - traefik.http.routers.passbolt.tls=true - traefik.http.routers.passbolt.tls.certresolver=cloudflare - traefik.http.routers.passbolt.service=passbolt Set up your first admin account # docker compose exec passbolt su -m -c \u0026#34;/usr/share/php/passbolt/bin/cake \\ passbolt register_user \\ -u YOUR_EMAIL \\ -f YOUR_NAME \\ -l YOUR_LASTNAME \\ -r admin\u0026#34; -s /bin/sh www-data Log in via one of the supported Browsers, by accessing the https://passbolt.home.arpa URL.\nCongratulations, you\u0026rsquo;re now ready to use Passbolt!\n","date":"6 December 2022","externalUrl":null,"permalink":"/videos/passbolt-tutorial/","section":"Videos","summary":"","title":"Self hosted, open source password manager built for teams!","type":"videos"},{"content":" Hey, there I’m Christian, and I’m passionate about creating educational tech content for IT Pros and Homelab nerds. Through my YouTube channel, I’m sharing engaging videos, tutorials, and write-ups that make complex topics easy to understand. Whether you\u0026rsquo;re a tech enthusiast or just someone curious about IT, my content offers valuable insights and practical knowledge.\nWhy am I doing all this? Because I just have a genuine love for IT and sharing my knowledge with others. I believe that by presenting what I\u0026rsquo;ve learned, I can inspire people to explore and experiment with technology themselves.\nMeet our Community # Because I believe in the power of connection and collaboration, I’ve created a tech community on Discord. It\u0026rsquo;s a fantastic place to connect with other IT professionals, tech enthusiasts and others who share your passion.\nJoin the Discord Community Support me and make a difference # Creating high-quality videos and valuable resources that are accessible to everyone, free of charge, is a huge challenge. With your contribution, I can dedicate more time and effort into the creation process, which ultimately enhances the quality of the content. So, all your support, by becoming a member, truly makes a significant impact on what I do. And you’ll also get some cool benefits and perks in return, as a recognition of your support.\nRemember, supporting me is entirely optional. Your choice to become a member or not won\u0026rsquo;t change your access to my videos and resources. You are also welcome to reach out to me on Discord, if you have any questions or feedback.\nBecome a YouTube Member ","externalUrl":null,"permalink":"/about/","section":"Christian Lempa","summary":"","title":"About Me","type":"page"},{"content":"","externalUrl":null,"permalink":"/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":"","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"CL Creative - Christian Lempa\nc/o Block Services\nStuttgarter Str. 106\n70736 Fellbach\nContact: info(at)clcreative(dot)de\nWe are committed to protecting your privacy. Please refer to our Privacy Policy for information on how we collect, use, and share your personal data.\nCopyright © 2025 Christian Lempa. All rights reserved.\n","externalUrl":null,"permalink":"/impressum/","section":"Christian Lempa","summary":"","title":"Legal Notice (Impressum)","type":"page"},{"content":" 1. Introduction # This Privacy Policy explains how Christian Lempa (hereinafter referred to as “the Website”) processes personal data. The Website is operated by CL Creative.\n2. What Data We Collect # The Website collects the following data:\nIP Address: Your IP address is automatically recorded each time you visit the Website Request Data: Data you submit when using the Website, such as through forms or search boxes 3. How We Use Your Data # We use your data for the following purposes:\nTo ensure the proper functioning of the Website. To analyze website traffic and user behavior (using anonymized data). To respond to your inquiries. 4. Data Retention # We retain your data as long as necessary to fulfill the purposes outlined in this policy.\n5. Data Sharing # We may share your data with:\nCloudflare: As a CDN and security provider, Cloudflare processes traffic data. 6. Your Rights # You have the following rights regarding your data:\nRight of access Right to rectification Right to erasure (“right to be forgotten”) Right to restriction of processing Right to data portability 7. Contact Information # If you have any questions or concerns about our privacy policy, please contact us at: info(at)clcreative(dot)de\n","externalUrl":null,"permalink":"/privacy/","section":"Christian Lempa","summary":"","title":"Privacy Policy","type":"page"},{"content":" These resources serve as valuable references that complement the information in my videos. You\u0026rsquo;ll find helpful example code snippets, templates, and more to support your learning process.\nMy GitHub Repositories # Boilerplates # ChristianLempa/boilerplates Create reusable templates and turn them into configurable workloads for homelabs and self-hosted infrastructure. Free and Open-Source. Python 7837 1831 Cheat-Sheets # ChristianLempa/cheat-sheets This is my personal knowledge-base. Here you\u0026rsquo;ll find code-snippets, technical documentation, and command reference for various tools, and technologies. null 4775 1446 Dotfiles # ChristianLempa/dotfiles This contain my personal config files. Here you\u0026rsquo;ll find configs, customizations, themes, and whatever I need to personalize my Linux and mac OS experience. Shell 1143 324 ","externalUrl":null,"permalink":"/resources/","section":"Christian Lempa","summary":"","title":"Resources","type":"page"},{"content":"","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"}]