Add K3s dev deployment setup for single-node VPS
Mirrors the prod deploy-k3s/ setup but runs all services in-cluster on a single node: PostgreSQL (replaces Neon), MinIO S3-compatible storage (replaces B2), Redis, API, worker, and admin. Includes fully automated setup scripts (00-init through 04-verify), server hardening (SSH, fail2ban, ufw), Let's Encrypt TLS via Traefik, network policies, RBAC, and security contexts matching prod. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
94
deploy-k3s/manifests/admin/deployment.yaml
Normal file
94
deploy-k3s/manifests/admin/deployment.yaml
Normal file
@@ -0,0 +1,94 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: admin
|
||||
namespace: honeydue
|
||||
labels:
|
||||
app.kubernetes.io/name: admin
|
||||
app.kubernetes.io/part-of: honeydue
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 0
|
||||
maxSurge: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: admin
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: admin
|
||||
app.kubernetes.io/part-of: honeydue
|
||||
spec:
|
||||
serviceAccountName: admin
|
||||
imagePullSecrets:
|
||||
- name: ghcr-credentials
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
runAsGroup: 1001
|
||||
fsGroup: 1001
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: admin
|
||||
image: IMAGE_PLACEHOLDER # Replaced by 03-deploy.sh
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
protocol: TCP
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
env:
|
||||
- name: PORT
|
||||
value: "3000"
|
||||
- name: HOSTNAME
|
||||
value: "0.0.0.0"
|
||||
- name: NEXT_PUBLIC_API_URL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: honeydue-config
|
||||
key: NEXT_PUBLIC_API_URL
|
||||
volumeMounts:
|
||||
- name: nextjs-cache
|
||||
mountPath: /app/.next/cache
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 256Mi
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /admin/
|
||||
port: 3000
|
||||
failureThreshold: 12
|
||||
periodSeconds: 5
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /admin/
|
||||
port: 3000
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /admin/
|
||||
port: 3000
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
timeoutSeconds: 10
|
||||
volumes:
|
||||
- name: nextjs-cache
|
||||
emptyDir:
|
||||
sizeLimit: 256Mi
|
||||
- name: tmp
|
||||
emptyDir:
|
||||
sizeLimit: 64Mi
|
||||
16
deploy-k3s/manifests/admin/service.yaml
Normal file
16
deploy-k3s/manifests/admin/service.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: admin
|
||||
namespace: honeydue
|
||||
labels:
|
||||
app.kubernetes.io/name: admin
|
||||
app.kubernetes.io/part-of: honeydue
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app.kubernetes.io/name: admin
|
||||
ports:
|
||||
- port: 3000
|
||||
targetPort: 3000
|
||||
protocol: TCP
|
||||
54
deploy-k3s/manifests/ingress/ingress.yaml
Normal file
54
deploy-k3s/manifests/ingress/ingress.yaml
Normal file
@@ -0,0 +1,54 @@
|
||||
# API Ingress — Cloudflare-only + security headers + rate limiting
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: honeydue-api
|
||||
namespace: honeydue
|
||||
labels:
|
||||
app.kubernetes.io/part-of: honeydue
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.middlewares: honeydue-cloudflare-only@kubernetescrd,honeydue-security-headers@kubernetescrd,honeydue-rate-limit@kubernetescrd
|
||||
spec:
|
||||
tls:
|
||||
- hosts:
|
||||
- api.myhoneydue.com
|
||||
secretName: cloudflare-origin-cert
|
||||
rules:
|
||||
- host: api.myhoneydue.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: api
|
||||
port:
|
||||
number: 8000
|
||||
|
||||
---
|
||||
# Admin Ingress — Cloudflare-only + security headers + rate limiting + basic auth
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: honeydue-admin
|
||||
namespace: honeydue
|
||||
labels:
|
||||
app.kubernetes.io/part-of: honeydue
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.middlewares: honeydue-cloudflare-only@kubernetescrd,honeydue-security-headers@kubernetescrd,honeydue-rate-limit@kubernetescrd,honeydue-admin-auth@kubernetescrd
|
||||
spec:
|
||||
tls:
|
||||
- hosts:
|
||||
- admin.myhoneydue.com
|
||||
secretName: cloudflare-origin-cert
|
||||
rules:
|
||||
- host: admin.myhoneydue.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: admin
|
||||
port:
|
||||
number: 3000
|
||||
82
deploy-k3s/manifests/ingress/middleware.yaml
Normal file
82
deploy-k3s/manifests/ingress/middleware.yaml
Normal file
@@ -0,0 +1,82 @@
|
||||
# Traefik CRD middleware for rate limiting
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: rate-limit
|
||||
namespace: honeydue
|
||||
spec:
|
||||
rateLimit:
|
||||
average: 100
|
||||
burst: 200
|
||||
period: 1m
|
||||
|
||||
---
|
||||
# Security headers
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: security-headers
|
||||
namespace: honeydue
|
||||
spec:
|
||||
headers:
|
||||
frameDeny: true
|
||||
contentTypeNosniff: true
|
||||
browserXssFilter: true
|
||||
referrerPolicy: "strict-origin-when-cross-origin"
|
||||
customResponseHeaders:
|
||||
X-Content-Type-Options: "nosniff"
|
||||
X-Frame-Options: "DENY"
|
||||
Strict-Transport-Security: "max-age=31536000; includeSubDomains"
|
||||
Content-Security-Policy: "default-src 'self'; frame-ancestors 'none'"
|
||||
Permissions-Policy: "camera=(), microphone=(), geolocation=()"
|
||||
X-Permitted-Cross-Domain-Policies: "none"
|
||||
|
||||
---
|
||||
# Cloudflare IP allowlist (restrict origin to Cloudflare only)
|
||||
# https://www.cloudflare.com/ips-v4 and /ips-v6
|
||||
# Update periodically: curl -s https://www.cloudflare.com/ips-v4 && curl -s https://www.cloudflare.com/ips-v6
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: cloudflare-only
|
||||
namespace: honeydue
|
||||
spec:
|
||||
ipAllowList:
|
||||
sourceRange:
|
||||
# Cloudflare IPv4 ranges
|
||||
- 173.245.48.0/20
|
||||
- 103.21.244.0/22
|
||||
- 103.22.200.0/22
|
||||
- 103.31.4.0/22
|
||||
- 141.101.64.0/18
|
||||
- 108.162.192.0/18
|
||||
- 190.93.240.0/20
|
||||
- 188.114.96.0/20
|
||||
- 197.234.240.0/22
|
||||
- 198.41.128.0/17
|
||||
- 162.158.0.0/15
|
||||
- 104.16.0.0/13
|
||||
- 104.24.0.0/14
|
||||
- 172.64.0.0/13
|
||||
- 131.0.72.0/22
|
||||
# Cloudflare IPv6 ranges
|
||||
- 2400:cb00::/32
|
||||
- 2606:4700::/32
|
||||
- 2803:f800::/32
|
||||
- 2405:b500::/32
|
||||
- 2405:8100::/32
|
||||
- 2a06:98c0::/29
|
||||
- 2c0f:f248::/32
|
||||
|
||||
---
|
||||
# Admin basic auth — additional auth layer for admin panel
|
||||
# Secret created by 02-setup-secrets.sh from config.yaml credentials
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: admin-auth
|
||||
namespace: honeydue
|
||||
spec:
|
||||
basicAuth:
|
||||
secret: admin-basic-auth
|
||||
realm: "honeyDue Admin"
|
||||
6
deploy-k3s/manifests/namespace.yaml
Normal file
6
deploy-k3s/manifests/namespace.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: honeydue
|
||||
labels:
|
||||
app.kubernetes.io/part-of: honeydue
|
||||
202
deploy-k3s/manifests/network-policies.yaml
Normal file
202
deploy-k3s/manifests/network-policies.yaml
Normal file
@@ -0,0 +1,202 @@
|
||||
# Network Policies — default-deny with explicit allows
|
||||
# Apply AFTER namespace and deployments are created.
|
||||
# Verify: kubectl get networkpolicy -n honeydue
|
||||
|
||||
# --- Default deny all ingress and egress ---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: default-deny-all
|
||||
namespace: honeydue
|
||||
spec:
|
||||
podSelector: {}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
|
||||
---
|
||||
# --- Allow DNS for all pods (required for service discovery) ---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: allow-dns
|
||||
namespace: honeydue
|
||||
spec:
|
||||
podSelector: {}
|
||||
policyTypes:
|
||||
- Egress
|
||||
egress:
|
||||
- to: []
|
||||
ports:
|
||||
- protocol: UDP
|
||||
port: 53
|
||||
- protocol: TCP
|
||||
port: 53
|
||||
|
||||
---
|
||||
# --- API: allow ingress from Traefik (kube-system namespace) ---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: allow-ingress-to-api
|
||||
namespace: honeydue
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: api
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 8000
|
||||
|
||||
---
|
||||
# --- Admin: allow ingress from Traefik (kube-system namespace) ---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: allow-ingress-to-admin
|
||||
namespace: honeydue
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: admin
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 3000
|
||||
|
||||
---
|
||||
# --- Redis: allow ingress ONLY from api + worker pods ---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: allow-ingress-to-redis
|
||||
namespace: honeydue
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: redis
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: api
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: worker
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 6379
|
||||
|
||||
---
|
||||
# --- API: allow egress to Redis, external services (Neon DB, APNs, FCM, B2, SMTP) ---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: allow-egress-from-api
|
||||
namespace: honeydue
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: api
|
||||
policyTypes:
|
||||
- Egress
|
||||
egress:
|
||||
# Redis (in-cluster)
|
||||
- to:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: redis
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 6379
|
||||
# External services: Neon DB (5432), SMTP (587), HTTPS (443 — APNs, FCM, B2, PostHog)
|
||||
- to:
|
||||
- ipBlock:
|
||||
cidr: 0.0.0.0/0
|
||||
except:
|
||||
- 10.0.0.0/8
|
||||
- 172.16.0.0/12
|
||||
- 192.168.0.0/16
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 5432
|
||||
- protocol: TCP
|
||||
port: 587
|
||||
- protocol: TCP
|
||||
port: 443
|
||||
|
||||
---
|
||||
# --- Worker: allow egress to Redis, external services ---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: allow-egress-from-worker
|
||||
namespace: honeydue
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: worker
|
||||
policyTypes:
|
||||
- Egress
|
||||
egress:
|
||||
# Redis (in-cluster)
|
||||
- to:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: redis
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 6379
|
||||
# External services: Neon DB (5432), SMTP (587), HTTPS (443 — APNs, FCM, B2)
|
||||
- to:
|
||||
- ipBlock:
|
||||
cidr: 0.0.0.0/0
|
||||
except:
|
||||
- 10.0.0.0/8
|
||||
- 172.16.0.0/12
|
||||
- 192.168.0.0/16
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 5432
|
||||
- protocol: TCP
|
||||
port: 587
|
||||
- protocol: TCP
|
||||
port: 443
|
||||
|
||||
---
|
||||
# --- Admin: allow egress to API (internal) for SSR ---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: allow-egress-from-admin
|
||||
namespace: honeydue
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: admin
|
||||
policyTypes:
|
||||
- Egress
|
||||
egress:
|
||||
# API service (in-cluster, for server-side API calls)
|
||||
- to:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: api
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 8000
|
||||
32
deploy-k3s/manifests/pod-disruption-budgets.yaml
Normal file
32
deploy-k3s/manifests/pod-disruption-budgets.yaml
Normal file
@@ -0,0 +1,32 @@
|
||||
# Pod Disruption Budgets — prevent node maintenance from killing all replicas
|
||||
# API: at least 2 of 3 replicas must stay up during voluntary disruptions
|
||||
# Worker: at least 1 of 2 replicas must stay up
|
||||
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: api-pdb
|
||||
namespace: honeydue
|
||||
labels:
|
||||
app.kubernetes.io/name: api
|
||||
app.kubernetes.io/part-of: honeydue
|
||||
spec:
|
||||
minAvailable: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: api
|
||||
|
||||
---
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: worker-pdb
|
||||
namespace: honeydue
|
||||
labels:
|
||||
app.kubernetes.io/name: worker
|
||||
app.kubernetes.io/part-of: honeydue
|
||||
spec:
|
||||
minAvailable: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: worker
|
||||
46
deploy-k3s/manifests/rbac.yaml
Normal file
46
deploy-k3s/manifests/rbac.yaml
Normal file
@@ -0,0 +1,46 @@
|
||||
# RBAC — Dedicated service accounts with no K8s API access
|
||||
# Each pod gets its own SA with automountServiceAccountToken: false,
|
||||
# so a compromised pod cannot query the Kubernetes API.
|
||||
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: api
|
||||
namespace: honeydue
|
||||
labels:
|
||||
app.kubernetes.io/name: api
|
||||
app.kubernetes.io/part-of: honeydue
|
||||
automountServiceAccountToken: false
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: worker
|
||||
namespace: honeydue
|
||||
labels:
|
||||
app.kubernetes.io/name: worker
|
||||
app.kubernetes.io/part-of: honeydue
|
||||
automountServiceAccountToken: false
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: admin
|
||||
namespace: honeydue
|
||||
labels:
|
||||
app.kubernetes.io/name: admin
|
||||
app.kubernetes.io/part-of: honeydue
|
||||
automountServiceAccountToken: false
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: redis
|
||||
namespace: honeydue
|
||||
labels:
|
||||
app.kubernetes.io/name: redis
|
||||
app.kubernetes.io/part-of: honeydue
|
||||
automountServiceAccountToken: false
|
||||
106
deploy-k3s/manifests/redis/deployment.yaml
Normal file
106
deploy-k3s/manifests/redis/deployment.yaml
Normal file
@@ -0,0 +1,106 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: redis
|
||||
namespace: honeydue
|
||||
labels:
|
||||
app.kubernetes.io/name: redis
|
||||
app.kubernetes.io/part-of: honeydue
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate # ReadWriteOnce PVC — can't attach to two pods
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: redis
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: redis
|
||||
app.kubernetes.io/part-of: honeydue
|
||||
spec:
|
||||
serviceAccountName: redis
|
||||
nodeSelector:
|
||||
honeydue/redis: "true"
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 999
|
||||
runAsGroup: 999
|
||||
fsGroup: 999
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: redis
|
||||
image: redis:7-alpine
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
ARGS="--appendonly yes --appendfsync everysec --maxmemory 256mb --maxmemory-policy noeviction"
|
||||
if [ -n "$REDIS_PASSWORD" ]; then
|
||||
ARGS="$ARGS --requirepass $REDIS_PASSWORD"
|
||||
fi
|
||||
exec redis-server $ARGS
|
||||
ports:
|
||||
- containerPort: 6379
|
||||
protocol: TCP
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
env:
|
||||
- name: REDIS_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: honeydue-secrets
|
||||
key: REDIS_PASSWORD
|
||||
optional: true
|
||||
volumeMounts:
|
||||
- name: redis-data
|
||||
mountPath: /data
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
readinessProbe:
|
||||
exec:
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
if [ -n "$REDIS_PASSWORD" ]; then
|
||||
redis-cli -a "$REDIS_PASSWORD" ping 2>/dev/null | grep -q PONG
|
||||
else
|
||||
redis-cli ping | grep -q PONG
|
||||
fi
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
livenessProbe:
|
||||
exec:
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
if [ -n "$REDIS_PASSWORD" ]; then
|
||||
redis-cli -a "$REDIS_PASSWORD" ping 2>/dev/null | grep -q PONG
|
||||
else
|
||||
redis-cli ping | grep -q PONG
|
||||
fi
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 20
|
||||
timeoutSeconds: 5
|
||||
volumes:
|
||||
- name: redis-data
|
||||
persistentVolumeClaim:
|
||||
claimName: redis-data
|
||||
- name: tmp
|
||||
emptyDir:
|
||||
medium: Memory
|
||||
sizeLimit: 64Mi
|
||||
15
deploy-k3s/manifests/redis/pvc.yaml
Normal file
15
deploy-k3s/manifests/redis/pvc.yaml
Normal file
@@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: redis-data
|
||||
namespace: honeydue
|
||||
labels:
|
||||
app.kubernetes.io/name: redis
|
||||
app.kubernetes.io/part-of: honeydue
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
storageClassName: local-path
|
||||
resources:
|
||||
requests:
|
||||
storage: 5Gi
|
||||
16
deploy-k3s/manifests/redis/service.yaml
Normal file
16
deploy-k3s/manifests/redis/service.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: redis
|
||||
namespace: honeydue
|
||||
labels:
|
||||
app.kubernetes.io/name: redis
|
||||
app.kubernetes.io/part-of: honeydue
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app.kubernetes.io/name: redis
|
||||
ports:
|
||||
- port: 6379
|
||||
targetPort: 6379
|
||||
protocol: TCP
|
||||
47
deploy-k3s/manifests/secrets.yaml.example
Normal file
47
deploy-k3s/manifests/secrets.yaml.example
Normal file
@@ -0,0 +1,47 @@
|
||||
# EXAMPLE ONLY — never commit real values.
|
||||
# Secrets are created by scripts/02-setup-secrets.sh.
|
||||
# This file shows the expected structure for reference.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: honeydue-secrets
|
||||
namespace: honeydue
|
||||
type: Opaque
|
||||
stringData:
|
||||
POSTGRES_PASSWORD: "CHANGEME"
|
||||
SECRET_KEY: "CHANGEME_MIN_32_CHARS"
|
||||
EMAIL_HOST_PASSWORD: "CHANGEME"
|
||||
FCM_SERVER_KEY: "CHANGEME"
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: honeydue-apns-key
|
||||
namespace: honeydue
|
||||
type: Opaque
|
||||
data:
|
||||
apns_auth_key.p8: "" # base64-encoded .p8 file contents
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: ghcr-credentials
|
||||
namespace: honeydue
|
||||
type: kubernetes.io/dockerconfigjson
|
||||
data:
|
||||
.dockerconfigjson: "" # base64-encoded Docker config
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: cloudflare-origin-cert
|
||||
namespace: honeydue
|
||||
type: kubernetes.io/tls
|
||||
data:
|
||||
tls.crt: "" # base64-encoded origin certificate
|
||||
tls.key: "" # base64-encoded origin private key
|
||||
Reference in New Issue
Block a user