Deploy Forgejo on railiance01 using gitea-charts/gitea 12.5.0
Pin chart to 12.5.0 because 12.6+ calls `gitea config edit-ini`, which Forgejo 11 lacks. Ingress targets forgejo-gitea-http (Helm release naming). Smoke test uses GET for /v2/ registry challenge (HEAD returns 405).
This commit is contained in:
parent
6d00232865
commit
75698636c6
8 changed files with 296 additions and 2 deletions
67
Makefile
67
Makefile
|
|
@ -32,10 +32,24 @@ REUSE_CERTIFICATE ?= reuse-surface-tls
|
||||||
RAILIANCE01_KUBECONFIG ?= $(HOME)/.kube/config-hosteurope
|
RAILIANCE01_KUBECONFIG ?= $(HOME)/.kube/config-hosteurope
|
||||||
INTER_HUB_KUBECONFIG ?= $(RAILIANCE01_KUBECONFIG)
|
INTER_HUB_KUBECONFIG ?= $(RAILIANCE01_KUBECONFIG)
|
||||||
REUSE_KUBECONFIG ?= $(RAILIANCE01_KUBECONFIG)
|
REUSE_KUBECONFIG ?= $(RAILIANCE01_KUBECONFIG)
|
||||||
|
FORGEJO_KUBECONFIG ?= $(RAILIANCE01_KUBECONFIG)
|
||||||
|
FORGEJO_RELEASE ?= forgejo
|
||||||
|
FORGEJO_NAMESPACE ?= forgejo
|
||||||
|
FORGEJO_CHART ?= gitea-charts/gitea
|
||||||
|
# Forgejo 11.x (Gitea 1.22) lacks `gitea config edit-ini`; chart 12.6+ requires Gitea 1.26+.
|
||||||
|
FORGEJO_CHART_VERSION ?= 12.5.0
|
||||||
|
FORGEJO_VALUES ?= helm/forgejo-values.yaml
|
||||||
|
FORGEJO_REGISTRY_VALUES ?= helm/forgejo-registry-values.yaml
|
||||||
|
FORGEJO_SECRETS ?= helm/forgejo-secrets.sops.yaml
|
||||||
|
FORGEJO_INGRESS ?= manifests/forgejo-ingress.yaml
|
||||||
|
FORGEJO_SSH_NODEPORT ?= manifests/forgejo-ssh-nodeport.yaml
|
||||||
|
FORGEJO_BASE_URL ?= https://forgejo.coulomb.social
|
||||||
|
FORGEJO_DB_CLUSTER ?= forgejo-db
|
||||||
|
FORGEJO_DB_NAMESPACE ?= databases
|
||||||
INTER_HUB_IMAGE_REF = $(INTER_HUB_IMAGE_REPOSITORY):$(INTER_HUB_IMAGE_TAG)
|
INTER_HUB_IMAGE_REF = $(INTER_HUB_IMAGE_REPOSITORY):$(INTER_HUB_IMAGE_TAG)
|
||||||
INTER_HUB_IMAGE_SET_ARG = $(if $(strip $(INTER_HUB_IMAGE_TAG)),--set image.tag=$(INTER_HUB_IMAGE_TAG),)
|
INTER_HUB_IMAGE_SET_ARG = $(if $(strip $(INTER_HUB_IMAGE_TAG)),--set image.tag=$(INTER_HUB_IMAGE_TAG),)
|
||||||
|
|
||||||
SOPS_SENTINEL ?=
|
SOPS_SENTINEL ?= $(FORGEJO_SECRETS)
|
||||||
DRY_RUN_CREATE_NAMESPACES ?= false
|
DRY_RUN_CREATE_NAMESPACES ?= false
|
||||||
|
|
||||||
##@ Operator checks
|
##@ Operator checks
|
||||||
|
|
@ -153,6 +167,55 @@ inter-hub-smoke: ## Verify public inter-hub v2 route and OpenAPI surface after r
|
||||||
inter-hub-logs: check-railiance01-kubeconfig ## Tail inter-hub app logs from Railiance01
|
inter-hub-logs: check-railiance01-kubeconfig ## Tail inter-hub app logs from Railiance01
|
||||||
KUBECONFIG="$(INTER_HUB_KUBECONFIG)" kubectl logs -n $(INTER_HUB_NAMESPACE) -l app=$(INTER_HUB_RELEASE) -f --tail=50
|
KUBECONFIG="$(INTER_HUB_KUBECONFIG)" kubectl logs -n $(INTER_HUB_NAMESPACE) -l app=$(INTER_HUB_RELEASE) -f --tail=50
|
||||||
|
|
||||||
|
##@ Forgejo (forgejo.coulomb.social)
|
||||||
|
|
||||||
|
forgejo-dry-run: check-railiance01-kubeconfig check-sops ## helm template render for Forgejo
|
||||||
|
KUBECONFIG="$(FORGEJO_KUBECONFIG)" helm template $(FORGEJO_RELEASE) $(FORGEJO_CHART) \
|
||||||
|
--version $(FORGEJO_CHART_VERSION) \
|
||||||
|
--namespace $(FORGEJO_NAMESPACE) \
|
||||||
|
-f $(FORGEJO_VALUES) \
|
||||||
|
-f $(FORGEJO_REGISTRY_VALUES) \
|
||||||
|
-f <(sops -d $(FORGEJO_SECRETS))
|
||||||
|
|
||||||
|
forgejo-server-dry-run: check-railiance01-kubeconfig check-sops ## Helm server dry-run Forgejo upgrade
|
||||||
|
KUBECONFIG="$(FORGEJO_KUBECONFIG)" helm upgrade --install $(FORGEJO_RELEASE) $(FORGEJO_CHART) \
|
||||||
|
--version $(FORGEJO_CHART_VERSION) \
|
||||||
|
--namespace $(FORGEJO_NAMESPACE) --create-namespace \
|
||||||
|
-f $(FORGEJO_VALUES) \
|
||||||
|
-f $(FORGEJO_REGISTRY_VALUES) \
|
||||||
|
-f <(sops -d $(FORGEJO_SECRETS)) \
|
||||||
|
--dry-run=server --timeout 5m
|
||||||
|
|
||||||
|
forgejo-deploy: check-railiance01-kubeconfig check-sops ## Deploy / upgrade Forgejo on railiance01
|
||||||
|
KUBECONFIG="$(FORGEJO_KUBECONFIG)" helm repo add gitea-charts https://dl.gitea.com/charts/ --force-update
|
||||||
|
KUBECONFIG="$(FORGEJO_KUBECONFIG)" helm upgrade --install $(FORGEJO_RELEASE) $(FORGEJO_CHART) \
|
||||||
|
--version $(FORGEJO_CHART_VERSION) \
|
||||||
|
--namespace $(FORGEJO_NAMESPACE) --create-namespace \
|
||||||
|
-f $(FORGEJO_VALUES) \
|
||||||
|
-f $(FORGEJO_REGISTRY_VALUES) \
|
||||||
|
-f <(sops -d $(FORGEJO_SECRETS)) \
|
||||||
|
--wait --timeout 10m
|
||||||
|
|
||||||
|
forgejo-ingress-deploy: check-railiance01-kubeconfig ## Apply Forgejo HTTPS ingress
|
||||||
|
KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl apply -f $(FORGEJO_INGRESS)
|
||||||
|
|
||||||
|
forgejo-ssh-nodeport-deploy: check-railiance01-kubeconfig ## Apply Forgejo SSH NodePort (30022)
|
||||||
|
KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl apply -f $(FORGEJO_SSH_NODEPORT)
|
||||||
|
|
||||||
|
forgejo-status: check-railiance01-kubeconfig ## Show Forgejo pods, svc, ingress, cert, database
|
||||||
|
KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl get pods,svc,ingress,certificate,pvc -n $(FORGEJO_NAMESPACE) --ignore-not-found
|
||||||
|
@if KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl cnpg status $(FORGEJO_DB_CLUSTER) -n $(FORGEJO_DB_NAMESPACE) >/dev/null 2>&1; then \
|
||||||
|
KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl cnpg status $(FORGEJO_DB_CLUSTER) -n $(FORGEJO_DB_NAMESPACE); \
|
||||||
|
else \
|
||||||
|
KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl get cluster $(FORGEJO_DB_CLUSTER) -n $(FORGEJO_DB_NAMESPACE) --ignore-not-found; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
forgejo-smoke: ## Verify Forgejo web and OCI registry challenge
|
||||||
|
FORGEJO_BASE_URL="$(FORGEJO_BASE_URL)" tools/forgejo-smoke.sh
|
||||||
|
|
||||||
|
forgejo-logs: check-railiance01-kubeconfig ## Tail Forgejo application logs
|
||||||
|
KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl logs -n $(FORGEJO_NAMESPACE) -l app.kubernetes.io/instance=$(FORGEJO_RELEASE) -f --tail=50
|
||||||
|
|
||||||
##@ reuse-surface (reuse.coulomb.social)
|
##@ reuse-surface (reuse.coulomb.social)
|
||||||
|
|
||||||
reuse-dry-run: check-railiance01-kubeconfig ## helm template render (no apply) for reuse-surface
|
reuse-dry-run: check-railiance01-kubeconfig ## helm template render (no apply) for reuse-surface
|
||||||
|
|
@ -183,4 +246,4 @@ help: ## Show this help
|
||||||
/^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[36m%-20s\033[0m %s\n", $$1, $$2 } \
|
/^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[36m%-20s\033[0m %s\n", $$1, $$2 } \
|
||||||
/^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) }' $(MAKEFILE_LIST)
|
/^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) }' $(MAKEFILE_LIST)
|
||||||
|
|
||||||
.PHONY: check-tools check-sops k8s-server-dry-run apps-pg-status check-railiance01-kubeconfig check-inter-hub-image-tag check-inter-hub-image vergabe-dry-run vergabe-deploy vergabe-ingress-deploy vergabe-status vergabe-migrate vergabe-seed vergabe-superuser vergabe-logs vergabe-db-url-secret inter-hub-render-baseline inter-hub-dry-run inter-hub-server-dry-run inter-hub-deploy inter-hub-status inter-hub-release-info inter-hub-smoke inter-hub-logs reuse-dry-run reuse-deploy reuse-status reuse-smoke reuse-logs help
|
.PHONY: check-tools check-sops k8s-server-dry-run apps-pg-status check-railiance01-kubeconfig check-inter-hub-image-tag check-inter-hub-image vergabe-dry-run vergabe-deploy vergabe-ingress-deploy vergabe-status vergabe-migrate vergabe-seed vergabe-superuser vergabe-logs vergabe-db-url-secret forgejo-dry-run forgejo-server-dry-run forgejo-deploy forgejo-ingress-deploy forgejo-ssh-nodeport-deploy forgejo-status forgejo-smoke forgejo-logs inter-hub-render-baseline inter-hub-dry-run inter-hub-server-dry-run inter-hub-deploy inter-hub-status inter-hub-release-info inter-hub-smoke inter-hub-logs reuse-dry-run reuse-deploy reuse-status reuse-smoke reuse-logs help
|
||||||
|
|
|
||||||
80
docs/forgejo-on-railiance01.md
Normal file
80
docs/forgejo-on-railiance01.md
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
# Forgejo on railiance01
|
||||||
|
|
||||||
|
Production source forge at **`https://forgejo.coulomb.social`**.
|
||||||
|
|
||||||
|
Mirrors the coulombcore Gitea pattern (`railiance-forge`) but targets
|
||||||
|
**railiance01** using the same OAS split as other S5 apps (`inter-hub`,
|
||||||
|
`reuse-surface`).
|
||||||
|
|
||||||
|
## Layer ownership
|
||||||
|
|
||||||
|
| Layer | Repo | Concern |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| S3 | `railiance-platform` | `forgejo-db` CNPG cluster + network policies |
|
||||||
|
| S5 | `railiance-apps` | Helm release, ingress, operator Makefile |
|
||||||
|
| S2 | `railiance-cluster` | Traefik, cert-manager, cnpg operator |
|
||||||
|
|
||||||
|
Hostname decision: `the-custodian/docs/forgejo-production-decisions.md`.
|
||||||
|
|
||||||
|
## Hosts
|
||||||
|
|
||||||
|
| Item | Value |
|
||||||
|
| --- | --- |
|
||||||
|
| Server | railiance01 `92.205.62.239` |
|
||||||
|
| Namespace | `forgejo` |
|
||||||
|
| Helm release | `forgejo` |
|
||||||
|
| HTTP service | `forgejo-gitea-http` (chart naming; ingress must target this) |
|
||||||
|
| Chart | `gitea-charts/gitea` **12.5.0** (Forgejo-compatible; 12.6+ needs Gitea 1.26 `config edit-ini`) |
|
||||||
|
| Image | `code.forgejo.org/forgejo/forgejo:11.0.3` |
|
||||||
|
| Database | `forgejo-db-rw.databases.svc.cluster.local:5432` |
|
||||||
|
| Kubeconfig | `~/.kube/config-hosteurope` |
|
||||||
|
|
||||||
|
## Bootstrap (first deploy)
|
||||||
|
|
||||||
|
### 1. Database credentials (platform)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ~/railiance-platform
|
||||||
|
# One-time: create and SOPS-encrypt helm/forgejo-db-secret.sops.yaml from template
|
||||||
|
KUBECONFIG=~/.kube/config-hosteurope make forgejo-db-deploy
|
||||||
|
KUBECONFIG=~/.kube/config-hosteurope make forgejo-db-status
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Application secrets (apps)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ~/railiance-apps
|
||||||
|
# Encrypt helm/forgejo-secrets.sops.yaml from template (DB PASSWD must match platform secret)
|
||||||
|
make check-sops
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Deploy Forgejo
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ~/railiance-apps
|
||||||
|
make forgejo-dry-run
|
||||||
|
make forgejo-deploy
|
||||||
|
make forgejo-ingress-deploy
|
||||||
|
make forgejo-ssh-nodeport-deploy # optional; git+ssh via nodePort 30022
|
||||||
|
make forgejo-status
|
||||||
|
make forgejo-smoke
|
||||||
|
```
|
||||||
|
|
||||||
|
## Day-2 operator targets
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make forgejo-status
|
||||||
|
make forgejo-logs
|
||||||
|
make forgejo-smoke
|
||||||
|
```
|
||||||
|
|
||||||
|
## Coexistence with Gitea
|
||||||
|
|
||||||
|
Gitea on coulombcore remains canonical until `RAIL-HO-WP-0005` migration drills
|
||||||
|
and cutover pass. Do not repoint repo remotes until Wave 1 cutover is approved.
|
||||||
|
|
||||||
|
## Related
|
||||||
|
|
||||||
|
- Gitea reference: `~/railiance-forge/Makefile` (`gitea-deploy`)
|
||||||
|
- Drain plan: `the-custodian/docs/coulombcore-drain-placement-plan.md` Wave 1
|
||||||
|
- Onboarding checklist: `docs/s5-app-onboarding-checklist.md`
|
||||||
14
helm/forgejo-registry-values.yaml
Normal file
14
helm/forgejo-registry-values.yaml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
# Public endpoint and package registry settings for Forgejo on railiance01.
|
||||||
|
service:
|
||||||
|
http:
|
||||||
|
type: ClusterIP
|
||||||
|
|
||||||
|
gitea:
|
||||||
|
config:
|
||||||
|
packages:
|
||||||
|
ENABLED: true
|
||||||
|
LIMIT_SIZE_CONTAINER: -1
|
||||||
|
repository:
|
||||||
|
DISABLED_REPO_UNITS: ""
|
||||||
|
server:
|
||||||
|
ROOT_URL: "https://forgejo.coulomb.social/"
|
||||||
15
helm/forgejo-secrets.sops.yaml.template
Normal file
15
helm/forgejo-secrets.sops.yaml.template
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
# Encrypt as helm/forgejo-secrets.sops.yaml before production deploy.
|
||||||
|
# Contains database PASSWD and admin password consumed by the gitea chart.
|
||||||
|
#
|
||||||
|
# gitea:
|
||||||
|
# admin:
|
||||||
|
# password: <generated>
|
||||||
|
# config:
|
||||||
|
# database:
|
||||||
|
# PASSWD: <same as forgejo-db-credentials>
|
||||||
|
gitea:
|
||||||
|
admin:
|
||||||
|
password: REPLACE_WITH_ADMIN_PASSWORD
|
||||||
|
config:
|
||||||
|
database:
|
||||||
|
PASSWD: REPLACE_WITH_DB_PASSWORD
|
||||||
47
helm/forgejo-values.yaml
Normal file
47
helm/forgejo-values.yaml
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
# Non-secret Forgejo Helm values (gitea-charts/gitea chart + Forgejo image).
|
||||||
|
# Layer helm/forgejo-secrets.sops.yaml for database password and admin credentials.
|
||||||
|
service:
|
||||||
|
http:
|
||||||
|
type: ClusterIP
|
||||||
|
|
||||||
|
image:
|
||||||
|
registry: code.forgejo.org
|
||||||
|
repository: forgejo/forgejo
|
||||||
|
tag: "11.0.3"
|
||||||
|
rootless: true
|
||||||
|
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
size: 10Gi
|
||||||
|
|
||||||
|
postgresql:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
postgresql-ha:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
redis-cluster:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
valkey-cluster:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
gitea:
|
||||||
|
admin:
|
||||||
|
username: forgejo_admin
|
||||||
|
email: admin@coulomb.social
|
||||||
|
passwordMode: initialOnlyRequireReset
|
||||||
|
config:
|
||||||
|
database:
|
||||||
|
DB_TYPE: postgres
|
||||||
|
HOST: forgejo-db-rw.databases.svc.cluster.local:5432
|
||||||
|
NAME: forgejo
|
||||||
|
USER: forgejo
|
||||||
|
server:
|
||||||
|
DOMAIN: forgejo.coulomb.social
|
||||||
|
SSH_DOMAIN: forgejo.coulomb.social
|
||||||
|
SSH_PORT: 22
|
||||||
|
SSH_LISTEN_PORT: 2222
|
||||||
|
DISABLE_SSH: false
|
||||||
|
service:
|
||||||
|
DISABLE_REGISTRATION: true
|
||||||
45
manifests/forgejo-ingress.yaml
Normal file
45
manifests/forgejo-ingress.yaml
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: forgejo
|
||||||
|
namespace: forgejo
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: forgejo
|
||||||
|
app.kubernetes.io/instance: forgejo
|
||||||
|
app.kubernetes.io/part-of: railiance-apps
|
||||||
|
railiance/component: forgejo-public-endpoint
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||||
|
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||||
|
traefik.ingress.kubernetes.io/router.tls: "true"
|
||||||
|
spec:
|
||||||
|
ingressClassName: traefik
|
||||||
|
rules:
|
||||||
|
- host: forgejo.coulomb.social
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /api/packages
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: forgejo-gitea-http
|
||||||
|
port:
|
||||||
|
number: 3000
|
||||||
|
- path: /v2
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: forgejo-gitea-http
|
||||||
|
port:
|
||||||
|
number: 3000
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: forgejo-gitea-http
|
||||||
|
port:
|
||||||
|
number: 3000
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- forgejo.coulomb.social
|
||||||
|
secretName: forgejo-tls
|
||||||
21
manifests/forgejo-ssh-nodeport.yaml
Normal file
21
manifests/forgejo-ssh-nodeport.yaml
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Git/SSH access for Forgejo (NodePort pattern mirrors coulombcore Gitea).
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: forgejo-ssh-nodeport
|
||||||
|
namespace: forgejo
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: forgejo
|
||||||
|
app.kubernetes.io/instance: forgejo
|
||||||
|
app.kubernetes.io/part-of: railiance-apps
|
||||||
|
spec:
|
||||||
|
type: NodePort
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/instance: forgejo
|
||||||
|
app.kubernetes.io/name: gitea
|
||||||
|
ports:
|
||||||
|
- name: ssh
|
||||||
|
port: 22
|
||||||
|
targetPort: 2222
|
||||||
|
nodePort: 30022
|
||||||
|
protocol: TCP
|
||||||
9
tools/forgejo-smoke.sh
Executable file
9
tools/forgejo-smoke.sh
Executable file
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
BASE_URL="${FORGEJO_BASE_URL:-https://forgejo.coulomb.social}"
|
||||||
|
|
||||||
|
curl -fsS "${BASE_URL}/" -o /dev/null -w "root_http=%{http_code}\n"
|
||||||
|
# HEAD returns 405 on Forgejo/Gitea; GET returns 401 + Docker-Distribution-Api-Version.
|
||||||
|
curl -sSI -X GET "${BASE_URL}/v2/" | awk 'BEGIN{code=""; ok=0} /^HTTP/{code=$2} /^[Dd]ocker-[Dd]istribution-[Aa]pi-[Vv]ersion:/{ok=1; print "registry_challenge=ok"} END{if (code=="" || !ok) exit 1; if (code!="401" && code!="200") {print "registry_http=" code; exit 1} else {print "registry_http=" code}}'
|
||||||
|
echo "forgejo smoke ok: ${BASE_URL}"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue