31 Commits

Author SHA1 Message Date
billisdead 336ad5bd38 chore(values): set explicit passwords for local deployment
Helm Chart CI/CD / lint-test (push) Waiting to run
Helm Chart CI/CD / publish (push) Blocked by required conditions
Required since temporal-secret.yaml now validates via required().
Values match the credentials used at initial cluster install.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 08:41:56 +02:00
billisdead 92ceb76f23 fix(helm): address CodeRabbit review findings
NOTES.txt:
- Detect ingress scheme dynamically (http/https based on .Values.ingress.tls)
- Include first path in ingress URL output
- Use .Values.service.port in port-forward example instead of hardcoded 80
- Add -n {{ .Release.Namespace }} to all kubectl commands

postiz-config.yaml:
- Merge temporal enabled/external branches: external address now also emits
  TEMPORAL_NAMESPACE and TEMPORAL_TLS, not just TEMPORAL_ADDRESS

temporal-init-job.yaml:
- Use .Values.temporal.postgresql.seeds as PGHOST source (with fallback to
  bitnami sub-chart service name) so init job and runtime use the same host
- Switch to quoted heredoc (<<-'SQL') + psql --set to pass credentials as
  psql variables, preventing shell expansion from breaking on special chars

temporal-secret.yaml:
- Add required validation: temporal.postgresql.password must be set explicitly
  when temporal.enabled=true

values.yaml:
- Remove hardcoded default passwords (postgresPassword, temporal.postgresql.password)
  replaced with empty strings to avoid predictable default credentials

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 08:41:15 +02:00
billisdead 98231d5eaf fix(helm): skip temporal init job when reusing postgresql main user
Helm Chart CI/CD / lint-test (push) Has been cancelled
Helm Chart CI/CD / publish (push) Has been cancelled
When temporal.postgresql.user == postgresql.auth.username, the user
already exists with CREATEDB — temporalio/auto-setup handles database
creation itself. The init job only runs for a distinct dedicated user.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 18:38:05 +02:00
billisdead 6b0e1ff5f3 chore: ignore SQL dump files 2026-06-16 18:17:02 +02:00
billisdead b3f447d0a7 feat: merge feat/temporal-support into main
Helm Chart CI/CD / lint-test (push) Has been cancelled
Helm Chart CI/CD / publish (push) Has been cancelled
- Temporal support (temporalio/auto-setup:1.28.1, PostgreSQL-only, no ES)
- Init job creates temporal user via postgres superuser
- ~100 env/secrets vars added to cover full Postiz v2.21.8 documentation
- NOTES.txt with post-install guidance and warnings
- ROLLBACK.md with 4 rollback scenarios + branch/tag structure

Chart: v1.0.5 → v1.1.0 | appVersion: 1.3.0 → v2.21.8

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 18:13:59 +02:00
billisdead df80f0e46e docs: document branch structure and upstream tag reference
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 18:13:52 +02:00
billisdead 6738a6a8be Revert "docs: add rollback guide to official GitHub chart"
This reverts commit 104bc7a56f.
2026-06-16 18:11:13 +02:00
billisdead 104bc7a56f docs: add rollback guide to official GitHub chart
Covers 4 scenarios: normal ArgoCD rollback, Gitea outage emergency,
image rollback with/without DB restore, and rollback to a specific Gitea commit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 18:06:42 +02:00
billisdead c5b3c3b8a0 docs: add rollback guide to official GitHub chart
Covers 4 scenarios: normal ArgoCD rollback, Gitea outage emergency,
image rollback with/without DB restore, and rollback to a specific Gitea commit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 18:06:13 +02:00
billisdead fc931e4707 feat(helm): add Temporal support and expand env coverage for v2.21.8
- Chart.yaml: bump to version 1.1.0, appVersion v2.21.8
- values.yaml: add temporal section (enabled/address/namespace/tls/apiKey/postgresql),
  expand env (~40 non-sensitive vars) and secrets (~60 sensitive vars) to match
  current Postiz documentation — covers all social providers, email SMTP,
  OAuth OIDC, AI/generation, analytics, MCP, payments, short-link services
- postiz-config.yaml: inject TEMPORAL_ADDRESS (auto-computed or override),
  TEMPORAL_NAMESPACE and TEMPORAL_TLS when temporal.enabled or address is set
- temporal-deployment.yaml: temporalio/auto-setup:1.28.1, postgres12 backend,
  ES disabled, dynamicconfig volume mount, liveness/readiness probes
- temporal-service.yaml: ClusterIP on port 7233 (gRPC)
- temporal-dynamicconfig.yaml: ConfigMap with development-sql.yaml content
- temporal-init-job.yaml: post-install/upgrade Job that creates the temporal
  PostgreSQL user via the postgres superuser before Temporal starts
- temporal-secret.yaml: Secret for temporal PostgreSQL credentials
- NOTES.txt: post-install guidance, search-attribute creation reminder,
  multi-replica/local-storage warning, backup reminder

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 17:53:18 +02:00
James Read 5d6a9de2d5 Merge pull request #7 from kyrbrbik/main
Add extra containers for postiz
2025-01-02 08:52:31 +00:00
Jan Breitkopf 24fcde5f2e add extra containers for postiz 2024-12-10 12:09:13 +01:00
James Read f09e2ff4fe Merge pull request #5 from Mattchewone/feat/volumes
feat: add volumes / fix issue with port
2024-11-05 16:21:05 +00:00
Matt Chaffe fc3d9c0910 continue: add defaults 2024-11-05 12:23:31 +00:00
Matt Chaffe 466cff4aa1 continue: bump version 2024-10-25 11:14:16 +01:00
Matt Chaffe b5ebad80c8 feat: add volumes / fix issue with port 2024-10-25 10:19:37 +01:00
James Read 465e817e22 Merge pull request #4 from zktaiga/add/sa
Add `ServiceAccount` template
2024-10-22 09:11:54 +01:00
Taiga 36c0e0a733 Bump Helm chart 2024-10-20 22:12:14 +04:00
Taiga 80f4cf1e3f Add ServiceAccount template 2024-10-20 22:07:06 +04:00
James Read 0450089618 Merge pull request #2 from captainswain/feat/ingress
Add configurable ingress, rename all files to `.yaml` for conformity.

I'm going to merge this as clearly the chart lints, and is installable. Thanks @captainswain for your patience while we fiddle with and fix the CI job.

I'll do some testing offline on one of my Kubernetes clusters to see what sort of a timeout we need to set here on GitHub (that's why the job is still failing).
2024-10-04 15:36:54 +01:00
James Read 75414d80a9 Add bitnami deps 2024-10-04 15:26:03 +01:00
James Read 7037baed38 Fix maintainers in chart lint 2024-10-03 09:34:34 +01:00
James Read 024bc3fe46 Add maintainers which is causing lint failures.
Add maintainers
2024-10-03 09:10:30 +01:00
James Read a0bf125273 Fixing lint failure with \n at end of file 2024-10-03 08:56:27 +01:00
James Read e69f46a89a Newline at end of values.yaml required 2024-10-03 08:54:09 +01:00
James Read 9935992ef0 Remove trailing \n to fix lint 2024-10-03 08:50:12 +01:00
Shane Lindsay cb93b32c18 Remove trailing space from description 2024-10-02 21:04:09 -07:00
Shane Lindsay 005d53cce7 Add configurable ingress, rename all files to .yaml for conformity. 2024-09-29 23:39:28 -07:00
jamesread c62e37d16f appVersion 1.3.0 2024-09-23 09:27:46 +01:00
jamesread 7049cf5b70 Update some outdated actions 2024-09-23 09:17:48 +01:00
jamesread 199d6bf2ac Updated instructions to use OCI images 2024-09-23 09:14:33 +01:00
20 changed files with 794 additions and 44 deletions
@@ -5,12 +5,12 @@ on:
branches: [ main ]
paths:
- 'charts/**'
- '.github/workflows/helm-chart-ci-cd.yml'
- '.github/workflows/helm-chart-ci-cd.yaml'
pull_request:
branches: [ main ]
paths:
- 'charts/**'
- '.github/workflows/helm-chart-ci-cd.yml'
- '.github/workflows/helm-chart-ci-cd.yaml'
release:
types: [created]
@@ -32,6 +32,10 @@ jobs:
with:
version: v3.14.4
- name: Install Chart deps
run: |
helm repo add bitnami https://charts.bitnami.com/bitnami
- name: Set up Python
uses: actions/setup-python@v5
with:
@@ -65,10 +69,10 @@ jobs:
if: github.event_name == 'release'
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Set up Helm
uses: azure/setup-helm@v3
uses: azure/setup-helm@v4.2.0
with:
version: v3.11.1
@@ -85,14 +89,14 @@ jobs:
helm package ${{ env.CHART_PATH }}
- name: Run chart-releaser
uses: helm/chart-releaser-action@v1.5.0
uses: helm/chart-releaser-action@v1.6.0
env:
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
with:
charts_dir: charts
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
+1
View File
@@ -1 +1,2 @@
.DS_Store
*.sql
+30 -7
View File
@@ -10,11 +10,12 @@ This Helm chart deploys the Postiz application on a Kubernetes cluster using the
## Installing the Chart
The Postiz helm chart registry uses the OCI format, not HTTP, which means you do not need to do a `helm repo add` to install the chart. You can install the chart directly from the GitHub repository.
To install the chart with the release name `postiz-app`:
```bash
$ helm repo add postiz https://github.com/gitroomhq/postiz-helmchart
$ helm install postiz-app postiz/postiz
$ helm install postiz oci://ghcr.io/gitroomhq/postiz-helmchart/charts/postiz-app
```
The command deploys Postiz on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation.
@@ -23,7 +24,7 @@ The command deploys Postiz on the Kubernetes cluster in the default configuratio
## Uninstalling the Chart
To uninstall/delete the `postiz-app` deployment:
To uninstall/delete the `postiz` deployment:
```bash
$ helm delete postiz-app
@@ -49,6 +50,15 @@ The following table lists the configurable parameters of the Postiz chart and th
| `postgresql.auth.database` | PostgreSQL database | `postiz` |
| `redis.enabled` | Deploy Redis | `true` |
| `redis.auth.password` | Redis password | `postiz-redis-password` |
| `ingress.enabled` | Enable ingress controller resource | `false` |
| `ingress.className` | IngressClass that will be be used | `""` |
| `ingress.annotations` | Ingress annotations | `{}` |
| `ingress.hosts` | Ingress hostnames | `[]` |
| `ingress.tls` | Ingress TLS configuration | `[]` |
| `ingress.path` | Path within the host | `/` |
| `ingress.pathType` | Ingress path type | `ImplementationSpecific` |
| `extraVolumes` | Additional volumes to mount | `[{"name": "uploads-volume", "emptyDir": {}}]` |
| `extraVolumeMounts` | Additional volume mounts to use | `[{"name": "uploads-volume", "mountPath": "/uploads"}]` |
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
@@ -60,13 +70,26 @@ $ helm install postiz-app \
The above command sets the PostgreSQL password to `secretpassword`.
Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example,
Alternatively, you can use a YAML file to specify the values while installing the chart. Create a file called `custom-values.yaml` (or any name you prefer) and specify your values:
```bash
$ helm install postiz-app -f values.yaml postiz/postiz
```yaml
postgresql:
auth:
password: secretpassword
ingress:
enabled: true
hosts:
- host: postiz.example.com
```
> **Tip**: You can use the default [values.yaml](values.yaml)
Then, you can install the chart using the `-f` flag:
```bash
$ helm install postiz-app -f custom-values.yaml postiz/postiz
```
> **Tip**: You can use the default [values.yaml](values.yaml) as a starting point for your custom configuration.
## Persistence
+194
View File
@@ -0,0 +1,194 @@
# Rollback — Retour vers la chart officielle GitHub
Ce document couvre le retour de la source ArgoCD depuis ce fork Gitea
(`homegit.gyozamancave.fr/billisdead/postiz-helmchart`) vers la chart officielle
(`github.com/gitroomhq/postiz-helmchart`).
---
## Structure des branches et référence upstream
```
Tag upstream-1.0.5 → commit 5d6a9de2 (upstream exact, immuable)
gitroomhq/postiz-helmchart, chart v1.0.5, jan 2025
main → contenu fonctionnellement identique à upstream
(source déployée par ArgoCD)
feat/temporal-support → 5d6a9de2 → Temporal + env → ROLLBACK.md
(branche de travail pour l'upgrade v2.21.8)
```
### Inspecter le delta entre upstream et notre travail
```bash
# Tout ce qui a changé par rapport à l'upstream dans la chart
git diff upstream-1.0.5 feat/temporal-support -- charts/
# Juste les fichiers modifiés (sans le contenu)
git diff --name-only upstream-1.0.5 feat/temporal-support
# Comparer main avec upstream (doit être vide sur charts/)
git diff upstream-1.0.5 main -- charts/
```
### Synchroniser le tag upstream si l'upstream GitHub évolue
```bash
# Ajouter le remote GitHub si absent
git remote add upstream https://github.com/gitroomhq/postiz-helmchart
# Récupérer le nouvel upstream
git fetch upstream
# Créer un nouveau tag pour la nouvelle version upstream
git tag -a upstream-<version> upstream/main -m "Upstream gitroomhq à <version>"
git push origin upstream-<version>
```
---
## Contexte de référence
| Paramètre | Fork Gitea (actuel) | Chart officielle (cible rollback) |
|---|---|---|
| `repoURL` | `https://homegit.gyozamancave.fr/billisdead/postiz-helmchart` | `https://github.com/gitroomhq/postiz-helmchart` |
| `targetRevision` | `main` | `HEAD` |
| `path` | `charts/postiz` | `charts/postiz` |
Les `values` inline dans l'Application ArgoCD ne changent pas.
---
## Scénario 1 — Rollback normal (ArgoCD accessible)
```bash
kubectl patch application postiz -n argocd --type='json' -p='[
{"op": "replace", "path": "/spec/source/repoURL", "value": "https://github.com/gitroomhq/postiz-helmchart"},
{"op": "replace", "path": "/spec/source/targetRevision", "value": "HEAD"}
]'
kubectl annotate application postiz -n argocd \
argocd.argoproj.io/refresh=hard --overwrite
```
Vérification :
```bash
kubectl get application postiz -n argocd \
-o jsonpath='{"sync: "}{.status.sync.status}{"\nhealth: "}{.status.health.status}{"\nrevision: "}{.status.sync.revision}{"\n"}'
```
Résultat attendu : `sync: Synced`, `health: Healthy`, revision = dernier commit GitHub.
---
## Scénario 2 — Gitea inaccessible (rollback d'urgence)
Si `homegit.gyozamancave.fr` est down et qu'ArgoCD est bloqué en erreur de fetch,
appliquer le patch de la même façon — ArgoCD re-tentera depuis GitHub immédiatement.
```bash
# Même commande que le scénario 1 — ArgoCD abandonne le fetch Gitea dès que repoURL change
kubectl patch application postiz -n argocd --type='json' -p='[
{"op": "replace", "path": "/spec/source/repoURL", "value": "https://github.com/gitroomhq/postiz-helmchart"},
{"op": "replace", "path": "/spec/source/targetRevision", "value": "HEAD"}
]'
```
Si ArgoCD lui-même ne répond plus, patcher le CRD directement via le control plane :
```bash
# Requiert un accès direct à k3s-master
KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl patch application postiz -n argocd \
--type='json' -p='[
{"op": "replace", "path": "/spec/source/repoURL", "value": "https://github.com/gitroomhq/postiz-helmchart"},
{"op": "replace", "path": "/spec/source/targetRevision", "value": "HEAD"}
]'
```
---
## Scénario 3 — Rollback après upgrade image (ex. v2.11.2 → v2.21.8 cassé)
Le rollback de la source chart ne suffit pas si l'image Postiz a aussi été changée
**et que Prisma a migré le schéma DB**. Dans ce cas, la séquence est :
### 3a. Rollback image seule (si DB non migrée)
Éditer les values inline de l'Application ArgoCD et remettre le tag d'origine :
```yaml
image:
tag: "v2.11.2"
```
```bash
# Puis forcer le sync
kubectl annotate application postiz -n argocd \
argocd.argoproj.io/refresh=hard --overwrite
```
### 3b. Rollback image + restauration DB (si Prisma a migré)
> **Toujours faire un `pg_dump` avant tout upgrade.**
```bash
# 1. Scale down pour éviter les écritures pendant la restauration
kubectl scale deployment postiz-postiz-app --replicas=0 -n default
# 2. Identifier le pod PostgreSQL
PGPOD=$(kubectl get pod -n default -l app.kubernetes.io/name=postgresql -o jsonpath='{.items[0].metadata.name}')
# 3. Vider le schéma (le dump pg_dump sans --clean ne contient pas de DROP TABLE)
kubectl exec -n default "$PGPOD" -- bash -c \
'PGPASSWORD="<password>" psql -U postiz postiz -c \
"DROP SCHEMA public CASCADE; CREATE SCHEMA public; \
GRANT ALL ON SCHEMA public TO postiz; \
GRANT ALL ON SCHEMA public TO public;"'
# 4. Restaurer depuis le backup local
kubectl exec -i -n default "$PGPOD" -- bash -c \
'PGPASSWORD="<password>" psql -U postiz postiz' \
< /path/to/postiz-backup-YYYYMMDD.sql
# 5. Remettre le tag image v2.11.2 dans les values ArgoCD, puis scale up
kubectl scale deployment postiz-postiz-app --replicas=1 -n default
```
---
## Scénario 4 — Rollback vers un commit Gitea précis (pas GitHub)
Si le problème vient d'un commit spécifique sur le fork mais que la branche `main`
reste valide, pointer sur le SHA du dernier commit stable :
```bash
# Trouver le SHA stable (ex. avant le commit problématique)
git -C /home/billisdead/gitea-trucs/postiz-helm log --oneline main | head -10
# Patcher vers ce SHA
kubectl patch application postiz -n argocd --type='json' -p='[
{"op": "replace", "path": "/spec/source/targetRevision", "value": "<SHA>"}
]'
```
---
## Vérification post-rollback (tous scénarios)
```bash
# Source effective
kubectl get application postiz -n argocd \
-o jsonpath='{.spec.source.repoURL}{"\n"}{.spec.source.targetRevision}{"\n"}'
# État de santé
kubectl get application postiz -n argocd \
-o jsonpath='{"sync: "}{.status.sync.status}{"\nhealth: "}{.status.health.status}{"\n"}'
# Pod toujours Running sans restart
kubectl get pods -n default -l "app.kubernetes.io/name=postiz-app"
# Logs démarrage (vérifier absence d'erreur Temporal/DB/Redis)
kubectl logs -n default deployment/postiz-postiz-app --tail=30
```
+11 -4
View File
@@ -1,9 +1,16 @@
apiVersion: v2
name: postiz-app
description: A Social Media Scheduling App
description: A Social Media Scheduling App
type: application
version: 1.0.0 # Chart Version
appVersion: "1.2.0"
version: 1.1.0
appVersion: "v2.21.8"
maintainers:
- name: jonathan-irvin
email: offendingcommit@gmail.com
url: https://linktr.ee/offendingcommit
- name: jamesread
email: contact@jread.com
url: http://jread.com
keywords:
- social media
- marketing
@@ -21,4 +28,4 @@ dependencies:
- name: redis
version: 20.1.0
repository: https://charts.bitnami.com/bitnami
condition: redis.enabled
condition: redis.enabled
+46
View File
@@ -0,0 +1,46 @@
Postiz has been deployed!
Access URL:
{{- if .Values.ingress.enabled }}
{{ if .Values.ingress.tls }}https{{ else }}http{{ end }}://{{ (first .Values.ingress.hosts).host }}{{ (first (first .Values.ingress.hosts).paths).path }}
{{- else if eq .Values.service.type "NodePort" }}
http://<node-ip>:{{ .Values.service.nodePort }}
{{- else }}
kubectl port-forward svc/{{ include "postiz.fullname" . }} 5000:{{ .Values.service.port }}
http://localhost:5000
{{- end }}
{{- if .Values.temporal.enabled }}
Temporal:
Internal address : {{ include "postiz.fullname" . }}-temporal:7233
Status : kubectl -n {{ .Release.Namespace }} get pods -l app.kubernetes.io/component=temporal
Init job logs : kubectl -n {{ .Release.Namespace }} logs job/{{ include "postiz.fullname" . }}-temporal-init
After first deploy, create Temporal search attributes:
kubectl -n {{ .Release.Namespace }} exec deploy/{{ include "postiz.fullname" . }}-temporal -- \
temporal operator search-attribute create \
--namespace {{ .Values.temporal.namespace | default "default" }} \
--name organizationId --type Keyword \
--name postId --type Keyword
{{- else if .Values.temporal.address }}
Temporal (external): {{ .Values.temporal.address }}
{{- else }}
WARNING: Temporal is disabled and no address is configured.
Postiz v2.12.0+ requires Temporal for post scheduling.
Set temporal.enabled=true or provide temporal.address.
{{- end }}
{{- if and (gt (.Values.replicaCount | int) 1) (eq (.Values.env.STORAGE_PROVIDER | default "local") "local") }}
WARNING: replicaCount={{ .Values.replicaCount }} with STORAGE_PROVIDER=local is unsupported.
Local uploads are not shared across replicas. Use Cloudflare R2 or an RWX PVC.
{{- end }}
Upgrade reminder:
Always back up the PostgreSQL database before upgrading Postiz:
kubectl exec -n {{ .Release.Namespace }} <postgresql-pod> -- \
pg_dump -U {{ .Values.postgresql.auth.username }} {{ .Values.postgresql.auth.database }} \
> postiz-backup-$(date +%Y%m%d).sql
@@ -0,0 +1,15 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "postiz.fullname" . }}-config
labels:
{{- include "postiz.labels" . | nindent 4 }}
data:
{{- range $key, $value := .Values.env }}
{{ $key }}: {{ $value | quote }}
{{- end }}
{{- if or .Values.temporal.enabled .Values.temporal.address }}
TEMPORAL_ADDRESS: {{ default (printf "%s-temporal:7233" (include "postiz.fullname" .)) .Values.temporal.address | quote }}
TEMPORAL_NAMESPACE: {{ .Values.temporal.namespace | default "default" | quote }}
TEMPORAL_TLS: {{ .Values.temporal.tls | toString | quote }}
{{- end }}
-10
View File
@@ -1,10 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "postiz.fullname" . }}-config
labels:
{{- include "postiz.labels" . | nindent 4 }}
data:
{{- range $key, $value := .Values.env }}
{{ $key }}: {{ $value | quote }}
{{- end }}
+19 -2
View File
@@ -35,8 +35,15 @@ spec:
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: 3000
containerPort: 5000
protocol: TCP
volumeMounts:
{{- if .Values.extraVolumeMounts }}
{{- toYaml .Values.extraVolumeMounts | nindent 12 }}
{{- else }}
- name: uploads-volume
mountPath: /uploads
{{- end }}
envFrom:
- configMapRef:
name: {{ include "postiz.fullname" . }}-config
@@ -44,6 +51,9 @@ spec:
name: {{ include "postiz.fullname" . }}-secrets
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- if .Values.extraContainers }}
{{- toYaml .Values.extraContainers | nindent 8 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
@@ -55,4 +65,11 @@ spec:
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
volumes:
{{- if .Values.extraVolumes }}
{{- toYaml .Values.extraVolumes | nindent 8 }}
{{- else }}
- name: uploads-volume
emptyDir: {}
{{- end }}
@@ -0,0 +1,44 @@
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "postiz.fullname" . }}
labels:
{{- include "postiz.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: {{ .pathType }}
backend:
service:
name: {{ include "postiz.fullname" $ }}
port:
number: {{ .port }}
{{- end }}
{{- end }}
{{- if .Values.ingress.extraRules }}
{{- toYaml .Values.ingress.extraRules | nindent 4 }}
{{- end }}
{{- end }}
@@ -11,5 +11,8 @@ spec:
targetPort: http
protocol: TCP
name: http
{{- if .Values.service.additionalPorts }}
{{- toYaml .Values.service.additionalPorts | nindent 4 }}
{{- end }}
selector:
{{- include "postiz.selectorLabels" . | nindent 4 }}
{{- include "postiz.selectorLabels" . | nindent 4 }}
@@ -0,0 +1,12 @@
{{- if .Values.serviceAccount.create }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "postiz.serviceAccountName" . }}
labels:
{{- include "postiz.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
@@ -0,0 +1,68 @@
{{- if .Values.temporal.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "postiz.fullname" . }}-temporal
labels:
{{- include "postiz.labels" . | nindent 4 }}
app.kubernetes.io/component: temporal
spec:
replicas: 1
selector:
matchLabels:
{{- include "postiz.selectorLabels" . | nindent 6 }}
app.kubernetes.io/component: temporal
template:
metadata:
labels:
{{- include "postiz.selectorLabels" . | nindent 8 }}
app.kubernetes.io/component: temporal
spec:
containers:
- name: temporal
image: "{{ .Values.temporal.image.repository }}:{{ .Values.temporal.image.tag }}"
imagePullPolicy: {{ .Values.temporal.image.pullPolicy }}
ports:
- name: grpc
containerPort: 7233
protocol: TCP
env:
- name: DB
value: "postgres12"
- name: DB_PORT
value: "5432"
- name: POSTGRES_USER
value: {{ .Values.temporal.postgresql.user | quote }}
- name: POSTGRES_PWD
valueFrom:
secretKeyRef:
name: {{ include "postiz.fullname" . }}-temporal-secret
key: POSTGRES_PWD
- name: POSTGRES_SEEDS
value: {{ default (printf "%s-postgresql" .Release.Name) .Values.temporal.postgresql.seeds | quote }}
- name: DYNAMIC_CONFIG_FILE_PATH
value: "config/dynamicconfig/development-sql.yaml"
- name: ENABLE_ES
value: "false"
- name: TEMPORAL_NAMESPACE
value: {{ .Values.temporal.namespace | default "default" | quote }}
volumeMounts:
- name: dynamicconfig
mountPath: /etc/temporal/config/dynamicconfig
livenessProbe:
tcpSocket:
port: grpc
initialDelaySeconds: 30
periodSeconds: 15
failureThreshold: 5
readinessProbe:
tcpSocket:
port: grpc
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 5
volumes:
- name: dynamicconfig
configMap:
name: {{ include "postiz.fullname" . }}-temporal-dynamicconfig
{{- end }}
@@ -0,0 +1,16 @@
{{- if .Values.temporal.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "postiz.fullname" . }}-temporal-dynamicconfig
labels:
{{- include "postiz.labels" . | nindent 4 }}
data:
development-sql.yaml: |
limit.maxIDLength:
- value: 255
constraints: {}
system.forceSearchAttributesCacheRefreshOnRead:
- value: true
constraints: {}
{{- end }}
@@ -0,0 +1,77 @@
{{- if .Values.temporal.enabled }}
{{- if .Values.postgresql.enabled }}
{{- if ne .Values.temporal.postgresql.user .Values.postgresql.auth.username }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "postiz.fullname" . }}-temporal-init
labels:
{{- include "postiz.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "-5"
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
spec:
backoffLimit: 6
template:
metadata:
labels:
app.kubernetes.io/component: temporal-init
{{- include "postiz.selectorLabels" . | nindent 8 }}
spec:
restartPolicy: OnFailure
initContainers:
- name: wait-for-postgres
image: postgres:16-alpine
command:
- sh
- -c
- |
until pg_isready -h $PGHOST -p 5432 -U postgres; do
echo "Waiting for PostgreSQL..."; sleep 3
done
env:
- name: PGHOST
value: {{ default (printf "%s-postgresql" .Release.Name) .Values.temporal.postgresql.seeds | splitList "," | first | quote }}
containers:
- name: create-temporal-user
image: postgres:16-alpine
command:
- sh
- -c
- |
export PGPASSWORD="$POSTGRES_PASSWORD"
psql -h "$PGHOST" -U postgres \
--set=temporal_user="$TEMPORAL_USER" \
--set=temporal_pwd="$TEMPORAL_PWD" <<-'SQL'
DO $$ BEGIN
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = :'temporal_user') THEN
EXECUTE format(
'CREATE ROLE %I WITH LOGIN PASSWORD %L CREATEDB',
:'temporal_user',
:'temporal_pwd'
);
RAISE NOTICE 'Role created.';
ELSE
RAISE NOTICE 'Role already exists, skipping.';
END IF;
END $$;
SQL
env:
- name: PGHOST
value: {{ default (printf "%s-postgresql" .Release.Name) .Values.temporal.postgresql.seeds | splitList "," | first | quote }}
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: {{ printf "%s-postgresql" .Release.Name | quote }}
key: postgres-password
- name: TEMPORAL_USER
value: {{ .Values.temporal.postgresql.user | quote }}
- name: TEMPORAL_PWD
valueFrom:
secretKeyRef:
name: {{ include "postiz.fullname" . }}-temporal-secret
key: POSTGRES_PWD
{{- end }}
{{- end }}
{{- end }}
@@ -0,0 +1,14 @@
{{- if .Values.temporal.enabled }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "postiz.fullname" . }}-temporal-secret
labels:
{{- include "postiz.labels" . | nindent 4 }}
type: Opaque
data:
POSTGRES_PWD: {{ required "temporal.postgresql.password is required when temporal.enabled=true" .Values.temporal.postgresql.password | b64enc | quote }}
{{- if .Values.temporal.apiKey }}
TEMPORAL_API_KEY: {{ .Values.temporal.apiKey | b64enc | quote }}
{{- end }}
{{- end }}
@@ -0,0 +1,19 @@
{{- if .Values.temporal.enabled }}
apiVersion: v1
kind: Service
metadata:
name: {{ include "postiz.fullname" . }}-temporal
labels:
{{- include "postiz.labels" . | nindent 4 }}
app.kubernetes.io/component: temporal
spec:
type: ClusterIP
ports:
- port: 7233
targetPort: grpc
protocol: TCP
name: grpc
selector:
{{- include "postiz.selectorLabels" . | nindent 4 }}
app.kubernetes.io/component: temporal
{{- end }}
+214 -14
View File
@@ -23,6 +23,7 @@ securityContext: {}
service:
type: ClusterIP
port: 80
additionalPorts: []
ingress:
enabled: false
@@ -32,11 +33,18 @@ ingress:
- host: chart-example.local
paths:
- path: /
pathType: ImplementationSpecific
pathType: Prefix
port: 80
tls: []
extraRules: []
resources: {}
extraContainers: []
extraVolumes: []
extraVolumeMounts: []
autoscaling:
enabled: false
minReplicas: 1
@@ -49,18 +57,22 @@ tolerations: []
affinity: {}
# PostgreSQL configuration
# PostgreSQL configuration (Bitnami sub-chart)
postgresql:
enabled: true
auth:
username: postiz
password: postiz-password
database: postiz
# postgresPassword is used by the temporal init job to create the temporal user.
# Set this explicitly; if left empty, Bitnami generates a random password
# that the init job cannot retrieve.
postgresPassword: "postgres-admin-password"
service:
ports:
postgresql: 5432
# Redis configuration
# Redis configuration (Bitnami sub-chart)
redis:
enabled: true
auth:
@@ -70,21 +82,134 @@ redis:
ports:
redis: 6379
# Environment variables
# Temporal workflow orchestration (required since Postiz v2.12.0)
# temporal.enabled=true → deploys Temporal alongside Postiz using the postgresql sub-chart
# temporal.enabled=false → Temporal must be deployed separately; set temporal.address
temporal:
enabled: true
# address: override auto-computed service address (<release>-temporal:7233)
address: ""
namespace: "default"
tls: false
# apiKey: only required for Temporal Cloud; leave empty for self-hosted
apiKey: ""
image:
repository: temporalio/auto-setup
tag: "1.28.1"
pullPolicy: IfNotPresent
postgresql:
# Credentials for the temporal user created in the shared PostgreSQL instance.
# The init job creates this user via the postgres superuser before Temporal starts.
user: temporal
password: "temporal-password"
# seeds: PostgreSQL hostname. Defaults to the Bitnami postgresql sub-chart service.
seeds: ""
# Non-sensitive environment variables (injected via ConfigMap)
env:
# === Required ===
FRONTEND_URL: "http://localhost:4200"
NEXT_PUBLIC_BACKEND_URL: "http://localhost:3000"
BACKEND_INTERNAL_URL: "http://backend:3000"
BACKEND_INTERNAL_URL: "http://localhost:3000"
# === Application behaviour ===
IS_GENERAL: "true"
NX_ADD_PLUGINS: "false"
MAIN_URL: ""
DISABLE_REGISTRATION: "false"
RUN_CRON: ""
API_LIMIT: "90"
RESTRICT_UPLOAD_DOMAINS: ""
DISALLOW_PLUS: ""
DISABLE_IMAGE_COMPRESSION: "false"
MOBILE_APP_SCHEME: ""
NOT_SECURED: "false"
# === Storage ===
STORAGE_PROVIDER: "local"
UPLOAD_DIRECTORY: ""
NEXT_PUBLIC_UPLOAD_STATIC_DIRECTORY: ""
NX_ADD_PLUGINS: "false"
IS_GENERAL: "true"
CLOUDFLARE_REGION: "auto"
# Sensitive environment variables (to be stored in Secrets)
# === Email ===
EMAIL_PROVIDER: "resend"
EMAIL_HOST: ""
EMAIL_PORT: ""
EMAIL_SECURE: "false"
EMAIL_FROM_ADDRESS: ""
EMAIL_FROM_NAME: ""
# === OAuth / OIDC sign-in ===
POSTIZ_GENERIC_OAUTH: "false"
POSTIZ_OAUTH_URL: ""
POSTIZ_OAUTH_AUTH_URL: ""
POSTIZ_OAUTH_TOKEN_URL: ""
POSTIZ_OAUTH_USERINFO_URL: ""
POSTIZ_OAUTH_SCOPE: "openid profile email"
NEXT_PUBLIC_POSTIZ_OAUTH_DISPLAY_NAME: ""
NEXT_PUBLIC_POSTIZ_OAUTH_LOGO_URL: ""
# === Social providers — non-sensitive settings ===
X_URL: ""
DISABLE_X_ANALYTICS: ""
STRIP_LINKS_FROM_X_POSTS: ""
MASTODON_URL: "https://mastodon.social"
NEYNAR_LOGIN_URL: ""
MEWE_HOST: ""
# === MCP / Agent ===
MCP_URL: ""
BACKEND_URL: ""
# === Payments ===
FEE_AMOUNT: "0.05"
# === Analytics & tracking (frontend) ===
NEXT_PUBLIC_SENTRY_DSN: ""
NEXT_PUBLIC_GTM_ID: ""
NEXT_PUBLIC_FACEBOOK_PIXEL: ""
NEXT_PUBLIC_POSTHOG_HOST: ""
NEXT_PUBLIC_POSTHOG_KEY: ""
SENTRY_ORG: ""
SENTRY_PROJECT: ""
SENTRY_SPOTLIGHT: "false"
# === Misc frontend ===
NEXT_PUBLIC_DISCORD_SUPPORT: ""
NEXT_PUBLIC_POLOTNO: ""
NEXT_PUBLIC_VERSION: ""
NEXT_PUBLIC_APP_VERSION: ""
NEXT_PUBLIC_OVERRIDE_BACKEND_URL: ""
# === Runtime ===
PORT: "3000"
TZ: "UTC"
NODE_ENV: "production"
# Sensitive environment variables (injected via Secret)
secrets:
# === Required ===
DATABASE_URL: ""
REDIS_URL: ""
JWT_SECRET: ""
# === Storage — Cloudflare R2 ===
CLOUDFLARE_ACCOUNT_ID: ""
CLOUDFLARE_ACCESS_KEY: ""
CLOUDFLARE_SECRET_ACCESS_KEY: ""
CLOUDFLARE_BUCKETNAME: ""
CLOUDFLARE_BUCKET_URL: ""
# === Email ===
RESEND_API_KEY: ""
EMAIL_USER: ""
EMAIL_PASS: ""
# === OAuth / OIDC sign-in ===
POSTIZ_OAUTH_CLIENT_ID: ""
POSTIZ_OAUTH_CLIENT_SECRET: ""
# === Social providers ===
X_API_KEY: ""
X_API_SECRET: ""
LINKEDIN_CLIENT_ID: ""
@@ -93,9 +218,84 @@ secrets:
REDDIT_CLIENT_SECRET: ""
GITHUB_CLIENT_ID: ""
GITHUB_CLIENT_SECRET: ""
RESEND_API_KEY: ""
CLOUDFLARE_ACCOUNT_ID: ""
CLOUDFLARE_ACCESS_KEY: ""
CLOUDFLARE_SECRET_ACCESS_KEY: ""
CLOUDFLARE_BUCKETNAME: ""
CLOUDFLARE_BUCKET_URL: ""
FACEBOOK_APP_ID: ""
FACEBOOK_APP_SECRET: ""
INSTAGRAM_APP_ID: ""
INSTAGRAM_APP_SECRET: ""
THREADS_APP_ID: ""
THREADS_APP_SECRET: ""
YOUTUBE_CLIENT_ID: ""
YOUTUBE_CLIENT_SECRET: ""
GOOGLE_GMB_CLIENT_ID: ""
GOOGLE_GMB_CLIENT_SECRET: ""
TIKTOK_CLIENT_ID: ""
TIKTOK_CLIENT_SECRET: ""
PINTEREST_CLIENT_ID: ""
PINTEREST_CLIENT_SECRET: ""
DRIBBBLE_CLIENT_ID: ""
DRIBBBLE_CLIENT_SECRET: ""
DISCORD_CLIENT_ID: ""
DISCORD_CLIENT_SECRET: ""
DISCORD_BOT_TOKEN_ID: ""
SLACK_ID: ""
SLACK_SECRET: ""
SLACK_SIGNING_SECRET: ""
TELEGRAM_TOKEN: ""
TELEGRAM_BOT_NAME: ""
MASTODON_CLIENT_ID: ""
MASTODON_CLIENT_SECRET: ""
NEYNAR_CLIENT_ID: ""
NEYNAR_SECRET_KEY: ""
MEWE_APP_ID: ""
MEWE_API_KEY: ""
TWITCH_CLIENT_ID: ""
TWITCH_CLIENT_SECRET: ""
KICK_CLIENT_ID: ""
KICK_SECRET: ""
VK_ID: ""
WHOP_CLIENT_ID: ""
BEEHIIVE_API_KEY: ""
BEEHIIVE_PUBLICATION_ID: ""
LISTMONK_DOMAIN: ""
LISTMONK_USER: ""
LISTMONK_API_KEY: ""
LISTMONK_LIST_ID: ""
LISTMONK_WELCOME_TEMPLATE_ID: ""
EXTENSION_ID: ""
# === AI / Generation ===
OPENAI_API_KEY: ""
OPENAI_APP_CHALLANGE: ""
ELEVENSLABS_API_KEY: ""
FAL_KEY: ""
TAVILY_API_KEY: ""
KIEAI_API_KEY: ""
TRANSLOADIT_AUTH: ""
TRANSLOADIT_SECRET: ""
TRANSLOADIT_TEMPLATE: ""
# === Payments ===
STRIPE_PUBLISHABLE_KEY: ""
STRIPE_SECRET_KEY: ""
STRIPE_SIGNING_KEY: ""
STRIPE_SIGNING_KEY_CONNECT: ""
STRIPE_DISCOUNT_ID: ""
NOWPAYMENTS_API_KEY: ""
NOWPAYMENTS_AMOUNT: ""
# === Analytics secrets ===
FACEBOOK_PIXEL_ACCESS_TOKEN: ""
NEXT_PUBLIC_TRACKING_TRIAL: ""
DATAFAST_API_KEY: ""
DATAFAST_WEBSITE_ID: ""
SENTRY_AUTH_TOKEN: ""
# === MCP / Agent ===
AGENT_API_KEY: ""
AGENT_MEDIA_SSO_KEY: ""
# === Short-link providers ===
DUB_TOKEN: ""
SHORT_IO_SECRET_KEY: ""
KUTT_API_KEY: ""
LINK_DRIP_API_KEY: ""