blumeops/docs/tutorials/replication/core-services.md
Erich Blume f9397b7fa0 Review core-services tutorial: add SSH rationale, runner example, TODO notice
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 21:22:00 -07:00

4.9 KiB

title modified last-reviewed tags
Core Services 2026-02-07 2026-04-05
tutorials
replication
forgejo

Core Services Setup

TODO: This tutorial is light on specifics and should be expanded. In its current form it serves as a general sketch of how BlumeOps got started — every component mentioned here (Forgejo, Zot, CI runners, etc.) receives much deeper treatment elsewhere in the blumeops codebase and documentation.

Audiences: Replicator

Prerequisites: tailscale-setup

This tutorial walks through setting up the foundational services that your GitOps infrastructure depends on: a git forge and optionally a container registry.

Why Core Services First?

Before Kubernetes and ArgoCD, you need somewhere to store your infrastructure definitions. forgejo provides:

  • Git hosting for your GitOps repository
  • CI/CD workflows for building and deploying
  • A web interface for code review and PRs

The zot container registry is optional but useful for hosting your own container images.

Step 1: Install Forgejo

Forgejo runs directly on your server (not in Kubernetes) because Kubernetes depends on it.

Using Ansible (BlumeOps Approach)

BlumeOps manages Forgejo via an Ansible role. See ansible.

Manual Installation

  1. Download Forgejo from forgejo.org
  2. Create a service user and directories
  3. Configure with app.ini
  4. Set up as a system service

Key configuration points:

  • SSH on a non-standard port (e.g., 2222) to avoid conflicts
  • Database (SQLite works fine for personal use)
  • Domain and URL settings for your Tailscale hostname

Step 2: Configure SSH Access

Forgejo runs its own SSH server on a non-standard port (e.g., 2222) to avoid conflicting with the host's SSH daemon on port 22. Later, caddy with the L4 plugin can map port 22 to 2222 using a DNS name (e.g., forge.ops.eblu.me), so git clients don't need to specify a port.

Set up SSH for git operations:

# Add your SSH key to Forgejo via the web UI
# Then test access (using the non-standard port directly):
ssh -T git@your-server.tailnet.ts.net -p 2222

Step 3: Create Your GitOps Repository

  1. Create a new repository in Forgejo (e.g., infrastructure or homelab)
  2. Initialize the standard directory structure:
your-repo/
├── ansible/           # Host configuration
│   ├── playbooks/
│   └── roles/
├── argocd/            # Kubernetes GitOps
│   ├── apps/          # ArgoCD Applications
│   └── manifests/     # K8s manifests per service
├── pulumi/            # IaC for Tailscale, DNS
└── docs/              # Documentation
  1. Push your initial commit

Step 4: Set Up CI/CD Runner (Optional)

Forgejo Actions runs workflows defined in .forgejo/workflows/. The simplest setup is a native runner that executes jobs directly on the host (no Docker required):

  1. Download the forgejo-runner binary from code.forgejo.org:
# macOS ARM64 example
curl -L -o forgejo-runner \
  https://code.forgejo.org/forgejo/runner/releases/download/v6.3.1/forgejo-runner-6.3.1-darwin-arm64
chmod +x forgejo-runner
  1. Generate a registration token from the Forgejo admin UI (Site Administration → Actions → Runners)

  2. Register and start the runner using the host scheme (no container isolation):

forgejo-runner register \
  --instance https://your-forge.tailnet.ts.net \
  --token <registration-token> \
  --name local-runner \
  --labels "native:host" \
  --no-interactive

forgejo-runner daemon
  1. Reference the label in your workflows:
# .forgejo/workflows/example.yaml
jobs:
  build:
    runs-on: native
    steps:
      - run: echo "Running on bare metal"

Note: Host mode has no isolation — jobs run as whatever user runs forgejo-runner. This is fine for a personal setup with trusted repos. Use a launchd plist or brew services wrapper to keep it running.

BlumeOps runs its Forgejo runner inside Kubernetes instead — see forgejo for that approach.

Step 5: Container Registry (Optional)

If you'll build custom container images, set up zot:

  1. Install Zot on your server
  2. Configure authentication
  3. Set up TLS (via Caddy or similar)

For getting started, you can skip this and use public registries.

What You Now Have

  • Git hosting for infrastructure code
  • SSH access for git operations
  • Foundation for CI/CD workflows
  • Optionally, a private container registry

Next Steps

  • kubernetes-bootstrap - Now that you have a git repo, set up your cluster
  • Configure Forgejo webhooks for ArgoCD (after ArgoCD is running)

BlumeOps Specifics

BlumeOps' Forgejo setup includes:

  • Ansible role for installation and updates
  • SSH on port 2222, proxied via Caddy
  • Integration with ArgoCD via deploy keys
  • Forgejo runner in Kubernetes for CI/CD

See forgejo and zot for full details.