Compare commits

..
5 Commits
Author SHA1 Message Date
ericandClaude Opus 5.5 5702010a3d Gitea: sign in only through Dex, send sign-up to /members
Demo / hello (push) Successful in 13s
Disable the password sign-in form so /user/login redirects to Dex,
keep registration enabled for Dex auto-registration, and redirect
/user/sign_up to www.eom.dev/members at the ingress.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 17:56:00 -05:00
ClaudeandClaude Opus 5.5 f56eab28af Poll for gitea rollout instead of using rollout status
Demo / hello (push) Successful in 20s
`kubectl rollout status` fails immediately once a rollout has exceeded
its progress deadline, even if the new pod is about to become ready.
Poll the deployment until replicas, updated and available counts agree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 13:31:04 -05:00
ClaudeandClaude Opus 5.5 584779945d Give PostgreSQL enough CPU to pass its liveness probe
Demo / hello (push) Successful in 18s
With a 150m CPU limit, pg_isready routinely exceeds the 5s probe timeout
under load (e.g. Gitea's startup migration check), so the kubelet kills
postgres mid-query. This is the cause of the long-running restart loop on
gitea-postgresql-0. Raise the limit to one core (request 250m).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 13:28:29 -05:00
ClaudeandClaude Opus 5.5 b81a2d64d0 Pin valkey/postgresql resources; harden runner token step
The live valkey and postgresql StatefulSets had memory limits raised by
hand (8Gi and 2Gi). A helm upgrade reverts those to the bitnami 192Mi
preset, and valkey then OOMs loading its ~3.3GB dataset. Move the limits
into role defaults so upgrades keep them.

Generate the runner token with kubectl exec against the deployment after
waiting for its rollout, with retries, instead of kubernetes.core.k8s_exec
(the control plane's kubernetes python client is too old for it).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 13:05:10 -05:00
ClaudeandClaude Opus 5.5 0f1ed99dfc Log real client IPs and enable Gitea Actions with a runner
Demo / hello (push) Successful in 18s
- Trust X-Forwarded-For from the pod network (10.244.0.0/16) via
  security.REVERSE_PROXY_TRUSTED_PROXIES / REVERSE_PROXY_LIMIT so Gitea
  logs the external client address instead of the ingress-nginx pod IP.
- Set actions.ENABLED explicitly and deploy an instance-wide runner via
  the gitea/actions chart (release "gitea-actions", pinned to 0.1.2).
  The registration token is generated in-cluster and stored in a Secret
  on first run, so no token lives in git or the vault.
- Fix the old actions.yaml, which reused the "gitea" release name and
  would have clobbered the main Gitea release.
- Add a demo workflow (.gitea/workflows/demo.yaml).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 12:56:58 -05:00
5 changed files with 192 additions and 16 deletions
+42
View File
@@ -0,0 +1,42 @@
# Demo workflow showing Gitea Actions running on the in-cluster runner.
name: Demo
on:
push:
workflow_dispatch:
jobs:
hello:
runs-on: ubuntu-latest
steps:
- name: Say hello
run: |
echo "Hello from Gitea Actions on ${{ gitea.server_url }}"
echo "Repository: ${{ gitea.repository }}"
echo "Ref: ${{ gitea.ref }}"
echo "Commit: ${{ gitea.sha }}"
echo "Triggered by: ${{ gitea.actor }} (${{ gitea.event_name }})"
- name: Check out the role
uses: actions/checkout@v4
- name: Show the role layout
run: find . -path ./.git -prune -o -type f -print | sort
- name: Validate YAML
run: |
python3 -c 'import yaml' 2>/dev/null || (apt-get update -qq && apt-get install -y -qq python3-yaml >/dev/null)
python3 - <<'PY'
import pathlib, sys
import yaml
bad = 0
for p in sorted(pathlib.Path('.').rglob('*.y*ml')):
if '.git' in p.parts:
continue
try:
yaml.safe_load(p.read_text())
print(f"ok {p}")
except yaml.YAMLError as e:
bad += 1
print(f"FAIL {p}: {e}")
sys.exit(1 if bad else 0)
PY
+33
View File
@@ -1,3 +1,36 @@
#SPDX-License-Identifier: MIT-0
---
# defaults file for ansible-role-gitea
# CIDRs allowed to set X-Forwarded-For / X-Real-IP for Gitea.
# 10.244.0.0/16 is the cluster pod network, where ingress-nginx runs.
gitea_trusted_proxies: "127.0.0.0/8,::1/128,10.244.0.0/16"
# Resources for chart subcharts. These match the limits previously set by
# hand on the live StatefulSets; the bitnami default presets (192Mi) OOM.
gitea_valkey_resources:
requests:
cpu: 100m
memory: 1Gi
ephemeral-storage: 50Mi
limits:
cpu: 150m
memory: 8Gi
ephemeral-storage: 4Gi
# PostgreSQL needs real CPU: at 150m its liveness probe (pg_isready, 5s
# timeout) times out under load and the kubelet restarts it.
gitea_postgresql_resources:
requests:
cpu: 250m
memory: 128Mi
ephemeral-storage: 50Mi
limits:
cpu: "1"
memory: 2Gi
ephemeral-storage: 2Gi
# Gitea Actions runner (gitea/actions chart)
gitea_actions_enabled: true
gitea_actions_chart_version: 0.1.2
gitea_actions_runner_replicas: 1
gitea_actions_runner_token_secret: gitea-actions-runner-token
+68 -13
View File
@@ -1,23 +1,78 @@
- name: deploy actions
---
# Deploys an instance-wide Gitea Actions runner (act_runner + DinD).
- name: check for existing runner registration token secret
kubernetes.core.k8s_info:
kind: Secret
namespace: gitea
name: "{{ gitea_actions_runner_token_secret }}"
register: runner_token_secret
- name: generate and store a runner registration token
when: runner_token_secret.resources | length == 0
block:
# Poll instead of `kubectl rollout status`, which exits immediately once
# a slow rollout has passed the deployment's progressDeadlineSeconds.
- name: wait for the gitea deployment to finish rolling out
command: >-
kubectl -n gitea get deployment gitea
-o jsonpath={.spec.replicas},{.status.replicas},{.status.updatedReplicas},{.status.availableReplicas}
register: gitea_rollout
until: gitea_rollout.stdout.split(',') | unique | length == 1
retries: 90
delay: 10
changed_when: false
- name: generate instance-level runner registration token
command: kubectl -n gitea exec deployment/gitea -c gitea -- gitea actions generate-runner-token
register: runner_token
retries: 10
delay: 15
until: runner_token.rc == 0 and (runner_token.stdout | trim | length) > 0
changed_when: false
no_log: true
- name: store runner registration token
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Secret
metadata:
name: "{{ gitea_actions_runner_token_secret }}"
namespace: gitea
type: Opaque
stringData:
token: "{{ runner_token.stdout | trim }}"
no_log: true
- name: deploy gitea actions runner
kubernetes.core.helm:
name: gitea
name: gitea-actions
chart_ref: gitea/actions
chart_version: "{{ gitea_actions_chart_version }}"
release_namespace: gitea
create_namespace: true
values:
enabled: true
provisioning:
enabled: true
giteaRootURL: https://gitea.eom.dev
existingSecret: "{{ gitea_actions_runner_token_secret }}"
existingSecretKey: token
statefulset:
actRunner:
replicas: "{{ gitea_actions_runner_replicas }}"
persistence:
size: 1Gi
runner:
config: |
log:
level: debug
cache:
enabled: false
log:
level: info
cache:
enabled: false
container:
require_docker: true
docker_timeout: 300s
runner:
capacity: 2
labels:
- "ubuntu-latest:docker://node:16-bullseye"
- "ubuntu-22.04:docker://node:16-bullseye"
- "ubuntu-20.04:docker://node:16-bullseye"
- "ubuntu-18.04:docker://node:16-buster"
- "ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest"
- "ubuntu-24.04:docker://docker.gitea.com/runner-images:ubuntu-24.04"
- "ubuntu-22.04:docker://docker.gitea.com/runner-images:ubuntu-22.04"
+44
View File
@@ -64,14 +64,26 @@
config:
APP_NAME: "Gitea"
service:
# Keep false: true would also block Dex auto-registration of members.
# The sign-up button is redirected to www.eom.dev/members at ingress.
DISABLE_REGISTRATION: false
SHOW_REGISTRATION_BUTTON: true
# Sign-in goes through Dex only (admin fallback: gitea admin CLI).
ENABLE_PASSWORD_SIGNIN_FORM: false
ENABLE_PASSKEY_AUTHENTICATION: false
DEFAULT_ALLOW_CREATE_ORGANIZATION: false
ALLOW_ONLY_EXTERNAL_REGISTRATION: true
ENABLE_NOTIFY_MAIL: true
EMAIL_DOMAIN_BLOCKLIST: "spammer.com,mailinator.com,tempmail.com,10minutemail.com,guerrillamail.com,dispostable.com,fakemail.com,maildrop.cc,trashmail.com,yopmail.com,techstrategylab.com,timminsgoldminetour.com,claxyn.org,sise.claxyn.org,blyxen.com,seti.blyxen.com,tute.blyxen.com,tula.blyxen.com,sise.blyxen.org,ivolix.com,seti.lyvix.org,tute.lyvix.org,seti.ivolix.org,semo.ivolix.com,elyquin.org,simu.elyquin.org,semo.claxyn.com,sise.oxilv.com,simu.glinxy.org,simu.hivoltz.org,semo.elyquin.com,prisite.online,sise.dravix.org,dravix.org,semo.glinxy.com,glinxy.com,dark-webmarket.com,seti.juxal.org,juxal.org,9e5d.getir.space,getir.space,topcompanygroup.com,6d43.getir.space,9e2d.mikrowellen-tests.com,verifiedlinklist.com,xylzen.com,tapi.xylzen.com,ylixo.com,tapi.ylixo.com,tute.ylixo.com,estrella.glinxy.com,nestmailbox.com,theweifamily.icu,1mail.x24hr.com,8.dnsabr.com,23.8.dnsabr.com,2712.bubbles-swimming.co.uk,anonmails.de,spambog.ru,anonmails.de,virginvoyages.click,travellersrest.click,mailus.virginvoyages.com,tula.hivoltz.org,theblueholiday.click,mailius.virginvoyages.com,travellersrest.click,twitch.work,backlinks.monster,onlinecmail.com,gsasearchenginerankervps.com,seoautomationpro.online"
ENABLE_CAPTCHA: true
REGISTER_EMAIL_CONFIRM: true
security:
# Trust X-Forwarded-For from ingress-nginx (pod network) so Gitea
# logs the real client address instead of the ingress pod IP.
REVERSE_PROXY_LIMIT: 1
REVERSE_PROXY_TRUSTED_PROXIES: "{{ gitea_trusted_proxies }}"
actions:
ENABLED: true
oauth2_client:
ENABLE_AUTO_REGISTRATION: true
UPDATE_AVATAR: true
@@ -89,6 +101,9 @@
DEFAULT_THEME: catppuccin-blue-auto
valkey:
enabled: true
primary:
# The chart's default preset (192Mi) cannot load the existing dataset.
resources: "{{ gitea_valkey_resources }}"
valkey-cluster:
enabled: false
replica:
@@ -113,8 +128,37 @@
password: "{{ gitea_admin_password }}"
database: gitea
primary:
resources: "{{ gitea_postgresql_resources }}"
persistence:
enabled: true
size: 2Ti
postgresql-ha:
enabled: false
- name: Send Gitea's sign-up button to the eom.dev membership site
kubernetes.core.k8s:
state: present
definition:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gitea-signup-redirect
namespace: gitea
annotations:
nginx.ingress.kubernetes.io/temporal-redirect: https://www.eom.dev/members
spec:
ingressClassName: nginx
tls:
- hosts: [gitea.eom.dev]
secretName: gitea-tls
rules:
- host: gitea.eom.dev
http:
paths:
- path: /user/sign_up
pathType: Exact
backend:
service:
name: gitea-http
port:
number: 3000
+5 -3
View File
@@ -2,6 +2,8 @@
---
# tasks file for ansible-role-gitea
- name: gitea
include_tasks: "{{ item }}"
loop:
- gitea.yaml
include_tasks: gitea.yaml
- name: gitea actions runner
include_tasks: actions.yaml
when: gitea_actions_enabled | bool