Compare commits

...

102 Commits

Author SHA1 Message Date
lunarfront-manager
e24786a075 chore: upgrade customer tvs to chart 0.1.102 2026-04-06 11:32:06 +00:00
lunarfront-manager
9d7b10730d chore: upgrade customer tvs to chart 0.1.100 2026-04-05 20:38:44 +00:00
lunarfront-manager
32e391a47f chore: upgrade customer tvs to chart 0.1.98 2026-04-05 20:05:48 +00:00
lunarfront-manager
188dced6a2 chore: upgrade customer tvs to chart 0.1.94 2026-04-05 19:46:29 +00:00
lunarfront-manager
81a4f4fb35 chore: upgrade customer tvs to chart 0.1.91 2026-04-05 17:21:12 +00:00
lunarfront-manager
b32d6b70c4 chore: upgrade customer tvs to chart 0.1.87 2026-04-05 16:50:59 +00:00
lunarfront-manager
22455e6b76 chore: upgrade customer tvs to chart 0.1.86 2026-04-05 16:39:52 +00:00
lunarfront-manager
0aa390fd14 chore: upgrade customer tvs to chart 0.1.78 2026-04-05 16:00:27 +00:00
lunarfront-manager
eeac6ecc2b chore: upgrade customer tvs to chart 0.1.77 2026-04-05 15:53:19 +00:00
Ryan Moon
2075f25f44 fix: add patch verb to manager ArgoCD role for chart upgrades 2026-04-05 10:44:45 -05:00
Ryan Moon
c0b2d0a837 fix: align deployment env vars with lunarfront-secrets; add email + encryption env vars
- Fix secret references: all env vars now read from lunarfront-secrets (was referencing 3 non-existent separate secrets)
- Add ENCRYPTION_KEY, RESEND_API_KEY, MAIL_FROM, BUSINESS_NAME, INITIAL_USER_* env vars to backend container
- Add RESEND_API_KEY to manager deployment from manager-secrets

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 10:28:02 -05:00
lunarfront-manager
16331d0dc6 chore: deprovision customer test 2026-04-05 14:39:53 +00:00
lunarfront-manager
467acbacd7 feat: provision customer tvs 2026-04-05 14:39:32 +00:00
Ryan Moon
7d859ab6d2 fix: add secrets read/patch to manager dev role for SSH key management 2026-04-05 09:36:49 -05:00
Ryan Moon
a677d9c366 fix: add dev namespace role for manager to manage dev pod deployment 2026-04-05 09:28:39 -05:00
Ryan Moon
25238ca677 fix: pin manager to 0.12.2, switch image updater to semver tracking 2026-04-04 19:18:46 -05:00
Ryan Moon
1ba2f9259b fix: remove OAuth env vars, auth handled by Cloudflare Access 2026-04-04 09:10:45 -05:00
Ryan Moon
4686fb558e fix: track devpod versioned tags for reliable image updates 2026-04-04 09:04:53 -05:00
Ryan Moon
ff19e89d73 fix: set imagePullPolicy Always for devpod to always pull latest 2026-04-04 09:02:03 -05:00
Ryan Moon
e8b2115aae fix: ignore replica diff so dev pod scale is not reverted by ArgoCD 2026-04-04 08:49:45 -05:00
Ryan Moon
3fe7985577 fix: mount PVC at /root so home dir persists 2026-04-04 08:43:27 -05:00
Ryan Moon
70466b447d fix: use manager repo with devpod-latest tag for dev pod image 2026-04-04 08:36:05 -05:00
Ryan Moon
0a0237d58f feat: add dev pod chart — code-server + SSH on dedicated node pool 2026-04-04 06:57:07 -05:00
lunarfront-manager
9658e3126c chore: deprovision customer music 2026-04-04 03:03:48 +00:00
lunarfront-manager
d02dbc2448 chore: upgrade all customers to chart 0.1.28 2026-04-04 02:54:19 +00:00
lunarfront-manager
7313af0671 chore: upgrade all customers to chart 0.1.27 2026-04-04 02:48:21 +00:00
lunarfront-manager
c82ddf4b24 chore: upgrade all customers to chart 0.1.25 2026-04-04 02:45:08 +00:00
lunarfront-manager
6c233ae518 chore: upgrade customer music to chart 0.1.1 2026-04-04 02:31:52 +00:00
Ryan Moon
c514466716 fix: pin music and test to chart 0.0.29 2026-04-03 21:20:37 -05:00
lunarfront-manager
edfbdaf3a0 feat: provision customer test 2026-04-04 01:49:08 +00:00
lunarfront-manager
bf4f867420 feat: provision customer music 2026-04-04 01:45:20 +00:00
lunarfront-manager
12290293a8 chore: deprovision customer music 2026-04-04 01:41:49 +00:00
Ryan Moon
f3ac743d1b feat: add Cloudflare env vars to manager deployment 2026-04-03 20:40:39 -05:00
Ryan Moon
8bb6605260 fix: update music ingress host to lunarfront.tech 2026-04-03 20:37:04 -05:00
Ryan Moon
c34f43b883 fix: pin music to chart 0.0.29 2026-04-03 20:35:49 -05:00
lunarfront-manager
68afe929bb feat: provision customer music 2026-04-04 01:26:11 +00:00
Ryan Moon
7aff9f31ec feat: add SPACES_KEY and SPACES_SECRET to manager deployment 2026-04-03 20:22:08 -05:00
lunarfront-manager
54e726c7cc chore: deprovision customer music 2026-04-04 01:18:12 +00:00
Ryan Moon
d9292aeab8 feat: add pods list permission to manager ClusterRole 2026-04-03 20:07:26 -05:00
Ryan Moon
986c30a694 feat: add MANAGED_VALKEY_URL env var to manager deployment 2026-04-03 19:48:27 -05:00
Ryan Moon
aa58dbcc17 fix: use semver constraint for music customer chart revision 2026-04-03 19:43:13 -05:00
lunarfront-manager
e74c05e423 feat: provision customer music 2026-04-04 00:39:29 +00:00
Ryan Moon
d0cb06c9df feat: add ClusterRole for customer provisioning, register DOCR helm repo, remove stale test customer 2026-04-03 18:53:11 -05:00
Ryan Moon
ea926e1972 feat: add App of Apps to auto-deploy customers from customers/ dir 2026-04-03 18:41:28 -05:00
lunarfront-manager
655146d6b8 feat: provision customer test 2026-04-03 23:37:46 +00:00
lunarfront-manager
6ff42ebe88 chore: deprovision customer test 2026-04-03 23:33:05 +00:00
lunarfront-manager
4635853af6 feat: provision customer test 2026-04-03 23:14:23 +00:00
Ryan Moon
3191f697b5 feat: add kustomization for image updater support 2026-04-03 15:33:25 -05:00
Ryan Moon
8badd440ed feat: use ArgoCD Image Updater for manager auto-deploy 2026-04-03 15:32:12 -05:00
lunarfront-bot
2b59d7733f chore: update manager image to v0.2.1 2026-04-03 20:28:37 +00:00
Ryan Moon
26170018e7 chore: pin manager image tag for auto-update 2026-04-03 15:27:19 -05:00
Ryan Moon
e5d7bf35b9 fix: update manager image path to match DOCR repo 2026-04-03 15:22:11 -05:00
Ryan Moon
7c590daa75 fix: remove nginx IP whitelist, access controlled by Cloudflare and JWT 2026-04-03 15:07:20 -05:00
Ryan Moon
0680d89474 feat: pull manager image from DOCR 2026-04-03 08:40:19 -05:00
Ryan Moon
8d53a603b0 fix: run haproxy as root to bind port 443 2026-04-03 08:04:10 -05:00
Ryan Moon
46fda1f393 fix: add NET_BIND_SERVICE capability to haproxy for port 443 2026-04-03 08:02:14 -05:00
Ryan Moon
0d18d36d18 fix: increase haproxy memory limit to 128Mi 2026-04-03 08:01:16 -05:00
Ryan Moon
0737bf0e69 fix: add haproxy sidecar to prepend PROXY protocol for registry pushes
Routes git.lunarfront.tech:443 through a local haproxy that adds the
PROXY protocol header nginx requires, bypassing the DO LB hairpin.
2026-04-03 07:59:25 -05:00
Ryan Moon
78e2a36859 feat: add JWT_SECRET env var to manager deployment 2026-04-03 07:41:40 -05:00
Ryan Moon
56cb7ce6dc fix: auto-register runner if .runner file missing, store state in /data
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 07:32:18 -05:00
Ryan Moon
a6926c4b04 fix: use nc TCP check for dind readiness instead of docker info
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 07:30:01 -05:00
Ryan Moon
f82fc1252c fix: move dind wait into runner container command to fix init deadlock 2026-04-03 07:23:43 -05:00
Ryan Moon
a7facce892 fix: use Recreate strategy for single-replica RWO PVC workloads (gitea, runner) 2026-04-03 07:17:49 -05:00
Ryan Moon
2af2ceb91c feat: pin all system workloads to system node pool 2026-04-03 07:12:15 -05:00
Ryan Moon
c82a533c61 feat: add manager db to pgbouncer 2026-04-03 06:51:55 -05:00
Ryan Moon
899dc7980f feat: add manager deployment manifests 2026-04-03 06:49:58 -05:00
Ryan Moon
bda73afa18 fix: add hostAliases for git.lunarfront.tech so dind can reach registry via nginx 2026-04-03 06:48:35 -05:00
Ryan Moon
705dab6e49 fix: add init container to wait for dind before starting runner 2026-04-03 06:37:57 -05:00
Ryan Moon
fd5be2805f fix: use internal Gitea service URL to avoid LB hairpin on gRPC 2026-04-03 06:36:39 -05:00
Ryan Moon
285ae3665c fix: route runner to nginx ClusterIP to avoid DO LB hairpin 2026-04-03 06:33:08 -05:00
Ryan Moon
87c0ed0931 chore: remove windmill pgbouncer config and values 2026-04-03 06:16:21 -05:00
Ryan Moon
9f3abebf32 chore: remove windmill 2026-04-03 06:15:15 -05:00
Ryan Moon
07899caa9c fix: increase windmill pool size to 10 to prevent query_wait_timeout 2026-04-03 06:13:37 -05:00
Ryan Moon
b0037459ee fix: use session pooling for windmill (prepared statements incompatible with transaction mode) 2026-04-02 22:29:58 -05:00
Ryan Moon
1cd7e9a818 fix: use session pooling for gitea (prepared statements incompatible with transaction mode) 2026-04-02 22:27:46 -05:00
Ryan Moon
969948691f fix: reduce pool size to 3, add server_reset_query for transaction mode 2026-04-02 22:26:17 -05:00
Ryan Moon
9858867bae fix: disable SSL for gitea→pgbouncer connection (pgbouncer handles TLS to DO) 2026-04-02 22:21:10 -05:00
Ryan Moon
964ddad2d0 feat: switch gitea+windmill to shared pgbouncer, disable windmill's built-in 2026-04-02 22:19:17 -05:00
Ryan Moon
1ba206283e fix: use correct pgbouncer binary path /opt/pgbouncer/pgbouncer 2026-04-02 22:17:28 -05:00
Ryan Moon
e85afcbe7a fix: override pgbouncer entrypoint to use config file directly 2026-04-02 22:16:21 -05:00
Ryan Moon
46c78cc11f fix: use pgbouncer/pgbouncer:latest image tag 2026-04-02 22:14:41 -05:00
Ryan Moon
54591c43ef feat: add shared PgBouncer deployment 2026-04-02 22:13:34 -05:00
Ryan Moon
ed98974c91 fix: enable PgBouncer to manage Postgres connection pool 2026-04-02 22:00:58 -05:00
Ryan Moon
ba667b9edd fix: use baseDomain/baseProtocol instead of baseUrl for Windmill ingress 2026-04-02 22:00:10 -05:00
Ryan Moon
951b9c15a7 fix: remove manual hosts from ingress, let chart derive from baseUrl 2026-04-02 21:58:25 -05:00
Ryan Moon
683f01213a fix: set 1 replica per worker group, lower resource requests 2026-04-02 21:56:16 -05:00
Ryan Moon
68ad0a744f fix: reduce Windmill worker resource requests 2026-04-02 21:52:12 -05:00
Ryan Moon
67def0a249 fix: correct Windmill helm chart repo URL 2026-04-02 21:42:22 -05:00
Ryan Moon
e3fe6bac3e feat: add Windmill deployment 2026-04-02 21:39:54 -05:00
Ryan Moon
6d73a50065 feat: add cert-manager-config ArgoCD app 2026-04-02 21:32:45 -05:00
Ryan Moon
4963f26cfc fix: use DNS-01 Cloudflare solver for cert-manager 2026-04-02 21:30:11 -05:00
Ryan Moon
2c2f18bb25 feat: switch to Let's Encrypt cert via cert-manager 2026-04-02 21:24:10 -05:00
Ryan Moon
e91187cb89 fix: revert to HTTPS for runner, removed git from WAF 2026-04-02 21:11:44 -05:00
Ryan Moon
c385c80cf3 fix: enable Gitea Actions explicitly in config 2026-04-02 21:02:41 -05:00
Ryan Moon
f7a92e1237 fix: use internal cluster URL for runner to bypass Cloudflare WAF 2026-04-02 20:56:47 -05:00
Ryan Moon
da841f37e9 fix: use SSH URL for ArgoCD app sources to match deploy key credential 2026-04-02 20:49:59 -05:00
Ryan Moon
d3e1b398c6 feat: rename git2/registry to git.lunarfront.tech 2026-04-02 20:43:00 -05:00
Ryan Moon
73f77b2f9a fix: remove nginx body size limit for container registry pushes 2026-04-02 20:30:35 -05:00
Ryan Moon
a938a3dcea fix: add PVC for runner state to persist registration across restarts 2026-04-02 19:57:07 -05:00
Ryan Moon
07dbdb5f39 fix: revert to plain act_runner:latest, let dind sidecar handle docker 2026-04-02 19:20:50 -05:00
Ryan Moon
17e0ffacea fix: use catthehacker docker images for runner labels (host mode lacks node) 2026-04-02 19:18:40 -05:00
Ryan Moon
2614b7adcf fix: use dind-rootless runner image for docker socket access 2026-04-02 19:16:54 -05:00
32 changed files with 821 additions and 23 deletions

View File

@@ -6,7 +6,7 @@ metadata:
spec:
project: default
source:
repoURL: https://git.lunarfront.tech/ryan/lunarfront-charts.git
repoURL: ssh://git@git-ssh.lunarfront.tech/ryan/lunarfront-charts.git
targetRevision: main
path: charts/lunarfront
helm:

View File

@@ -0,0 +1,20 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: cert-manager-config
namespace: argocd
spec:
project: default
source:
repoURL: ssh://git@git-ssh.lunarfront.tech/ryan/lunarfront-charts.git
targetRevision: main
path: cert-manager
destination:
server: https://kubernetes.default.svc
namespace: cert-manager
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true

18
argocd/customers-app.yaml Normal file
View File

@@ -0,0 +1,18 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: customers
namespace: argocd
spec:
project: default
source:
repoURL: ssh://git@git-ssh.lunarfront.tech/ryan/lunarfront-charts.git
targetRevision: main
path: customers
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true

31
argocd/dev-app.yaml Normal file
View File

@@ -0,0 +1,31 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: dev
namespace: argocd
annotations:
argocd-image-updater.argoproj.io/image-list: dev=registry.digitalocean.com/lunarfront/manager
argocd-image-updater.argoproj.io/dev.update-strategy: name
argocd-image-updater.argoproj.io/dev.allow-tags: regexp:^devpod-
argocd-image-updater.argoproj.io/write-back-method: argocd
spec:
project: default
source:
repoURL: ssh://git@git-ssh.lunarfront.tech/ryan/lunarfront-charts.git
targetRevision: main
path: dev
destination:
server: https://kubernetes.default.svc
namespace: dev
ignoreDifferences:
- group: apps
kind: Deployment
name: dev
jsonPointers:
- /spec/replicas
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true

View File

@@ -19,7 +19,7 @@ spec:
helm:
valueFiles:
- $values/gitea/values.yaml
- repoURL: https://git2.lunarfront.tech/ryan/lunarfront-charts.git
- repoURL: ssh://git@git-ssh.lunarfront.tech/ryan/lunarfront-charts.git
targetRevision: main
ref: values
destination:

25
argocd/manager-app.yaml Normal file
View File

@@ -0,0 +1,25 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: manager
namespace: argocd
annotations:
argocd-image-updater.argoproj.io/image-list: manager=registry.digitalocean.com/lunarfront/manager
argocd-image-updater.argoproj.io/manager.update-strategy: semver
argocd-image-updater.argoproj.io/manager.allow-tags: regexp:^\d+\.\d+\.\d+$
argocd-image-updater.argoproj.io/write-back-method: argocd
spec:
project: default
source:
repoURL: ssh://git@git-ssh.lunarfront.tech/ryan/lunarfront-charts.git
targetRevision: main
path: manager
destination:
server: https://kubernetes.default.svc
namespace: manager
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true

20
argocd/pgbouncer-app.yaml Normal file
View File

@@ -0,0 +1,20 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: pgbouncer
namespace: argocd
spec:
project: default
source:
repoURL: ssh://git@git-ssh.lunarfront.tech/ryan/lunarfront-charts.git
targetRevision: main
path: pgbouncer
destination:
server: https://kubernetes.default.svc
namespace: pgbouncer
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true

View File

@@ -6,7 +6,7 @@ metadata:
spec:
project: default
source:
repoURL: https://git2.lunarfront.tech/ryan/lunarfront-charts.git
repoURL: ssh://git@git-ssh.lunarfront.tech/ryan/lunarfront-charts.git
targetRevision: main
path: runner
destination:

View File

@@ -0,0 +1,16 @@
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: ryan@lunarfront.tech
privateKeySecretRef:
name: letsencrypt-prod-key
solvers:
- dns01:
cloudflare:
apiTokenSecretRef:
name: cloudflare-api-token
key: api-token

View File

@@ -28,18 +28,92 @@ spec:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: {{ .Values.database.secretName }}
key: url
name: lunarfront-secrets
key: database-url
- name: REDIS_URL
valueFrom:
secretKeyRef:
name: {{ .Values.redis.secretName }}
key: url
name: lunarfront-secrets
key: redis-url
- name: REDIS_KEY_PREFIX
valueFrom:
secretKeyRef:
name: lunarfront-secrets
key: redis-key-prefix
- name: JWT_SECRET
valueFrom:
secretKeyRef:
name: {{ .Values.auth.secretName }}
key: secret
name: lunarfront-secrets
key: jwt-secret
- name: SPACES_KEY
valueFrom:
secretKeyRef:
name: lunarfront-secrets
key: spaces-key
- name: SPACES_SECRET
valueFrom:
secretKeyRef:
name: lunarfront-secrets
key: spaces-secret
- name: SPACES_BUCKET
valueFrom:
secretKeyRef:
name: lunarfront-secrets
key: spaces-bucket
- name: SPACES_ENDPOINT
valueFrom:
secretKeyRef:
name: lunarfront-secrets
key: spaces-endpoint
- name: SPACES_PREFIX
valueFrom:
secretKeyRef:
name: lunarfront-secrets
key: spaces-prefix
- name: ENCRYPTION_KEY
valueFrom:
secretKeyRef:
name: lunarfront-secrets
key: encryption-key
- name: RESEND_API_KEY
valueFrom:
secretKeyRef:
name: lunarfront-secrets
key: resend-api-key
- name: MAIL_FROM
valueFrom:
secretKeyRef:
name: lunarfront-secrets
key: mail-from
- name: BUSINESS_NAME
valueFrom:
secretKeyRef:
name: lunarfront-secrets
key: business-name
- name: INITIAL_USER_EMAIL
valueFrom:
secretKeyRef:
name: lunarfront-secrets
key: initial-user-email
optional: true
- name: INITIAL_USER_PASSWORD
valueFrom:
secretKeyRef:
name: lunarfront-secrets
key: initial-user-password
optional: true
- name: INITIAL_USER_FIRST_NAME
valueFrom:
secretKeyRef:
name: lunarfront-secrets
key: initial-user-first-name
optional: true
- name: INITIAL_USER_LAST_NAME
valueFrom:
secretKeyRef:
name: lunarfront-secrets
key: initial-user-last-name
optional: true
resources:
{{- toYaml .Values.resources.backend | nindent 12 }}
livenessProbe:

View File

@@ -2,11 +2,11 @@
image:
backend:
repository: registry.lunarfront.tech/ryan/lunarfront-app
repository: git.lunarfront.tech/ryan/lunarfront-app
tag: latest
pullPolicy: Always
frontend:
repository: registry.lunarfront.tech/ryan/lunarfront-frontend
repository: git.lunarfront.tech/ryan/lunarfront-frontend
tag: latest
pullPolicy: Always

24
customers/tvs.yaml Normal file
View File

@@ -0,0 +1,24 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: customer-tvs
namespace: argocd
spec:
project: default
source:
repoURL: registry.digitalocean.com/lunarfront
chart: lunarfront
targetRevision: "0.1.102"
helm:
parameters:
- name: ingress.host
value: tvs.lunarfront.tech
destination:
server: https://kubernetes.default.svc
namespace: customer-tvs
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true

54
dev/deployment.yaml Normal file
View File

@@ -0,0 +1,54 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: dev
namespace: dev
spec:
replicas: 0
selector:
matchLabels:
app: dev
template:
metadata:
labels:
app: dev
spec:
nodeSelector:
role: dev
tolerations:
- key: dedicated
value: dev
effect: NoSchedule
imagePullSecrets:
- name: registry-lunarfront
containers:
- name: dev
image: registry.digitalocean.com/lunarfront/manager:devpod-latest
imagePullPolicy: Always
ports:
- containerPort: 8080
name: web
- containerPort: 22
name: ssh
env:
- name: SSH_AUTHORIZED_KEYS
valueFrom:
secretKeyRef:
name: dev-secrets
key: ssh-authorized-keys
- name: ANTHROPIC_API_KEY
valueFrom:
secretKeyRef:
name: dev-secrets
key: anthropic-api-key
volumeMounts:
- name: workspace
mountPath: /root
resources:
requests:
cpu: 500m
memory: 1Gi
volumes:
- name: workspace
persistentVolumeClaim:
claimName: dev-workspace

25
dev/ingress.yaml Normal file
View File

@@ -0,0 +1,25 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dev
namespace: dev
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
rules:
- host: dev.lunarfront.tech
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: dev
port:
number: 8080
tls:
- secretName: dev-lunarfront-tech-tls
hosts:
- dev.lunarfront.tech

4
dev/namespace.yaml Normal file
View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: dev

12
dev/pvc.yaml Normal file
View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dev-workspace
namespace: dev
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Gi
storageClassName: do-block-storage

4
dev/secret.yaml Normal file
View File

@@ -0,0 +1,4 @@
# Managed externally — apply manually:
# kubectl create secret generic dev-secrets -n dev \
# --from-literal=code-server-password=<password> \
# --from-literal=ssh-authorized-keys="<your-public-key>"

25
dev/services.yaml Normal file
View File

@@ -0,0 +1,25 @@
apiVersion: v1
kind: Service
metadata:
name: dev
namespace: dev
spec:
selector:
app: dev
ports:
- name: web
port: 8080
targetPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: dev-ssh
namespace: dev
spec:
selector:
app: dev
ports:
- name: ssh
port: 22
targetPort: 22

View File

@@ -6,20 +6,22 @@ gitea:
config:
server:
DOMAIN: git2.lunarfront.tech
ROOT_URL: https://git2.lunarfront.tech
SSH_DOMAIN: git2-ssh.lunarfront.tech
DOMAIN: git.lunarfront.tech
ROOT_URL: https://git.lunarfront.tech
SSH_DOMAIN: git-ssh.lunarfront.tech
SSH_PORT: 22
START_SSH_SERVER: true
database:
DB_TYPE: postgres
SSL_MODE: require
SSL_MODE: disable
session:
PROVIDER: db
cache:
ADAPTER: memory
queue:
TYPE: level
actions:
ENABLED: true
additionalConfigFromEnvs:
- name: GITEA__database__HOST
@@ -67,7 +69,7 @@ service:
clusterIP: None
port: 22
annotations:
external-dns.alpha.kubernetes.io/hostname: git2-ssh.lunarfront.tech
external-dns.alpha.kubernetes.io/hostname: git-ssh.lunarfront.tech
external-dns.alpha.kubernetes.io/target: "167.99.21.170"
ingress:
@@ -75,15 +77,23 @@ ingress:
className: nginx
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "0"
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: git2.lunarfront.tech
- host: git.lunarfront.tech
paths:
- path: /
pathType: Prefix
tls:
- secretName: cloudflare-origin-cert
- secretName: git-lunarfront-tech-tls
hosts:
- git2.lunarfront.tech
- git.lunarfront.tech
strategy:
type: Recreate
nodeSelector:
role: system
resources:
requests:

View File

@@ -5,3 +5,4 @@ metadata:
namespace: ingress-nginx
data:
"22": "gitea/gitea-ssh:22"
"2222": "dev/dev-ssh:22"

107
manager/deployment.yaml Normal file
View File

@@ -0,0 +1,107 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: manager
namespace: manager
spec:
replicas: 1
selector:
matchLabels:
app: manager
template:
metadata:
labels:
app: manager
spec:
serviceAccountName: manager
nodeSelector:
role: system
imagePullSecrets:
- name: registry-lunarfront
containers:
- name: manager
image: registry.digitalocean.com/lunarfront/manager:0.12.2
ports:
- containerPort: 3000
env:
- name: PORT
value: "3000"
- name: DO_API_TOKEN
valueFrom:
secretKeyRef:
name: manager-secrets
key: do-api-token
- name: DO_DB_CLUSTER_ID
valueFrom:
secretKeyRef:
name: manager-secrets
key: do-db-cluster-id
- name: GIT_SSH_KEY
valueFrom:
secretKeyRef:
name: manager-secrets
key: git-ssh-key
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: manager-secrets
key: database-url
- name: DOADMIN_DATABASE_URL
valueFrom:
secretKeyRef:
name: manager-secrets
key: doadmin-database-url
- name: JWT_SECRET
valueFrom:
secretKeyRef:
name: manager-secrets
key: jwt-secret
- name: MANAGED_VALKEY_URL
valueFrom:
secretKeyRef:
name: manager-secrets
key: managed-valkey-url
- name: SPACES_KEY
valueFrom:
secretKeyRef:
name: manager-secrets
key: spaces-key
- name: SPACES_SECRET
valueFrom:
secretKeyRef:
name: manager-secrets
key: spaces-secret
- name: CF_API_TOKEN
valueFrom:
secretKeyRef:
name: manager-secrets
key: cf-api-token
- name: CF_ZONE_ID
valueFrom:
secretKeyRef:
name: manager-secrets
key: cf-zone-id
- name: RESEND_API_KEY
valueFrom:
secretKeyRef:
name: manager-secrets
key: resend-api-key
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10

25
manager/ingress.yaml Normal file
View File

@@ -0,0 +1,25 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: manager
namespace: manager
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
rules:
- host: manager.lunarfront.tech
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: manager
port:
number: 3000
tls:
- secretName: manager-lunarfront-tech-tls
hosts:
- manager.lunarfront.tech

View File

@@ -0,0 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
- ingress.yaml
- rbac.yaml

125
manager/rbac.yaml Normal file
View File

@@ -0,0 +1,125 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: manager
namespace: manager
---
# pgbouncer config management
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: manager-pgbouncer
namespace: pgbouncer
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["pgbouncer-config"]
verbs: ["get", "patch"]
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["pgbouncer-userlist"]
verbs: ["get", "patch"]
- apiGroups: ["apps"]
resources: ["deployments"]
resourceNames: ["pgbouncer"]
verbs: ["get", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: manager-pgbouncer
namespace: pgbouncer
subjects:
- kind: ServiceAccount
name: manager
namespace: manager
roleRef:
kind: Role
apiGroup: rbac.authorization.k8s.io
name: manager-pgbouncer
---
# ArgoCD application management
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: manager-argocd
namespace: argocd
rules:
- apiGroups: ["argoproj.io"]
resources: ["applications"]
verbs: ["get", "create", "delete", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: manager-argocd
namespace: argocd
subjects:
- kind: ServiceAccount
name: manager
namespace: manager
roleRef:
kind: Role
apiGroup: rbac.authorization.k8s.io
name: manager-argocd
---
# Dev pod management
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: manager-dev
namespace: dev
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "patch", "update"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["dev-secrets"]
verbs: ["get", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: manager-dev
namespace: dev
subjects:
- kind: ServiceAccount
name: manager
namespace: manager
roleRef:
kind: Role
apiGroup: rbac.authorization.k8s.io
name: manager-dev
---
# Cluster-wide: create/delete customer namespaces and manage secrets within them
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: manager-customer-provisioner
rules:
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "create", "delete"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "create", "delete", "patch"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: manager-customer-provisioner
subjects:
- kind: ServiceAccount
name: manager
namespace: manager
roleRef:
kind: ClusterRole
apiGroup: rbac.authorization.k8s.io
name: manager-customer-provisioner

11
manager/service.yaml Normal file
View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: Service
metadata:
name: manager
namespace: manager
spec:
selector:
app: manager
ports:
- port: 3000
targetPort: 3000

26
pgbouncer/configmap.yaml Normal file
View File

@@ -0,0 +1,26 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: pgbouncer-config
namespace: pgbouncer
data:
pgbouncer.ini: |
[databases]
gitea = host=lunarfront-postgres-do-user-35277853-0.e.db.ondigitalocean.com port=25060 dbname=gitea user=gitea pool_mode=session pool_size=3
manager = host=lunarfront-postgres-do-user-35277853-0.e.db.ondigitalocean.com port=25060 dbname=manager user=manager pool_mode=session pool_size=3
[pgbouncer]
listen_port = 5432
listen_addr = 0.0.0.0
auth_type = plain
auth_file = /etc/pgbouncer/userlist.txt
pool_mode = transaction
max_client_conn = 200
default_pool_size = 3
min_pool_size = 0
reserve_pool_size = 1
server_tls_sslmode = require
server_reset_query = DISCARD ALL
ignore_startup_parameters = extra_float_digits
log_connections = 0
log_disconnections = 0

54
pgbouncer/deployment.yaml Normal file
View File

@@ -0,0 +1,54 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: pgbouncer
namespace: pgbouncer
spec:
replicas: 1
selector:
matchLabels:
app: pgbouncer
template:
metadata:
labels:
app: pgbouncer
spec:
nodeSelector:
role: system
containers:
- name: pgbouncer
image: pgbouncer/pgbouncer:latest
command: ["/opt/pgbouncer/pgbouncer", "/etc/pgbouncer/pgbouncer.ini"]
ports:
- containerPort: 5432
volumeMounts:
- name: config
mountPath: /etc/pgbouncer/pgbouncer.ini
subPath: pgbouncer.ini
- name: userlist
mountPath: /etc/pgbouncer/userlist.txt
subPath: userlist.txt
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
cpu: 200m
memory: 64Mi
livenessProbe:
tcpSocket:
port: 5432
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
tcpSocket:
port: 5432
initialDelaySeconds: 5
periodSeconds: 10
volumes:
- name: config
configMap:
name: pgbouncer-config
- name: userlist
secret:
secretName: pgbouncer-userlist

11
pgbouncer/service.yaml Normal file
View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: Service
metadata:
name: pgbouncer
namespace: pgbouncer
spec:
selector:
app: pgbouncer
ports:
- port: 5432
targetPort: 5432

View File

@@ -7,9 +7,9 @@ data:
config.yaml: |
runner:
labels:
- "ubuntu-latest:host"
- "ubuntu-22.04:host"
- "ubuntu-24.04:host"
- "ubuntu-latest:docker://catthehacker/ubuntu:act-22.04"
- "ubuntu-22.04:docker://catthehacker/ubuntu:act-22.04"
- "ubuntu-24.04:docker://catthehacker/ubuntu:act-24.04"
container:
docker_host: tcp://localhost:2375
network: host

View File

@@ -5,6 +5,8 @@ metadata:
namespace: runner
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: gitea-runner
@@ -13,9 +15,17 @@ spec:
labels:
app: gitea-runner
spec:
nodeSelector:
role: system
hostAliases:
- ip: 127.0.0.1
hostnames:
- git.lunarfront.tech
containers:
- name: runner
image: gitea/act_runner:latest
workingDir: /data
command: ["sh", "-c", "until nc -z localhost 2375 2>/dev/null; do echo 'waiting for dind...'; sleep 2; done && if [ ! -f /data/.runner ]; then /usr/local/bin/act_runner register --no-interactive --instance \"$GITEA_INSTANCE_URL\" --token \"$GITEA_RUNNER_REGISTRATION_TOKEN\" --name \"$GITEA_RUNNER_NAME\" --config \"$CONFIG_FILE\"; fi && exec /usr/local/bin/act_runner daemon --config \"$CONFIG_FILE\""]
resources:
requests:
cpu: 100m
@@ -25,7 +35,7 @@ spec:
memory: 2Gi
env:
- name: GITEA_INSTANCE_URL
value: https://git2.lunarfront.tech
value: http://gitea-http.gitea.svc.cluster.local:3000
- name: GITEA_RUNNER_REGISTRATION_TOKEN
valueFrom:
secretKeyRef:
@@ -42,6 +52,23 @@ spec:
volumeMounts:
- name: runner-config
mountPath: /etc/runner
- name: runner-data
mountPath: /data
- name: registry-proxy
image: haproxy:alpine
securityContext:
runAsUser: 0
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
cpu: 100m
memory: 128Mi
volumeMounts:
- name: haproxy-config
mountPath: /usr/local/etc/haproxy
- name: dind
image: docker:dind
@@ -63,3 +90,9 @@ spec:
- name: runner-config
configMap:
name: gitea-runner-config
- name: runner-data
persistentVolumeClaim:
claimName: gitea-runner-data
- name: haproxy-config
configMap:
name: runner-haproxy-config

View File

@@ -0,0 +1,24 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: runner-haproxy-config
namespace: runner
data:
haproxy.cfg: |
global
daemon
log stdout format raw local0
defaults
mode tcp
log global
timeout connect 5s
timeout client 30s
timeout server 30s
frontend registry
bind 0.0.0.0:443
default_backend nginx
backend nginx
server nginx ingress-nginx-controller.ingress-nginx.svc.cluster.local:443 send-proxy

12
runner/pvc.yaml Normal file
View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: gitea-runner-data
namespace: runner
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: do-block-storage