chore: fmt [no ci]

This commit is contained in:
2026-06-20 21:17:50 +07:00 Unverified
parent 446aa7d5c8
commit 4eb402c5a9
6 changed files with 290 additions and 14 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ import {
SlipUpload,
} from "../rubgram/admin/@modal/manual/client";
import { DownloadButton } from "../rubgram/client";
import Link from 'next/link';
import Link from "next/link";
const { TMN_DEST_PHONE_NUM, SASTIFY_API_PRIVKEY } = process.env as Record<
string,
+1 -3
View File
@@ -311,9 +311,7 @@ export function SubmissionList({
<SidebarMenuButton
key={s.id}
asChild
className={cn(
((debug && !s.paid) || s.deleted) && "opacity-50",
)}
className={cn(((debug && !s.paid) || s.deleted) && "opacity-50")}
>
<SidebarLink
submission={{ ...s, queue: s.publicQueue }}
+2 -1
View File
@@ -449,7 +449,8 @@ export function TierList({
>
<span>
{type.name} เวอร์ชั่น {version.name} ระดับ
<span className="text-yellow-400">{type.mode}</span> ใช้ได้ถึง{" "}
<span className="text-yellow-400">{type.mode}</span>{" "}
ใช้ได้ถึง{" "}
</span>
<span className="text-green-400">{version.deprecates}</span>
{deleteMode && (
+24 -7
View File
@@ -3,6 +3,7 @@
## Architecture Decisions
### Ingress
- **k3s built-in Traefik**, not nginx.
- Annotations `traefik.ingress.kubernetes.io/response-buffering: "false"` + `read-timeout: "200"` preserve SSE (Server-Sent Events).
- Traefik Middleware `sse-optimizer` caps `maxRequestBodyBytes` at 100 MB (for slip image uploads).
@@ -10,10 +11,12 @@
- External port: **80/443** (standard). `m.dgnr.us` DNS should point at k3s node IP(s). Old port 8604 is retired.
### Namespace
- Everything lives in namespace `buzz`.
- The namespace is created once manually (`kubectl create ns buzz`) and listed in kustomization.yaml.
### Secrets
- **`buzz-env`** Secret created once from `.env`:
```
kubectl create secret generic buzz-env --from-env-file=.env -n buzz
@@ -25,6 +28,7 @@
```
### Database Migration
- **k8s Job** (deploy-time), not in Dockerfile.
- The `drizzle` stage was removed from `Dockerfile`. The build no longer runs `bun dr push`.
- CI creates the `db-migrate` Job imperatively, waits for completion, then updates deployments.
@@ -32,12 +36,14 @@
- Old job is deleted before creating the new one (`kubectl delete job ... --ignore-not-found`).
### Service Discovery
- Frontend Service: `app` (ClusterIP, port 3000).
- Backend reaches frontend at `http://app:3000` (same namespace, k8s DNS resolves `<service>`).
- Backend references in `backend/index.ts:231,279` using `http://app:3000` remain unchanged.
- `lib/auth.ts` `trustedOrigins` includes `http://app.buzz.svc.cluster.local:3000` for completeness.
### CI/CD
- Gitea Actions builds and pushes images as before (same tags: `:frontend`, `:backend`, `:frontend-$SHA`, `:backend-$SHA`).
- Deploy step in `build.yml`:
1. Delete old migration Job, create fresh one with `:frontend-$SHA`, wait for completion.
@@ -45,33 +51,40 @@
- Kustomize is used for initial cluster bootstrap (`kubectl apply -k k8s/`). Subsequent updates use imperative `kubectl set image` because Kustomize's `images` field cannot differentiate two images that share the same image name (different tags). If image naming changes to separate repos (e.g., `buzz-frontend:tag` / `buzz-backend:tag`), switch to `kustomize edit set image` + `kubectl apply -k .`.
### CI Authentication
- **ServiceAccount `ci-deployer`** in namespace `buzz`.
- RBAC Role grants: Deployments (get/list/watch/update/patch), Pods (get/list/watch), Jobs (full CRUD), Services/Ingresses/Middlewares (get/list/watch/create/update/patch).
- Token for the runner: `kubectl create token ci-deployer -n buzz` (or use a long-lived token from a Secret tied to the SA).
- The runner also needs `docker` login access to `mts.dgnr.us:5000` (same as today).
### Replicated Stateful Services (external to buzz namespace)
- **PostgreSQL**: CloudNativePG operator. `DATABASE_URL` in Secret points to the CNPG cluster's read-write service (e.g. `postgres://...@<cluster>-rw.<cnpg-ns>.svc:5432/buzz`).
- **Redis**: redis-operator. `REDIS_URL` in Secret points to the Redis operator's endpoint.
### Container Registry
- **Zot** running in-cluster (namespace `registry`), exposed via ServiceLB on host port 5000.
- All k3s nodes have `/etc/rancher/k3s/registries.yaml` mirroring `mts.dgnr.us:5000` → `http://localhost:5000` (svclb binds host port 5000). k3s must be restarted after writing this file.
- CI runner pushes to `mts.dgnr.us:5000` (Tailscale → `100.75.220.33` → svclb → zot pod).
### Resource Limits
- **app**: 2 replicas, limits 1 CPU / 1 Gi memory, requests 500m / 512 Mi. Liveness probe on `/api/health` (60s interval). Readiness probe same.
- **backend**: 1 replica, limits 1 CPU / 512 Mi memory, requests 250m / 256 Mi. No probes (no HTTP endpoint).
- **db-migrate Job**: limits 1 CPU / 512 Mi, requests 250m / 256 Mi.
### HPA / PDB
- HPA scales `app` on CPU > 70%, min 2 / max 6 replicas (replaces `swarm.autoscale` label).
- PDB ensures min 1 pod always available during voluntary disruptions (node drains, rollouts).
### TLS
- Not configured in manifests. Currently HTTP-only behind Traefik. Add `spec.tls` + cert-manager or k3s Traefik's built-in Let's Encrypt when ready.
## First Deploy (manual bootstrap)
```bash
kubectl create ns buzz
kubectl create secret generic buzz-env --from-env-file=.env -n buzz
@@ -79,6 +92,7 @@ kubectl apply -k k8s/
```
## Subsequent Deploys (CI)
```bash
# In .github/workflows/build.yml
TAG=${{ gitea.sha }}
@@ -108,6 +122,7 @@ kubectl set image deployment/backend backend=mts.dgnr.us:5000/astral/buzz:backen
```
CI runner needs Gitea secret `KUBE_TOKEN` containing the `ci-deployer` SA token. Rotate via:
```bash
kubectl delete secret ci-deployer-token -n buzz && \
kubectl apply -f k8s/service-account.yaml && \
@@ -120,15 +135,17 @@ TOKEN=$(kubectl get secret ci-deployer-token -n buzz -o jsonpath='{.data.token}'
```
## Files Changed from Swarm
| File | Change |
|------|--------|
| `Dockerfile` | Removed `drizzle` stage (migration moved to k8s Job) |
| `lib/auth.ts` | Added `app.buzz.svc.cluster.local:3000` to `trustedOrigins` |
| `.github/workflows/build.yml` | Replaced `docker service update` with k8s deploy commands |
| `nginx/nginx.conf` | Archived — replaced by Traefik Ingress |
| `docker-compose.yml` | Archived — replaced by k8s manifests |
| File | Change |
| ----------------------------- | ----------------------------------------------------------- |
| `Dockerfile` | Removed `drizzle` stage (migration moved to k8s Job) |
| `lib/auth.ts` | Added `app.buzz.svc.cluster.local:3000` to `trustedOrigins` |
| `.github/workflows/build.yml` | Replaced `docker service update` with k8s deploy commands |
| `nginx/nginx.conf` | Archived — replaced by Traefik Ingress |
| `docker-compose.yml` | Archived — replaced by k8s manifests |
## Key Distinctions from Swarm
- No `overlay` network (k8s CNI handles multi-node networking).
- No host port `8604` (Traefik on 80/443).
- Service discovery via k8s DNS, not Swarm DNS.
-1
View File
@@ -6,4 +6,3 @@ metadata:
spec:
buffering:
maxRequestBodyBytes: 104857600
File diff suppressed because one or more lines are too long