---
title: "Project: Hugo Documentation Framework (Blowfish)"
description: "Architecture, local development, and deployment documentation for the central Hugo framework repository."
author: wompmacho
date: '2026-03-28T22:05:00-04:00'
lastmod: '2026-03-28'
tags: [hugo, framework, architecture, deployment, readme]
---

# Project: Hugo Documentation Framework (Blowfish)

This repository (`hugo-framework`) manages the core **Hugo build environment** (engine, Blowfish theme, layouts, partials, and base configuration) for both the Public and Private Wikis.

## 🏗️ Architecture

To allow for seamless Dev vs. Prod workflows, the architecture is split into three repositories:

1.  **Framework (`/srv/dev/hugo/wiki`)**: Contains the Hugo engine, themes, custom shortcodes (like `include`), and the **default configuration**.
2.  **Public Content (`/srv/docs/public`)**: Contains the Markdown files and assets for the public-facing wiki.
3.  **Private Content (`/srv/docs/private`)**: Contains the Markdown files and assets for the internal/private wiki.

**Dynamic Configuration Merging:**
The Framework defines the base styling in `config/_default/params.toml`. 
However, the Content repositories can dynamically override settings during the build:
*   **Menus**: By providing a `config/_default/menus.en.toml` file.
*   **Theme Settings (Edit Links)**: Injected via Environment Variables (`HUGO_PARAMS_ARTICLE_EDITURL`) during the CI/CD pipeline to avoid hardcoding repository URLs in the base framework.

## 💻 Local Development ("Live Link")

To write documentation with real-time previews, use symbolic links on your host machine to connect a content repository to the framework:

1.  **Establish Symlinks** (Example for Public Docs):
    ```bash
    cd /srv/dev/hugo/wiki
    rm -rf content static
    ln -s /srv/docs/public content
    ln -s /srv/docs/public/static static
    ```
2.  **Preview Changes**: 
    ```bash
    hugo server --bind 0.0.0.0 --appendPort=false --baseURL="/"
    ```

## 🚀 CI/CD Pipeline & Deployment

Deployment is fully automated through Gitea Actions stored in the **Content repositories** (e.g., `.gitea/workflows/deploy.yaml`). **Manual builds to production should be avoided.**

**The Build Process:**
1. The Gitea Runner checks out the triggering content repository.
2. It clones this Framework repository dynamically.
3. It injects the Markdown files and static assets into the framework.
4. It builds the static HTML site using Hugo.
5. The generated files are copied directly into the persistent web server volumes:
   * Public Wiki: `/srv/www/docs-public`
   * Private Wiki: `/srv/www/docs-private`

These directories are then served by their respective Dockerized Nginx containers.

## 📂 File Inclusions (Absolute Paths)

To allow for the inclusion of raw files outside of the standard Hugo `content/` directory (such as system configurations located in `/srv/configs`), this framework utilizes **Hugo Module Mounts** mapping into the virtual `assets/` directory.

### How it Works

Hugo's `readFile` and `fileExists` functions are blocked by strict OS security policies and cannot read paths outside the project root. To bypass this safely:
1. The external directory is mounted in `config/_default/hugo.toml`:
   ```toml
   [[module.mounts]]
     source = "/srv/configs"
     target = "assets/srv/configs"
   ```
2. The custom `include.html` shortcode (`{{< include "/srv/configs/..." >}}`) detects paths starting with `/srv/`, trims the leading slash, and uses `resources.Get` to fetch the raw file from the virtual `assets/` namespace, completely bypassing the Markdown parser and security blocks.

**⚠️ Critical Note on CI/CD for External Files:**
If you map new external directories in `hugo.toml` (e.g., `/srv/newfolder`), the Docker container running the Gitea Action must also have OS-level access to those files. You must:
1. Allow the volume in the host's Gitea runner config (`/srv/gitea/runner/config.yaml` -> `valid_volumes`).
2. Mount the volume in the job options of the content repository's `.gitea/workflows/deploy.yaml` (e.g., `options: --user root -v /srv/www:/srv/www -v /srv:/srv:ro`).
