--- id: 1768246525-RVRY tags: - blumeops - forgejo - git - scm - forge --- # Mon Jan 12 11:35 ```fish ❯ brew install forgejo ❯ brew --prefix forgejo /opt/homebrew/opt/forgejo ❯ brew services start forgejo ==> Successfully started `forgejo` (label: homebrew.mxcl.forgejo) ``` From the service definition I can see that this runs as: ```bash /opt/homebrew/opt/forgejo/bin/forgejo web --work-path /opt/homebrew/var/forgejo > /opt/homebrew/var/log/forgejo.log 2> /opt/homebrew/var/log/forgejo.log ``` It sounds from the docs like this means the config file should live at: ``` /opt/homebrew/var/forgejo/custom/conf/app.ini ``` Ah, based on the logs, it looks like forgejo has picked port 3000 which is used by grafana: ``` ❯ lsof -nP -iTCP:3000 -sTCP:LISTEN COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME grafana 1530 erichblume 15u IPv6 0x4acfad8b21dcb063 0t0 TCP *:3000 (LISTEN) ``` Ok I've set a basic config for port 3001, and then gone through the basic app setup. Looks like it's working! Not sure how SSH works yet though. Let's get this service registered. Ok so the next issue is that I want to use ssh as my primary git interface, and I want that to look to users like I'm using port 22 but I want to host it on indri which has its own separate ssh setup. Hmm. Let's tell forgejo to use port 2200. Ah perfect, we can set SSH_PORT to 22 and SSH_LISTEN_PORT to 2200. Hmm, let's stop running this as me and run as a new user, 'forgejo'. ```fish sudo sysadminctl -addUser forgejo -system -shell /usr/bin/false sudo chown -R forgejo:staff /opt/homebrew/var/forgejo ``` Ok, I think I need to switch all my services on this host over to a services file. Wow, missing from the above is like 4 hours of deep diving in to the particulars of tailscale service definition hosting. In the end, I never got a services file to work - and yes, I did remember to advertise! Adding to the complexity is that I didn't discover until the end that you can't do "hairpinning", ie you CANNOT use the tailnet service name from the host doing that hosting. I probably had it fixed at some point hours ago and ruled it out because I didn't know about the hairpinning issue. So anyway... what ended up working was to just use the cli: ```fish tailscale serve --service="svc:forge" --tcp=22 tcp://localhost:2200 tailscale serve --service="svc:forge" --https=443 http://localhost:3001 ``` That's it. Nothing else needed, worked right away. Sheesh. (Ok there was also a solid hour spent on permission issues... I honestly don't know how it's working now, as there is now a `forgejo` user and the config says to use it but the files are all owned by `erichblume:staff` but with group permissions set... in any case, it friggin' works. So I'm happy. # Configuration (Ansible-Managed) As of 2026-01-23, the `app.ini` is managed by ansible: - Template: `ansible/roles/forgejo/templates/app.ini.j2` - Secrets fetched from 1Password in playbook pre_tasks - Secrets item: "Forgejo Secrets" in blumeops vault (fields: `lfs-jwt-secret`, `internal-token`, `oauth2-jwt-secret`, `runner_reg`) Deploy config changes: ```bash mise run provision-indri -- --tags forgejo ``` # Forgejo Actions (CI/CD) ## Runner (k8s) The Forgejo runner runs in Kubernetes with Docker-in-Docker (DinD) for container builds. **Architecture:** - Runner daemon + DinD sidecar in a single pod - Jobs execute in containers using the `k8s` label - DinD exposes Docker API on `tcp://127.0.0.1:2375` - Pods reach `*.ops.eblu.me` services via Caddy reverse proxy **Components:** - ArgoCD app: `argocd/apps/forgejo-runner.yaml` - Manifests: `argocd/manifests/forgejo-runner/` - Job image: `registry.ops.eblu.me/blumeops/forgejo-runner` (Node.js + Docker CLI) - Job image source: `containers/forgejo-runner/` **Deployment:** ```bash # Apply secret (contains runner token from 1Password) op inject -i argocd/manifests/forgejo-runner/secret.yaml.tpl | kubectl --context=minikube-indri apply -f - # Sync via ArgoCD argocd app sync forgejo-runner ``` **View logs:** ```bash kubectl --context=minikube-indri logs -n forgejo-runner -l app=forgejo-runner -c runner ``` ## Container Build Workflow Container images are built via `.forgejo/workflows/build-container.yaml`, triggered by tags matching `-v`. **Release a container:** ```bash mise run container-list # See available containers mise run container-tag-and-release nettest v1.0.0 # Tag and trigger build ``` **Test container** (`containers/nettest/`): Network connectivity test for debugging CI/CD. ## Workflows Workflows live in `.forgejo/workflows/` (not `.github/workflows/`). **Important**: Use `github.*` context variables, not `gitea.*`. Forgejo supports both at runtime, but: 1. The Forgejo web UI schema validator only recognizes `github.*` 2. `actionlint` pre-commit hook validates workflows locally (catches errors before push) 3. Pass untrusted inputs (like `github.head_ref`) through env vars for security ## Runner Token Stored in 1Password "Forgejo Secrets" item, field `runner_reg`. To create a new token: 1. Go to https://forge.ops.eblu.me/admin/actions/runners 2. Click "Create new Runner" 3. Copy the token and update 1Password