docs: add portable from-zero deploy runbook and GitOps templates
Document server-side rollout (values, Sealed Secrets, logging, greenfield reset) with environment variables so any cluster can follow the same steps. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+7
-4
@@ -1,5 +1,7 @@
|
||||
# GitOps stack for abrban.com
|
||||
|
||||
> **راهنمای استقرار از صفر (هر محیط):** [`RUNBOOK-DEPLOY.fa.md`](../RUNBOOK-DEPLOY.fa.md) — متغیرها، values، Sealed Secrets، logging، deploy، greenfield reset.
|
||||
|
||||
## DNS (A record → cluster IP `78.157.39.52`)
|
||||
|
||||
| Host | Purpose |
|
||||
@@ -84,8 +86,9 @@ kubectl apply -f gitops/argocd/application-platform.yaml
|
||||
|
||||
Gitea Actions: [.gitea/workflows/build-deploy.yaml](../.gitea/workflows/build-deploy.yaml)
|
||||
|
||||
Push به `main` → Kaniko → push به `abrban/` → کامیت tag در ریپوی [cloud-host-gitops](https://git.abrban.com/abrban/cloud-host-gitops) → ArgoCD sync.
|
||||
Push به `main` → **تست Jest** → Kaniko → push به `abrban/` → کامیت tag در ریپوی [cloud-host-gitops](https://git.abrban.com/abrban/cloud-host-gitops) → ArgoCD sync.
|
||||
|
||||
- مقادیر Production در ریپوی جدا `abrban/cloud-host-gitops` است (`platform/values-abrban.yaml`)؛ Application بهصورت multi-source تعریف شده.
|
||||
- Secretهای CI بهصورت SealedSecret در همان ریپو هستند (کنترلر در `kube-system`، values در `gitops/sealed-secrets/values.yaml`).
|
||||
- مستند کامل: [RUNBOOK-CICD.fa.md](../RUNBOOK-CICD.fa.md)
|
||||
- **استقرار اولیه از صفر:** [`RUNBOOK-DEPLOY.fa.md`](../RUNBOOK-DEPLOY.fa.md) (فاز ۲–۷)
|
||||
- مقادیر Production: [`platform/values-abrban.example.yaml`](platform/values-abrban.example.yaml) → کپی به gitops و ویرایش
|
||||
- SealedSecretهای نمونه: [`sealed-secrets/abrban-platform-secrets.example.yaml`](sealed-secrets/abrban-platform-secrets.example.yaml)، [`sealed-secrets/elasticsearch-credentials.example.yaml`](sealed-secrets/elasticsearch-credentials.example.yaml)
|
||||
- Pipeline و rollback: [RUNBOOK-CICD.fa.md](../RUNBOOK-CICD.fa.md)
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
# Production values template — copy and customize for YOUR environment.
|
||||
#
|
||||
# Full step-by-step (from zero, any cluster):
|
||||
# See RUNBOOK-DEPLOY.fa.md — Phase 2 (values) and Phase 3 (secrets)
|
||||
#
|
||||
# Example for abrban.com:
|
||||
# cp values-abrban.example.yaml ../cloud-host-gitops/platform/values-abrban.yaml
|
||||
#
|
||||
# CI only updates images.backend.tag and images.frontend.tag on each deploy.
|
||||
|
||||
namespace: cloudhost
|
||||
createNamespace: false
|
||||
|
||||
global:
|
||||
storageClass: local-path
|
||||
|
||||
images:
|
||||
# Harbor proxy-cache — first pull is slow, no manual seed needed (see gitops/README.md)
|
||||
postgres: registry.abrban.com/proxy-dockerhub/library/postgres:16-alpine
|
||||
redis: registry.abrban.com/proxy-dockerhub/library/redis:7-alpine
|
||||
busybox: registry.abrban.com/proxy-dockerhub/library/busybox:1.36
|
||||
backend:
|
||||
repository: registry.abrban.com/abrban/cloudhost-backend
|
||||
tag: "1.0.0" # ← CI overwrites on each deploy
|
||||
pullPolicy: IfNotPresent
|
||||
frontend:
|
||||
repository: registry.abrban.com/abrban/cloudhost-frontend
|
||||
tag: "1.0.0" # ← CI overwrites on each deploy
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
postgres:
|
||||
enabled: true
|
||||
database: cloudhost
|
||||
username: cloudhost
|
||||
password: "" # managed in abrban-platform-secrets (postgres-password)
|
||||
storage: 10Gi
|
||||
imagePullSecrets:
|
||||
- name: registry-pull-secret
|
||||
resources:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
limits:
|
||||
cpu: "2"
|
||||
memory: 2Gi
|
||||
|
||||
redis:
|
||||
enabled: true
|
||||
storage: 1Gi
|
||||
password: "" # managed in abrban-platform-secrets (redis-password)
|
||||
imagePullSecrets:
|
||||
- name: registry-pull-secret
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
|
||||
# GitOps: never let Helm generate random JWT/redis passwords on each sync.
|
||||
# Create once with kubeseal — see gitops/sealed-secrets/abrban-platform-secrets.example.yaml
|
||||
secrets:
|
||||
existingSecret: abrban-platform-secrets
|
||||
|
||||
backend:
|
||||
enabled: true
|
||||
replicas: 1
|
||||
imagePullSecrets:
|
||||
- name: registry-pull-secret
|
||||
uploads:
|
||||
size: 20Gi
|
||||
sourceStorage:
|
||||
enabled: false
|
||||
existingSecret: ceph-app-sources-credentials
|
||||
resources:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
limits:
|
||||
cpu: "2"
|
||||
memory: 2Gi
|
||||
env:
|
||||
NODE_ENV: production
|
||||
PORT: "4000"
|
||||
JWT_EXPIRES_IN: 15m
|
||||
JWT_REFRESH_EXPIRES_IN: 7d
|
||||
PLATFORM_DOMAIN: apps.abrban.com
|
||||
PREVIEW_BASE_DOMAIN: apps.abrban.com
|
||||
FRONTEND_URL: https://panel.abrban.com,https://abrban.com
|
||||
REGISTRY_URL: harbor-registry.cloudhost.svc.cluster.local:5000/abrban
|
||||
REGISTRY_PULL_URL: registry.abrban.com/abrban
|
||||
BUILD_NAMESPACE: cloudhost-builds
|
||||
BUILD_SERVICE_ACCOUNT: kaniko-builder
|
||||
UPLOAD_DIR: /app/uploads
|
||||
PLATFORM_CREATE_STORAGE_CLASS: "true"
|
||||
PLATFORM_STORAGE_CLASS: cloudhost-expandable
|
||||
PLATFORM_STORAGE_PROVISIONER: rancher.io/local-path
|
||||
ELASTICSEARCH_HOST: elasticsearch.logging.svc.cluster.local
|
||||
ELASTICSEARCH_AUTO_PORT_FORWARD: "false"
|
||||
# Mirror prefix for user-app Dockerfiles and managed DB/Redis/RabbitMQ charts
|
||||
BASE_IMAGE_REGISTRY: registry.abrban.com/proxy-dockerhub/library
|
||||
# Must match elasticsearch-credentials Secret in logging namespace (not in Helm chart)
|
||||
ELASTIC_PASSWORD: "CHANGE_VIA_SEALEDSECRET_OR_KUBECTL"
|
||||
FLUENTBIT_PASSWORD: "CHANGE_VIA_SEALEDSECRET_OR_KUBECTL"
|
||||
KIBANA_SYSTEM_PASSWORD: "CHANGE_VIA_SEALEDSECRET_OR_KUBECTL"
|
||||
# Swagger disabled in production unless explicitly enabled
|
||||
# SWAGGER_ENABLED: "true"
|
||||
|
||||
frontend:
|
||||
enabled: true
|
||||
replicas: 1
|
||||
imagePullSecrets:
|
||||
- name: registry-pull-secret
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
cpu: "1"
|
||||
memory: 1Gi
|
||||
|
||||
ingress:
|
||||
enabled: true
|
||||
className: traefik
|
||||
frontend:
|
||||
host: abrban.com
|
||||
panel:
|
||||
host: panel.abrban.com
|
||||
api:
|
||||
host: api.abrban.com
|
||||
tls:
|
||||
enabled: true
|
||||
clusterIssuer: letsencrypt-prod
|
||||
|
||||
migrations:
|
||||
enabled: true
|
||||
image: registry.abrban.com/proxy-dockerhub/library/postgres:16-alpine
|
||||
|
||||
backups:
|
||||
postgres:
|
||||
enabled: true
|
||||
schedule: "0 3 * * *"
|
||||
storageSize: 10Gi
|
||||
retentionDays: 7
|
||||
|
||||
monitoring:
|
||||
enabled: false
|
||||
@@ -0,0 +1,30 @@
|
||||
# Example: seal platform secrets for namespace cloudhost.
|
||||
# Full guide (any environment): RUNBOOK-DEPLOY.fa.md — Phase 3
|
||||
# Real SealedSecret lives in cloud-host-gitops/sealed-secrets/ — never commit plaintext passwords.
|
||||
#
|
||||
# Required keys (must match backend Deployment + validate-production-config):
|
||||
# postgres-password, jwt-secret, jwt-refresh-secret, cluster-kubeconfig-key, redis-password
|
||||
#
|
||||
# Generate (replace CHANGE_ME_* with strong random values):
|
||||
#
|
||||
# kubectl -n cloudhost create secret generic abrban-platform-secrets \
|
||||
# --from-literal=postgres-password='CHANGE_ME_PG' \
|
||||
# --from-literal=jwt-secret='CHANGE_ME_JWT_32CHARS_MIN' \
|
||||
# --from-literal=jwt-refresh-secret='CHANGE_ME_REFRESH_32CHARS_MIN' \
|
||||
# --from-literal=cluster-kubeconfig-key='0123456789abcdef0123456789abcdef' \
|
||||
# --from-literal=redis-password='CHANGE_ME_REDIS' \
|
||||
# --dry-run=client -o json \
|
||||
# | kubeseal \
|
||||
# --controller-name=sealed-secrets-controller \
|
||||
# --controller-namespace=kube-system \
|
||||
# --format yaml \
|
||||
# > ../cloud-host-gitops/sealed-secrets/abrban-platform-secrets.yaml
|
||||
#
|
||||
# Then in platform/values-abrban.yaml:
|
||||
# secrets:
|
||||
# existingSecret: abrban-platform-secrets
|
||||
#
|
||||
# Apply:
|
||||
# kubectl apply -f ../cloud-host-gitops/sealed-secrets/abrban-platform-secrets.yaml
|
||||
#
|
||||
# Rotate redis-password: update SealedSecret, sync Argo, restart backend + redis pods.
|
||||
@@ -0,0 +1,20 @@
|
||||
# Example: seal Elasticsearch stack credentials (namespace logging).
|
||||
# Full guide (any environment): RUNBOOK-DEPLOY.fa.md — Phase 4
|
||||
# Apply elasticsearch-stack.yaml FIRST (without inline passwords), then create this Secret.
|
||||
#
|
||||
# kubectl -n logging create secret generic elasticsearch-credentials \
|
||||
# --from-literal=ELASTIC_PASSWORD="$(openssl rand -base64 24)" \
|
||||
# --from-literal=FLUENTBIT_PASSWORD="$(openssl rand -base64 24)" \
|
||||
# --dry-run=client -o json \
|
||||
# | kubeseal \
|
||||
# --controller-name=sealed-secrets-controller \
|
||||
# --controller-namespace=kube-system \
|
||||
# --format yaml \
|
||||
# > ../cloud-host-gitops/sealed-secrets/elasticsearch-credentials.yaml
|
||||
#
|
||||
# Backend must receive the same ELASTIC_* values via backend.env in values-abrban.yaml
|
||||
# (or a separate SealedSecret referenced with envFrom).
|
||||
#
|
||||
# After deploy, verify:
|
||||
# kubectl -n logging get secret elasticsearch-credentials
|
||||
# curl -u elastic:$ELASTIC_PASSWORD https://elasticsearch.logging.svc.cluster.local:9200
|
||||
Reference in New Issue
Block a user