fix: address review — rename forgejo.nomad.hcl + wire nomad job validate CI
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/nomad-validate Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/nomad-validate Pipeline was successful
ci/woodpecker/pr/secret-scan Pipeline was successful

Two blockers from the #844 review:

1. Rename nomad/jobs/forgejo.hcl → nomad/jobs/forgejo.nomad.hcl to match
   the convention documented in nomad/AGENTS.md:38 (*.nomad.hcl suffix).
   First jobspec sets the pattern for all future ones; keeps any glob-
   based tooling over nomad/jobs/*.nomad.hcl working.
2. Add a dedicated `nomad-job-validate` step to .woodpecker/nomad-validate.yml.
   `nomad config validate` (step 1) parses agent configs only — it rejects
   jobspec HCL as "unknown block 'job'". `nomad job validate` is the
   correct offline validator for jobspec HCL. Per the Hashicorp docs it
   does not require a running agent (exit 0 clean, 1 on syntax/semantic
   error). New jobspecs will add an explicit line alongside forgejo's,
   matching step 1's enumeration pattern and this file's "no-ad-hoc-steps"
   principle.

Also updated the file header comment and the pipeline's top-of-file step
index to reflect the new step ordering (2. nomad-job-validate inserted;
old 2-4 renumbered to 3-5).

Refs: #840 (S1.1), PR #844
This commit is contained in:
Claude 2026-04-16 10:11:34 +00:00
parent 2ad4bdc624
commit db64f2fdae
2 changed files with 25 additions and 7 deletions

View file

@ -1,113 +0,0 @@
# =============================================================================
# nomad/jobs/forgejo.hcl Forgejo git server (Nomad service job)
#
# Part of the Nomad+Vault migration (S1.1, issue #840). First jobspec to
# land under nomad/jobs/ proves the docker driver + host_volume plumbing
# from Step 0 (client.hcl) by running a real factory service.
#
# Host_volume contract:
# This job mounts the `forgejo-data` host_volume declared in
# nomad/client.hcl. That volume is backed by /srv/disinto/forgejo-data on
# the factory box, created by lib/init/nomad/cluster-up.sh before any job
# references it. Keep the `source = "forgejo-data"` below in sync with the
# host_volume stanza in client.hcl — drift = scheduling failures.
#
# No Vault integration yet Step 2 (#...) templates in OAuth secrets and
# replaces the inline FORGEJO__oauth2__* bits. The env vars below are the
# subset of docker-compose.yml's forgejo service that does NOT depend on
# secrets: DB type, public URL, install lock, registration lockdown, webhook
# allow-list. OAuth app registration lands later, per-service.
#
# Not the runtime yet: docker-compose.yml is still the factory's live stack
# until cutover. This file exists so CI can validate it and S1.3 can wire
# `disinto init --backend=nomad --with forgejo` to `nomad job run` it.
# =============================================================================
job "forgejo" {
type = "service"
datacenters = ["dc1"]
group "forgejo" {
count = 1
# Static :3000 matches docker-compose's published port so the rest of
# the factory (agents, woodpecker, caddy) keeps reaching forgejo at the
# same host:port during and after cutover. `to = 3000` maps the host
# port into the container's :3000 listener.
network {
port "http" {
static = 3000
to = 3000
}
}
# Host-volume mount: declared in nomad/client.hcl, path
# /srv/disinto/forgejo-data on the factory box.
volume "forgejo-data" {
type = "host"
source = "forgejo-data"
read_only = false
}
# Conservative restart policy fail fast to the scheduler instead of
# spinning on a broken image/config. 3 attempts over 5m, then back off.
restart {
attempts = 3
interval = "5m"
delay = "15s"
mode = "delay"
}
# Native Nomad service discovery (no Consul in this factory cluster).
# Health check gates the service as healthy only after the API is up;
# initial_status is deliberately unset so Nomad waits for the first
# probe to pass before marking the allocation healthy on boot.
service {
name = "forgejo"
port = "http"
provider = "nomad"
check {
type = "http"
path = "/api/v1/version"
interval = "10s"
timeout = "3s"
}
}
task "forgejo" {
driver = "docker"
config {
image = "codeberg.org/forgejo/forgejo:11.0"
ports = ["http"]
}
volume_mount {
volume = "forgejo-data"
destination = "/data"
read_only = false
}
# Mirrors the non-secret env set from docker-compose.yml's forgejo
# service. OAuth/secret-bearing env vars land in Step 2 via Vault
# templates do NOT add them here.
env {
FORGEJO__database__DB_TYPE = "sqlite3"
FORGEJO__server__ROOT_URL = "http://forgejo:3000/"
FORGEJO__server__HTTP_PORT = "3000"
FORGEJO__security__INSTALL_LOCK = "true"
FORGEJO__service__DISABLE_REGISTRATION = "true"
FORGEJO__webhook__ALLOWED_HOST_LIST = "private"
}
# Baseline tune once we have real usage numbers under nomad. The
# docker-compose stack runs forgejo uncapped; these limits exist so
# an unhealthy forgejo can't starve the rest of the node.
resources {
cpu = 300
memory = 512
}
}
}
}