Files
ansible-role-listmonk/templates/listmonk.yml.j2
T
claudeandClaude Opus 5.5 22a7ffe676 Initial listmonk role: eom.dev newsletter on Kubernetes
listmonk v6.2.0 with PostgreSQL 17, Dex login for listed admins,
delivery through postfix.eom.dev, Catppuccin public pages, Altcha
captcha and a double opt-in "eom.dev" list. Database-held settings
are converged by an idempotent SQL script, tested against v6.2.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 20:17:30 -05:00

148 lines
4.2 KiB
Django/Jinja

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ listmonk_name }}-uploads
namespace: {{ listmonk_namespace }}
labels:
app.kubernetes.io/name: listmonk
app.kubernetes.io/instance: {{ listmonk_name }}
spec:
accessModes: [ReadWriteOnce]
storageClassName: {{ listmonk_storage_class }}
resources:
requests:
storage: {{ listmonk_uploads_storage_size }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ listmonk_name }}
namespace: {{ listmonk_namespace }}
labels:
app.kubernetes.io/name: listmonk
app.kubernetes.io/instance: {{ listmonk_name }}
app.kubernetes.io/component: app
spec:
replicas: 1
# One writer: listmonk's campaign manager is not safe to run twice.
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/instance: {{ listmonk_name }}
app.kubernetes.io/component: app
template:
metadata:
labels:
app.kubernetes.io/name: listmonk
app.kubernetes.io/instance: {{ listmonk_name }}
app.kubernetes.io/component: app
annotations:
checksum/secret: {{ lookup('ansible.builtin.template', 'secret.yml.j2') | hash('sha256') }}
spec:
affinity: {{ listmonk_affinity | to_json }}
containers:
- name: listmonk
image: {{ listmonk_image }}
imagePullPolicy: {{ listmonk_image_pull_policy }}
# --config '' : configuration comes from the environment only.
# --install --idempotent only installs into an empty database;
# --upgrade runs migrations after an image bump.
command:
- sh
- -c
- >-
./listmonk --install --idempotent --yes --config '' &&
./listmonk --upgrade --yes --config '' &&
exec ./listmonk --config ''
env:
- name: TZ
value: America/New_York
- name: LISTMONK_app__address
value: 0.0.0.0:9000
- name: LISTMONK_db__host
value: {{ listmonk_name }}-db
- name: LISTMONK_db__port
value: "5432"
- name: LISTMONK_db__user
value: listmonk
- name: LISTMONK_db__database
value: listmonk
- name: LISTMONK_db__ssl_mode
value: disable
envFrom:
- secretRef:
name: {{ listmonk_name }}
ports:
- name: http
containerPort: 9000
startupProbe:
httpGet:
path: /health
port: http
periodSeconds: 5
failureThreshold: 60
readinessProbe:
httpGet:
path: /health
port: http
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: http
periodSeconds: 30
timeoutSeconds: 5
resources: {{ listmonk_resources | to_json }}
volumeMounts:
- name: uploads
mountPath: /listmonk/uploads
volumes:
- name: uploads
persistentVolumeClaim:
claimName: {{ listmonk_name }}-uploads
---
apiVersion: v1
kind: Service
metadata:
name: {{ listmonk_name }}
namespace: {{ listmonk_namespace }}
labels:
app.kubernetes.io/name: listmonk
app.kubernetes.io/instance: {{ listmonk_name }}
spec:
selector:
app.kubernetes.io/instance: {{ listmonk_name }}
app.kubernetes.io/component: app
ports:
- name: http
port: 80
targetPort: http
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ listmonk_name }}
namespace: {{ listmonk_namespace }}
labels:
app.kubernetes.io/name: listmonk
app.kubernetes.io/instance: {{ listmonk_name }}
annotations: {{ listmonk_ingress_annotations | to_json }}
spec:
ingressClassName: {{ listmonk_ingress_class_name }}
tls:
- hosts:
- {{ listmonk_host }}
secretName: {{ listmonk_tls_secret_name }}
rules:
- host: {{ listmonk_host }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ listmonk_name }}
port:
name: http