docs: add deployment playbooks and templates
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
FROM --platform=$BUILDPLATFORM oven/bun:1.3.14-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN bun install --frozen-lockfile
|
||||
RUN bun build --compile --outfile #APP_NAME src/index.ts
|
||||
|
||||
FROM --platform=#PLATFORM alpine:3.22
|
||||
WORKDIR /app
|
||||
RUN apk add --no-cache libstdc++ libgcc
|
||||
COPY --from=builder /app/#APP_NAME ./#APP_NAME
|
||||
EXPOSE 7000
|
||||
CMD ["./#APP_NAME"]
|
||||
@@ -0,0 +1,3 @@
|
||||
# On-Demand Discord Bot Template
|
||||
|
||||
For Bun-based bots that expose readiness endpoints for Kubernetes probes.
|
||||
@@ -0,0 +1 @@
|
||||
DISCORD_TOKEN=
|
||||
@@ -0,0 +1,32 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: #APP_NAME
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: #APP_NAME
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: #APP_NAME
|
||||
from: #APP_NAME
|
||||
spec:
|
||||
containers:
|
||||
- name: #APP_NAME
|
||||
image: #IMAGE
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: #SECRET_NAME
|
||||
ports:
|
||||
- containerPort: 7000
|
||||
name: probe
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: probe
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /readyz
|
||||
port: probe
|
||||
@@ -0,0 +1,6 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
resources:
|
||||
- namespace.yaml
|
||||
- deployment.yaml
|
||||
@@ -0,0 +1,4 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: #NAMESPACE
|
||||
@@ -0,0 +1,21 @@
|
||||
import { $, env } from "bun";
|
||||
|
||||
if ("K_ACTION" in env) {
|
||||
switch (env.K_ACTION) {
|
||||
case "up":
|
||||
await $`docker buildx build --platform #PLATFORM -t #IMAGE --push .`;
|
||||
await $`kubectl apply -k k8s/overlays/prod`;
|
||||
await $`kubectl rollout restart deployment #APP_NAME -n #NAMESPACE`;
|
||||
break;
|
||||
case "push_env":
|
||||
await $`kubectl create secret generic #SECRET_NAME --from-env-file=.env --dry-run=client -o yaml -n #NAMESPACE | kubectl apply -f -`;
|
||||
break;
|
||||
case "pull_env":
|
||||
await $`kubectl get secret #SECRET_NAME -n #NAMESPACE -o go-template='{{range $k,$v := .data}}{{$k}}={{$v|base64decode}}{{"\n"}}{{end}}' > .env`;
|
||||
break;
|
||||
case "logs":
|
||||
await $`kubectl logs -f -l from=#APP_NAME -n #NAMESPACE`;
|
||||
break;
|
||||
}
|
||||
process.exit();
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
namespace: #NAMESPACE
|
||||
|
||||
resources:
|
||||
- ../../base
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"scripts": {
|
||||
"up": "K_ACTION=up bun k8s/index.ts",
|
||||
"logs": "K_ACTION=logs bun k8s/index.ts",
|
||||
"env:pull": "K_ACTION=pull_env bun k8s/index.ts",
|
||||
"env:push": "K_ACTION=push_env bun k8s/index.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.3.14"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { serve } from "bun";
|
||||
|
||||
const subsystems = ["discord"] as const;
|
||||
type Subsystem = (typeof subsystems)[number];
|
||||
|
||||
const readiness = Object.fromEntries(subsystems.map((e) => [e, false])) as Record<Subsystem, boolean>;
|
||||
|
||||
serve({
|
||||
port: 7000,
|
||||
routes: {
|
||||
"/healthz": new Response("ok"),
|
||||
"/readyz": () => {
|
||||
const ok = subsystems.every((key) => readiness[key]);
|
||||
return Response.json({ ready: ok, subsystems: readiness }, { status: ok ? 200 : 503 });
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export function setReady(key: Subsystem, ready = true) {
|
||||
readiness[key] = ready;
|
||||
}
|
||||
Reference in New Issue
Block a user