Restructured Documentation
Automatic Documentation Deployment / Sync Docs to https://kb.bunny-lab.io (push) Successful in 8s

This commit is contained in:
2026-09-05 14:08:43 -06:00
parent c4bd235eba
commit 289769a601
281 changed files with 5403 additions and 3563 deletions
+6 -16
View File
@@ -1,26 +1,16 @@
---
tags:
- Blog
- Index
- Documentation
---
# Blog
## Purpose
Narrative posts for lessons learned, experiments, and updates.
Read the dated experiments and lessons behind changes in the lab. Follow the linked operational pages when you need the reusable configuration or procedure.
## New Post Template
````markdown
# <Post Title>
## Context
<why this mattered>
## Includes
- Posts
## What Changed
- <key actions or decisions>
## Results
- <what worked / what failed>
## Lessons Learned
- <what you would do differently next time>
````
## Follow the Experiments
- [Gitea Runners](<posts/05-16-2025 Learning to Leverage Gitea Runners.md>) — Read the configuration-delivery experiment and continue to the extracted runner procedures.
- [OpenStack](<posts/12-15-2024 OpenStack Frustrations.md>) — Read the context behind the separate OpenStack deployment attempts.
@@ -1,5 +1,5 @@
---
draft: false
draft: false
date: 2025-01-22
updated: 2025-01-22
authors:
@@ -20,12 +20,15 @@ So I've been noticing a trend recently regarding something I never really took m
## Overview of the Problem
The general idea is that Windows devices (Workstations & Servers) have what are called power "**profiles**". These profiles, by default, are set to "**Balanced**". Which in basic terms means that the operating system will artificially limit the CPU speed to below 2.0GHz at all times. This means if the CPU is capable of 4GHz, it will be limited to 2GHz no-matter-what. This is a huge problem since it leaves performance just sitting on the table.
## Observations & Actions Taken
When I learned of the above, I began to audit every Windows-based server and workstation (Physical and Virtual) in my homelab. The virtual machines seemed unaffected by this issue, but I still configured them to "**High Performance**" power profiles regardless. However, every single physical host (`VIRT-NODE-01`, `VIRT-NODE-02`, and `LAB-DRAAS-01`), all saw notable performance improvements ranging from 32% to 41%, on average going from 1.75GHz to 2.6GHz on the virtualization hosts, and 1.9GHz to 3.2GHz on the backup server.
## Observations and Actions Taken
When I learned of the above, I began to audit every Windows-based server and workstation (Physical and Virtual) in my homelab. The virtual machines seemed unaffected by this issue, but I still configured them to "**High Performance**" power profiles regardless. However, every single physical host (`VIRT-NODE-01`, `VIRT-NODE-02`, and `LAB-DRAAS-01`), all saw notable performance improvements ranging from 32% to 41%, on average going from 1.75GHz to 2.6GHz on the virtualization hosts, and 1.9GHz to 3.2GHz on the backup server.
## Final Thoughts
I am so upset that for so many years, it never occured to me that the power profiles applied to server operating systems. I always just *assumed* they ran in "**High Performance**" power profiles all the time. I discovered I had non-trivial amounts of performance loss because of this simple checkbox setting in the OS.
I am so upset that for so many years, it never occured to me that the power profiles applied to server operating systems. I always just *assumed* they ran in "**High Performance**" power profiles all the time. I discovered I had non-trivial amounts of performance loss because of this simple checkbox setting in the OS.
!!! success "Performance Improvements"
The two Hyper-V Failover Cluster hosts saw a **32%** performance improvement (**1.75GHz to 2.6GHz**), while the Veeam Backup & Replication Server host observed a whopping **42%** performance improvement (**1.9GHz to 3.2GHz**).
The two Hyper-V Failover Cluster hosts saw a **32%** performance improvement (**1.75GHz to 2.6GHz**), while the Veeam Backup & Replication Server host observed a whopping **42%** performance improvement (**1.9GHz to 3.2GHz**).
## Related Documentation
- [Windows and Linux Administration](<../../reference/Windows and Linux/index.md>) — Find the operating-system procedures related to this performance observation.
- [Virtualization and Storage](<../../reference/Virtualization and Storage/index.md>) — Find the host and guest documentation for the environment being tuned.
@@ -1,7 +1,7 @@
---
draft: false
draft: false
date: 2025-05-16
updated: 2025-05-16
updated: 2026-09-05
authors:
- nicole
categories:
@@ -15,7 +15,7 @@ tags:
---
# Learning to Leverage Gitea Runners
When I first started my journey with a GitOps mentality to transition a portion of my homelab's infrastructure to an "**Intrastructure-as-Code**" structure, I had made my own self-made Docker container that I called the [Git-Repo-Updater](../../deployments/platforms/containerization/docker/custom-containers/git-repo-updater.md). This self-made tool was useful to me because it copied the contents of Gitea repositories into bind-mounted container folders on my Portainer servers. This allowed me to set up configurations for Homepage-Docker, Material MkDocs, Traefik Reverse Proxy, and others to pull configuration changes from Gitea directly into the production servers, causing them to hot-load the changes instantly. (within 10 seconds, give or take).
When I first started my journey with a GitOps mentality to transition a portion of my homelab's infrastructure to an "**Intrastructure-as-Code**" structure, I had made my own self-made Docker container that I called the [Git-Repo-Updater](<../../deployments/Containers/Docker/Git Repo Updater.md>). This self-made tool was useful to me because it copied the contents of Gitea repositories into bind-mounted container folders on my Portainer servers. This allowed me to set up configurations for Homepage-Docker, Material MkDocs, Traefik Reverse Proxy, and others to pull configuration changes from Gitea directly into the production servers, causing them to hot-load the changes instantly. (within 10 seconds, give or take).
## Criticisms of Git-Repo-Updater
When I made the [Git-Repo-Updater docker container stack](https://git.bunny-lab.io/container-registry/git-repo-updater), I ran into the issue of having made something I knew existing solutions existed for but simply did not understand well-enough to use yet. This caused me to basically delegate the GitOps workflow to a bash script with a few environment variables, running inside of an Alpine Linux container. While the container did it's job, it would occassionally have hiccups, caching issues, or repository branch errors that made no sense. This lack of transparency and the need to build an entire VSCode development environment to push new docker package updates to Gitea's [package repository for Git-Repo-Updater](https://git.bunny-lab.io/container-registry/-/packages/container/git-repo-updater/latest) caused a lot of development headaches.
@@ -31,80 +31,10 @@ When I finally got around to figuring out the general architecture of how [Gitea
- The Gitea repository has a Gitea-specific workflows folder that holds `.yaml` files that the runner uses to define tasks that occur when the repository has changes made to it / commits pushed to it.
- The runner checks out the repository (*clones it to the runner environment*), and leverages rsync to copy the data into the production server's configuration folder(s) based on the unique needs of the task.
- The runner cleans up after itself and returns back to an "Idle" state.
- The production server hot-loads the changed configuration files (e.g. Material MkDocs, Traefik, Nginx, etc) and the changes go to into effect immediately
- The production server hot-loads the changed configuration files (e.g. Material MkDocs, Traefik, Nginx, etc) and the changes go to into effect immediately
### Docker-Compose Runner Deployment
When it comes to deploying a runner, (*assuming you want to use a docker-based runner*) it has a few simple things that need to be configured, the `docker-compose.yml` and the `.env` files. These tell the runner to reach out to Gitea server to register the runner with the given repository that you generated a registration token on.
```yaml title="docker-compose.yml"
version: "3.8"
services:
app:
image: docker.io/gitea/act_runner:latest
environment:
CONFIG_FILE: /config.yaml
GITEA_INSTANCE_URL: "${INSTANCE_URL}"
GITEA_RUNNER_REGISTRATION_TOKEN: "${REGISTRATION_TOKEN}"
GITEA_RUNNER_NAME: "${RUNNER_NAME}"
GITEA_RUNNER_LABELS: "${RUNNER_NAME}" # This can be anything, and is referenced by the workflow task(s) later.
volumes:
- /srv/containers/gitea-runner-mkdocs/config.yaml:/config.yaml # You have to manually make this file before you start the container
- /srv/containers/material-mkdocs/docs/docs:/Gitops_Destination # This is where the repository data will be copied to
```
```sh title=".env"
INSTANCE_URL=https://git.bunny-lab.io
RUNNER_NAME=gitea-runner-mkdocs
REGISTRATION_TOKEN=<Generated Here: https://git.bunny-lab.io/bunny-lab/docs/settings/actions/runners>
```
### Creating the `config.yaml`
The oddball thing about the way that I configured the Gitea Act Runner was telling it to run the container in "host mode" which tells it to run the tasks / workflows directly on the container itself instead of spinning up an instanced container (referred to as "*Docker-in-Docker*"). This keeps things simpler, but requires us to add a line to the `config.yaml` located at `/srv/containers/gitea-runner-mkdocs/config.yaml`. You can use your preferred text editor to add the following to the file's contents. This tells the runner to use itself for the tasks instead of an instanced docker container.
```yaml title="/srv/containers/gitea-runner-mkdocs/config.yaml"
container_engine: ""
```
!!! info "Quick Config Command"
```sh
mkdir -p /srv/containers/gitea-runner-mkdocs
echo 'container_engine: ""' > "/srv/containers/gitea-runner-mkdocs/config.yaml"
```
### Runner Workflow Task Files
When it comes to telling the runner what to do and how to do it, you create what are called runner "**Workflows**". These files reside within `<RepoRoot>/.gitea/workflows` and are `.yaml` format. If you have any familiarity with Ansible, the similarities are staggaring. You can have multiple workflows for one repository, with different flows that fire-off on different runners. An example of the flow used to replace Git-Repo-Updater's functionality can be seen below.
In the workflow below, it spins up a runner within the Alpine Linux environment that the `docker.io/gitea/act_runner:latest` uses, then installs NodeJS, Git, and Rsync for the core functionality that mirrors Git-Repo-Updater:
```yaml title=".gitea/workflows/gitops-automatic-deployment.yml"
name: GitOps Automatic Deployment
on:
push:
branches: [ main ]
jobs:
GitOps Automatic Deployment:
runs-on: gitea-runner-mkdocs
steps:
- name: Install Node.js, git, rsync, and curl
run: |
apk add --no-cache nodejs npm git rsync curl
- name: Checkout Repository
uses: actions/checkout@v3
- name: Copy Repository Data to Production Server
run: |
rsync -a --delete --exclude='.git/' --exclude='.gitea/' . /Gitops_Destination/
- name: Notify via NTFY
run: |
curl -d "https://docs.bunny-lab.io - Workflow Completed" https://ntfy.bunny-lab.io/gitea-runners
```
!!! note "`runs-on` Variable"
In this example workflow file, we are targeting the previously-mentioned `gitea-runner-mkdocs` runner, which we gave that "label" in the docker-compose.yaml file's `GITEA_RUNNER_LABELS` variable. You can name these labels whatever you want, as a way of organizing which runners run which workflows associated with a repository when changes are made to the repository.
### Runner Configuration
I have separated the Docker runner configuration and repository workflow into [Deliver Configuration with a Docker Runner](<../../workflows/Automation/Gitea/Deliver Configuration with a Docker Runner.md>). This preserves the operational example alongside the reasons I chose it. The [Zensical host runner workflow](<../../workflows/Automation/Gitea/Publish Zensical Documentation with a Host Runner.md>) documents the separate host-based implementation.
### It All Comes Together
When all of this is set up, it works exactly like Git-Repo-Updater did, but more securely, faster, and more robustly, as the tasks can be changed from the repository-level instead of having to make changes inside of a `Dockerfile` or having to learn how to publish your own Docker containers to a registry. When you learn how to do it, it becomes faster and easier to set up than Git-Repo-Updater as well.
@@ -113,6 +43,4 @@ Then, when you push changes to a repository, the workflow's task triggers automa
Gitea Act Runners are a beautiful thing, and it's a damn shame it took me this long to get around to learning how they work and using them.
![Gitea_Runner_Screenshot](./Images/Gitea_Runner_Screenshot.png)
![Gitea_Runner_Screenshot](<Images/Gitea_Runner_Screenshot.png>)
@@ -1,5 +1,5 @@
---
draft: false
draft: false
date: 2024-12-15
updated: 2024-12-15
authors:
@@ -39,4 +39,8 @@ tags:
# Example Post Title
Placeholder Text / Body of the Blog Post.
```
```
## Related Documentation
- [Zensical Deployment](<../../deployments/automation/Documentation/Zensical.md>) — Find the separately documented Zensical service and its content-delivery workflow.
- [Blog Styling Contract](<../../reference/foundations/Documentation Styling.md>) — Use the canonical blog front matter and narrative structure.
@@ -1,12 +1,12 @@
---
draft: false
draft: false
date: 2024-12-15
updated: 2024-12-15
authors:
- nicole
links:
- platforms/virtualization/openstack/ansible-openstack.md
- platforms/virtualization/openstack/canonical-openstack.md
- ../../deployments/Virtualization and Storage/OpenStack/Ansible OpenStack.md
- ../../deployments/Virtualization and Storage/OpenStack/Canonical OpenStack.md
categories:
- Virtualization
- Containers
@@ -22,12 +22,10 @@ tags:
So, I want to start with a little context. As part of a long-standing project I have been working on, I have tried to deploy OpenStack. OpenStack is sort of envisioned as "Infrastructure as a Service (IAAS)". Basically you deploy an OpenStack cluster, which can run its own KVM for virtual machine and containers, or it can interface with an existing Hypervisor infrastructure, such as Hyper-V. In most cases, people branch out the "Control", "Compute", and "Storage" roles into different physical servers, but in my homelab, I have been attempting to deploy it via a "Converged" model, of having Control, Compute, and Storage on each node, spanning a high-availability cluster of 3 nodes.
## The Problem
The problems come into the overall documentation provided for deploying either [Canonical Openstack](https://ubuntu.com/openstack/install) which I have detailed my frustrations of the system in my own attempted re-write of the documentation [here](../../deployments/platforms/virtualization/openstack/canonical-openstack.md). I have also attempted to deploy it via [Ansible OpenStack](https://docs.openstack.org/project-deploy-guide/openstack-ansible/2024.1/), whereas my documentation thus far in my homelab is visible [here](../../deployments/platforms/virtualization/openstack/ansible-openstack.md).
The problems come into the overall documentation provided for deploying either [Canonical Openstack](https://ubuntu.com/openstack/install) which I have detailed my frustrations of the system in my own attempted re-write of the documentation [here](<../../deployments/Virtualization and Storage/OpenStack/Canonical OpenStack.md>). I have also attempted to deploy it via [Ansible OpenStack](https://docs.openstack.org/project-deploy-guide/openstack-ansible/2024.1/), whereas my documentation thus far in my homelab is visible [here](<../../deployments/Virtualization and Storage/OpenStack/Ansible OpenStack.md>).
You see, OpenStack is like icecream, it has many different ways to deploy it, and it can be as simple, or as overtly-complex as you need it to be, and it scales *really well* across a fleet of servers in a datacenter. My problems come in where the Canonical deployment has never worked fully / properly, and their own development team is hesitant to recommend the current documentation, and the Ansible OpenStack deployment process, while relatively simple, requires a base of existing knowledge that makes translating the instructions into more user-friendly instructions in my homelab documentation a difficult task. Eventually I want to automate much of the process as much as I can, but that will take time.
The common issue I've seen while trying to deploy OpenStack is understanding the networking, how networking is configured, network bridges, etc. The process is different based on the deployment method (Currently trying to deploy it via OpenStack Ansible). Hopefully in the near future I will make some kind of breakthrough in the deployment process and get everything working.
I will post an update later if I figure things out!