- Listmonk: newsletter/mailing list manager with PostgreSQL backend, NodePort 32375, Postmark SMTP. Replaces Ghost's broken Mailgun-only newsletter sending via n8n automation pipeline. - Mattermost: team messaging manifest, NodePort 32374, PostgreSQL backend. - Ghost: added Postmark SMTP config for transactional email, disabled staffDeviceVerification on all three instances (Ghost has no TOTP, only email-based verification which requires working SMTP). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
134 lines
3.3 KiB
YAML
134 lines
3.3 KiB
YAML
# Listmonk — self-hosted newsletter and mailing list manager
|
|
# PostgreSQL backend via cluster DNS: postgres
|
|
# SMTP via Postmark
|
|
# Unpinned — scheduler places freely
|
|
# NodePort 32375
|
|
#
|
|
# Deploy:
|
|
# kubectl create secret generic listmonk-secret \
|
|
# --from-literal=db-password='<password>' \
|
|
# --from-literal=admin-password='<password>' \
|
|
# --from-literal=postmark-token='<token>'
|
|
# kubectl apply -f listmonk-db-init.yaml
|
|
# kubectl get jobs -w # wait for completion
|
|
# kubectl apply -f listmonk.yaml
|
|
#
|
|
# First run: Listmonk auto-runs DB migrations on startup.
|
|
# Admin UI: http://<any-node-wg-ip>:32375
|
|
#
|
|
# n8n integration: Ghost webhook -> n8n -> Listmonk API
|
|
# POST /api/campaigns to create campaign from Ghost post
|
|
# PUT /api/campaigns/{id}/status to trigger send
|
|
|
|
---
|
|
apiVersion: v1
|
|
kind: PersistentVolumeClaim
|
|
metadata:
|
|
name: listmonk-uploads-pvc
|
|
spec:
|
|
accessModes:
|
|
- ReadWriteOnce
|
|
storageClassName: local-path
|
|
resources:
|
|
requests:
|
|
storage: 5Gi
|
|
|
|
---
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: listmonk-config
|
|
data:
|
|
config.toml: |
|
|
[app]
|
|
address = "0.0.0.0:9000"
|
|
admin_username = "admin"
|
|
admin_password = ""
|
|
|
|
[db]
|
|
host = "postgres"
|
|
port = 5432
|
|
user = "listmonk_user"
|
|
password = ""
|
|
database = "listmonk_db"
|
|
ssl_mode = "disable"
|
|
max_open = 25
|
|
max_idle = 25
|
|
max_lifetime = "300s"
|
|
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: listmonk
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: listmonk
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: listmonk
|
|
spec:
|
|
containers:
|
|
- name: listmonk
|
|
image: listmonk/listmonk:latest
|
|
command: ["./listmonk", "--config", "/etc/listmonk/config.toml"]
|
|
env:
|
|
- name: LISTMONK_app__admin_password
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: listmonk-secret
|
|
key: admin-password
|
|
- name: LISTMONK_db__password
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: listmonk-secret
|
|
key: db-password
|
|
ports:
|
|
- containerPort: 9000
|
|
volumeMounts:
|
|
- name: config
|
|
mountPath: /etc/listmonk
|
|
- name: uploads
|
|
mountPath: /listmonk/uploads
|
|
initContainers:
|
|
- name: listmonk-install
|
|
image: listmonk/listmonk:latest
|
|
command: ["./listmonk", "--install", "--idempotent", "--yes", "--config", "/etc/listmonk/config.toml"]
|
|
env:
|
|
- name: LISTMONK_app__admin_password
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: listmonk-secret
|
|
key: admin-password
|
|
- name: LISTMONK_db__password
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: listmonk-secret
|
|
key: db-password
|
|
volumeMounts:
|
|
- name: config
|
|
mountPath: /etc/listmonk
|
|
volumes:
|
|
- name: config
|
|
configMap:
|
|
name: listmonk-config
|
|
- name: uploads
|
|
persistentVolumeClaim:
|
|
claimName: listmonk-uploads-pvc
|
|
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: listmonk
|
|
spec:
|
|
selector:
|
|
app: listmonk
|
|
ports:
|
|
- port: 9000
|
|
targetPort: 9000
|
|
nodePort: 32375
|
|
type: NodePort
|