Automated Documentation Pipeline: Obsidian to WordPress via Gitea Actions

Project Goal: Create a seamless documentation workflow where writing in Obsidian automatically generates and deploys static webpages to an existing WordPress site.

The Problem: My team needed a better documentation solution. Writing in Obsidian is efficient, but sharing required manual export/conversion. We wanted:

  • Obsidian's writing experience

  • Automated webpage generation

  • No manual publishing steps

  • Integration with existing infrastructure

The Solution: Built a CI/CD pipeline using Gitea Actions that automatically converts Obsidian Markdown files to MkDocs static sites and deploys them to an Apache2 server running WordPress.

Key Results:

  • ✓ Zero-touch publishing: git push triggers full build & deploy

  • ✓ All documentation on www.onthezero.com/docs uses this system

  • ✓ Local preview capability before deployment

  • ✓ Minimal new infrastructure required


Technical Implementation

Architecture & Constraints

Infrastructure Context:

  • Home lab running Proxmox with existing LXC containers

  • WordPress LXC (Apache2) for hosting

  • Gitea LXC for version control

  • Constraint: Minimize new VMs/LXCs

Technical Stack:

  • Source Control: Gitea with custom Actions

  • Static Site Generator: MkDocs

  • Editor: Obsidian

  • Infrastructure: Proxmox, Debian LXC, Docker

  • AI Assistant: Deepseek (for gap filling)

Development Process

Challenge 1: Missing Gitea Runner Infrastructure

  • Problem: New Gitea instance lacked action runners

  • Solution: Created Debian LXC, installed Docker, configured as Gitea runner per official documentation

Challenge 2: First-Time Action Development

  • Problem: No experience creating custom Git actions

  • Solution: Used Deepseek to understand YAML structure and deployment workflows

  • Key learning: Runner authentication via SSH keys for server deployment

Challenge 3: WordPress Integration

  • Problem: Deploying static content to existing WordPress directory structure

  • Solution: Configured runner SSH access to Apache document root at /var/www/html/docs/

Final Workflow

  1. Write: Create/edit Markdown in Obsidian with local vault synced to

  2. Commit & Push: Standard Git workflow to Gitea repository

  3. Automated Build: Gitea Action triggers MkDocs build in Docker container

  4. Deploy: Built static files copied via SSH to WordPress server

  5. Live: Documentation immediately available at /docs path


Outcome & Impact

Successful Implementation

  • Fully automated pipeline: Obsidian → Git → MkDocs → WordPress

  • Local testing: mkdocs serve allows preview before commit

  • Infrastructure efficient: Only one new LXC required (Gitea runner)

Current Limitations

  1. Per-repo runner setup: Each repository requires dedicated runner configuration

  2. SSH key management: Manual key distribution needed

  3. Path-based deployment: Currently uses /docs subdirectory rather than subdomain

Quantifiable Benefits

  • Time savings: Publishing webpages automated, simply write in Obsidian and push to repo

  • Consistency: Eliminated manual conversion errors

  • Version control: Full Git history of all documentation changes


Code Snippet: Gitea Action Configuration

name: Deploy MkDocs to WordPress
on: [push]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.x"

      - name: Install MkDocs
        run: pip install mkdocs

      - name: Build MkDocs site
        run: mkdocs build

      - name: Deploy Documentation
        run: |
          # Setup SSH
          mkdir -p ~/.ssh
          KEY_PATH=~/.ssh/deploy_key
          echo "${{ secrets.DEPLOY_SSH_KEY }}" | tr -d '\r' > $KEY_PATH
          chmod 600 $KEY_PATH

          # Accept host
          ssh-keyscan -H ${{secrets.WORDPRESS_HOST}} >> ~/.ssh/known_hosts 2>/dev/null

          echo "🚀 Deploying to WordPress..."

          # Clean and deploy
          ssh -i $KEY_PATH ${{secrets.WORDPRESS_USER}}@${{secrets.WORDPRESS_HOST}} \
            "rm -rf ${{secrets.WORDPRESS_PATH}}* 2>/dev/null || true"

          scp -r \
            -i $KEY_PATH \
            -o StrictHostKeyChecking=accept-new \
            site/* \
            ${{secrets.WORDPRESS_USER}}@${{secrets.WORDPRESS_HOST}}:${{secrets.WORDPRESS_PATH}}

          echo "✅ Deployment complete!"

          # Cleanup
          rm -f $KEY_PATH

Lessons Learned & Next Steps

Key Technical Insights

  1. Gitea Actions are powerful but require careful runner isolation

  2. SSH key rotation needs to be part of maintenance planning

Immediate Improvements Planned

  1. Subdomain deployment: Migrate from /docs to docs.onthezero.com

    • Requires Nginx Proxy Manager configuration changes

    • Better SEO separation from main WordPress site

  2. Runner optimization: Create reusable runner template for new documentation repos

Future Enhancements

  • Multi-environment support (staging/production)

  • Automated link checking in pipeline

  • Analytics integration for documentation usage


Why This Matters

This project demonstrates how infrastructure automation can solve real workflow problems. By connecting existing tools (Obsidian, Gitea, WordPress) through custom automation, I created a system that's greater than the sum of its parts—reducing friction while maintaining flexibility.

The result: A sustainable documentation system that encourages writing by making publishing invisible.