diff --git a/deploy/appflowy/deployment.yaml b/deploy/appflowy/deployment.yaml new file mode 100644 index 0000000..6e0dfbe --- /dev/null +++ b/deploy/appflowy/deployment.yaml @@ -0,0 +1,341 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gotrue + namespace: appflowy +spec: + replicas: 1 + selector: + matchLabels: + app: gotrue + template: + metadata: + labels: + app: gotrue + spec: + containers: + - name: gotrue + image: appflowyinc/gotrue:latest + ports: + - containerPort: 9999 + env: + # ----- DB (Postgres HA) ----- + - name: GOTRUE_DB_DRIVER + value: postgres + - name: DATABASE_URL + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: GOTRUE_DATABASE_URL + - name: GOTRUE_ADMIN_EMAIL + value: hello@beatrice.wtf + - name: GOTRUE_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: GOTRUE_ADMIN_PASSWORD + - name: GOTRUE_DISABLE_SIGNUP + value: "false" + - name: GOTRUE_SITE_URL + value: "appflowy-flutter://" + - name: GOTRUE_URI_ALLOW_LIST + value: "**" + - name: GOTRUE_JWT_SECRET + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: GOTRUE_JWT_SECRET + - name: GOTRUE_JWT_EXP + value: "7200" + - name: GOTRUE_SMTP_HOST + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: SMTP_HOST + - name: GOTRUE_SMTP_PORT + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: SMTP_PORT + - name: GOTRUE_SMTP_USER + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: SMTP_USER + - name: GOTRUE_SMTP_PASS + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: SMTP_PASS + - name: GOTRUE_SMTP_ADMIN_EMAIL + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: SMTP_ADMIN_EMAIL + - name: PORT + value: "9999" + - name: GOTRUE_JWT_ADMIN_GROUP_NAME + value: supabase_admin + - name: API_EXTERNAL_URL + value: https://appflowy.prod.panic.haus/gotrue + - name: GOTRUE_MAILER_URLPATHS_CONFIRMATION + value: /gotrue/verify + - name: GOTRUE_MAILER_URLPATHS_INVITE + value: /gotrue/verify + - name: GOTRUE_MAILER_URLPATHS_RECOVERY + value: /gotrue/verify + - name: GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE + value: /gotrue/verify + + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: appflowy-cloud + namespace: appflowy +spec: + replicas: 1 + selector: + matchLabels: + app: appflowy-cloud + template: + metadata: + labels: + app: appflowy-cloud + spec: + containers: + - name: appflowy-cloud + image: appflowyinc/appflowy_cloud:latest + ports: + - containerPort: 8000 + env: + # ----- Database ----- + - name: APPFLOWY_DATABASE_URL + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: APPFLOWY_DATABASE_URL + - name: APPFLOWY_REDIS_URI + value: "redis://redis-lb.redis.svc.cluster.local:6379" + + # ----- GoTrue (Auth) ----- + - name: APPFLOWY_GOTRUE_BASE_URL + value: "http://gotrue.appflowy.svc.cluster.local:9999" + - name: APPFLOWY_GOTRUE_JWT_SECRET + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: GOTRUE_JWT_SECRET + - name: APPFLOWY_GOTRUE_JWT_EXP + value: "7200" + + # ----- S3 / Minio ----- + - name: APPFLOWY_S3_USE_MINIO + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: APPFLOWY_S3_USE_MINIO + - name: APPFLOWY_S3_MINIO_URL + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: APPFLOWY_S3_MINIO_URL + - name: APPFLOWY_S3_BUCKET + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: APPFLOWY_S3_BUCKET + - name: APPFLOWY_S3_REGION + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: AWS_REGION + - name: APPFLOWY_S3_ACCESS_KEY + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: AWS_ACCESS_KEY + - name: APPFLOWY_S3_SECRET_KEY + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: AWS_SECRET_KEY + #- name: APPFLOWY_S3_PRESIGNED_URL_ENDPOINT + # value: "https://minio.example.com" + # ← Replace with your actual public Minio endpoint if different + + # ----- Mailer (AppFlowy Cloud) ----- + - name: APPFLOWY_MAILER_SMTP_HOST + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: SMTP_HOST + - name: APPFLOWY_MAILER_SMTP_PORT + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: SMTP_PORT + - name: APPFLOWY_MAILER_SMTP_USERNAME + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: SMTP_USER + - name: APPFLOWY_MAILER_SMTP_PASSWORD + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: SMTP_PASS + - name: APPFLOWY_MAILER_SMTP_EMAIL + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: SMTP_USER + - name: APPFLOWY_MAILER_SMTP_TLS_KIND + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: SMTP_TLS_KIND + + # ----- General ----- + - name: APPFLOWY_ACCESS_CONTROL + value: "true" + - name: RUST_LOG + value: info + - name: APPFLOWY_ENVIRONMENT + value: production + - name: APPFLOWY_WEB_URL + value: "https://appflowy.prod.panic.haus" # ← your public AppFlowy URL + readinessProbe: + httpGet: + path: /health + port: 8000 + initialDelaySeconds: 10 + periodSeconds: 10 + livenessProbe: + httpGet: + path: /health + port: 8000 + initialDelaySeconds: 20 + periodSeconds: 20 + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: admin-frontend + namespace: appflowy +spec: + replicas: 1 + selector: + matchLabels: + app: admin-frontend + template: + metadata: + labels: + app: admin-frontend + spec: + containers: + - name: admin-frontend + image: appflowyinc/admin_frontend:latest + ports: + - containerPort: 80 + env: + - name: ADMIN_FRONTEND_REDIS_URL + value: "redis://redis-lb.redis.svc.cluster.local:6379" + - name: ADMIN_FRONTEND_GOTRUE_URL + value: "http://gotrue.appflowy.svc.cluster.local:9999" + - name: ADMIN_FRONTEND_APPFLOWY_CLOUD_URL + value: "http://appflowy-cloud.appflowy.svc.cluster.local:8000" + - name: ADMIN_FRONTEND_PATH_PREFIX + value: "/console" + readinessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + periodSeconds: 10 + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: appflowy-worker + namespace: appflowy +spec: + replicas: 1 + selector: + matchLabels: + app: appflowy-worker + template: + metadata: + labels: + app: appflowy-worker + spec: + containers: + - name: appflowy-worker + image: appflowyinc/appflowy_worker:latest + env: + - name: RUST_LOG + value: info + - name: APPFLOWY_ENVIRONMENT + value: production + - name: APPFLOWY_WORKER_REDIS_URL + value: "redis://redis-lb.redis.svc.cluster.local:6379" + - name: APPFLOWY_WORKER_DATABASE_URL + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: GOTRUE_DATABASE_URL + - name: APPFLOWY_WORKER_DATABASE_NAME + value: appflowy_db + - name: APPFLOWY_S3_USE_MINIO + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: APPFLOWY_S3_USE_MINIO + - name: APPFLOWY_S3_MINIO_URL + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: APPFLOWY_S3_MINIO_URL + - name: APPFLOWY_S3_ACCESS_KEY + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: AWS_ACCESS_KEY + - name: APPFLOWY_S3_SECRET_KEY + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: AWS_SECRET_KEY + - name: APPFLOWY_S3_BUCKET + valueFrom: + secretKeyRef: + name: appflowy-secrets + key: APPFLOWY_S3_BUCKET + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: appflowy-web + namespace: appflowy +spec: + replicas: 1 + selector: + matchLabels: + app: appflowy-web + template: + metadata: + labels: + app: appflowy-web + spec: + containers: + - name: appflowy-web + image: appflowyinc/appflowy_web:latest + ports: + - containerPort: 80 + env: + - name: APPFLOWY_CLOUD_URL + value: "http://appflowy-cloud.appflowy.svc.cluster.local:8000" \ No newline at end of file diff --git a/deploy/appflowy/ingress.yaml b/deploy/appflowy/ingress.yaml new file mode 100644 index 0000000..4eed706 --- /dev/null +++ b/deploy/appflowy/ingress.yaml @@ -0,0 +1,67 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: appflowy-ingress + namespace: appflowy + annotations: + cert-manager.io/cluster-issuer: "letsencrypt-prod" + nginx.ingress.kubernetes.io/force-ssl-redirect: "true" + nginx.ingress.kubernetes.io/proxy-body-size: "50m" +spec: + ingressClassName: nginx + + tls: + - hosts: + - appflowy.prod.panic.haus # ← replace with your public domain + secretName: appflowy-tls + + rules: + - host: appflowy.prod.panic.haus + http: + paths: + # ┌──────────────────────────────────────────────────────────────────────────────┐ + # │ 1) Admin UI (served under /console) │ + # └──────────────────────────────────────────────────────────────────────────────┘ + - path: /console + pathType: Prefix + backend: + service: + name: admin-frontend + port: + number: 80 + + # ┌──────────────────────────────────────────────────────────────────────────────┐ + # │ 2) GoTrue (auth) – exposed under /gotrue │ + # └──────────────────────────────────────────────────────────────────────────────┘ + - path: /gotrue + pathType: Prefix + backend: + service: + name: gotrue + port: + number: 9999 + + # ┌──────────────────────────────────────────────────────────────────────────────┐ + # │ 3) AppFlowy-Cloud API & Web │ + # • If you want API served on /api, and the static Web on / │ + # • You could also send all traffic to appflowy-web and let it call │ + # • the backend at /api internally. │ + # └──────────────────────────────────────────────────────────────────────────────┘ + + # a) Direct all `/api/*` calls to the backend service + - path: /api + pathType: Prefix + backend: + service: + name: appflowy-cloud + port: + number: 8000 + + # b) Everything else (root path) → appflowy-web (static UI) + - path: / + pathType: Prefix + backend: + service: + name: appflowy-web + port: + number: 80 \ No newline at end of file diff --git a/deploy/appflowy/kustomization.yaml b/deploy/appflowy/kustomization.yaml new file mode 100644 index 0000000..272d7eb --- /dev/null +++ b/deploy/appflowy/kustomization.yaml @@ -0,0 +1,10 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: appflowy + +resources: + - secret.yaml + - deployment.yaml + - service.yaml + - ingress.yaml diff --git a/deploy/appflowy/secret.yaml b/deploy/appflowy/secret.yaml new file mode 100644 index 0000000..85a7c7f --- /dev/null +++ b/deploy/appflowy/secret.yaml @@ -0,0 +1,45 @@ +apiVersion: v1 +kind: Secret +metadata: + name: appflowy-secrets + namespace: appflowy +stringData: + FQDN: "appflowy.prod.panic.haus" + SCHEME: "https" + APPFLOWY_BASE_URL: "https://appflowy.prod.panic.haus" + APPFLOWY_WEB_URL: "https://appflowy.prod.panic.haus" + + # ==== PostgreSQL credentials ==== + GOTRUE_DATABASE_URL: "postgres://appflowy:AjUIkz5lcaEGpCrO9KHYAvaKbLsH2Q0e@postgres-base-rw.postgres.svc.cluster.local:5432/appflowy_db?search_path=auth" + APPFLOWY_DATABASE_URL: "postgres://appflowy:AjUIkz5lcaEGpCrO9KHYAvaKbLsH2Q0e@postgres-base-rw.postgres.svc.cluster.local:5432/appflowy_db" + + # ==== GoTrue (Auth) keys ==== + GOTRUE_JWT_SECRET: "5IqQzMmpRPoeParMsgoWIphrCYdhFhxz9NSyEQYlwGyTrRSsjInyMSaM44ZCH" + GOTRUE_ADMIN_PASSWORD: "KaTPKUXiDUVIcUYWjqSy5SFdqrIl5csS" + + # ==== Minio (S3) ==== + APPFLOWY_S3_MINIO_URL: "https://s3.minio.panic.haus" + MINIO_HOST: "s3.minio.panic.haus" + MINIO_PORT: "443" + AWS_ACCESS_KEY: "rjtPFRp52DgmWb4kdsyiFKjtBMxYSaow" # must match your Minio secret + AWS_SECRET_KEY: "kabSK8RXcONjO8I7GNfJ03WMueJ7fk6z" # must match your Minio secret + APPFLOWY_S3_BUCKET: "appflowy" # your bucket name + APPFLOWY_S3_USE_MINIO: "true" + # If you use AWS S3 instead of Minio, set APPFLOWY_S3_CREATE_BUCKET / AWS_REGION here. + # APPFLOWY_S3_REGION: cluster-panic-haus + + # ==== GoTrue SMTP (optional) ==== + SMTP_HOST: "mail.mind-overflow.net" + SMTP_PORT: "465" + SMTP_USER: "cloud@mind-overflow.net" + SMTP_PASS: "PcYchuLLUyfT2gvY4Tx7wQ575Tnqjx84zVNoP6Mb" + SMTP_ADMIN_EMAIL: "hello@beatrice.wtf" + + # ==== AppFlowy Mailer (Cloud) ==== + SMTP_EMAIL: "cloud@mind-overflow.net" + SMTP_TLS_KIND: "wrapper" # "none" "wrapper" "required" "opportunistic" + + # ==== Additional secrets for AppFlowy AI (if used) ==== + AI_OPENAI_API_KEY: "" + + # (Optional) any other secrets you need can go here. diff --git a/deploy/appflowy/service.yaml b/deploy/appflowy/service.yaml new file mode 100644 index 0000000..0844460 --- /dev/null +++ b/deploy/appflowy/service.yaml @@ -0,0 +1,95 @@ +apiVersion: v1 +kind: Service +metadata: + name: gotrue + namespace: appflowy +spec: + ports: + - port: 9999 + targetPort: 9999 + protocol: TCP + name: http + selector: + app: gotrue + type: ClusterIP + +--- +apiVersion: v1 +kind: Service +metadata: + name: appflowy-cloud + namespace: appflowy +spec: + ports: + - port: 8000 + targetPort: 8000 + protocol: TCP + name: http + selector: + app: appflowy-cloud + type: ClusterIP + +--- +apiVersion: v1 +kind: Service +metadata: + name: admin-frontend + namespace: appflowy +spec: + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: http + selector: + app: admin-frontend + type: ClusterIP + +--- +apiVersion: v1 +kind: Service +metadata: + name: appflowy-worker + namespace: appflowy +spec: + ports: + - port: 8081 + targetPort: 8081 + protocol: TCP + name: http + selector: + app: appflowy-worker + type: ClusterIP + +--- +apiVersion: v1 +kind: Service +metadata: + name: appflowy-web + namespace: appflowy +spec: + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: http + selector: + app: appflowy-web + type: ClusterIP + +# (If you added appflowy-ai) +--- +apiVersion: v1 +kind: Service +metadata: + name: appflowy-ai + namespace: appflowy +spec: + ports: + - port: 5001 + targetPort: 5001 + protocol: TCP + name: http + selector: + app: appflowy-ai + type: ClusterIP \ No newline at end of file