Files
claudeandClaude Opus 5.5 a58a99bf3b Mount base.html by subPath; ConfigMap ..data dirs crash listmonk
A whole-directory ConfigMap mount puts ..data symlink dirs in
--static-dir, which listmonk refuses to read (CrashLoopBackOff).

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

160 lines
4.9 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') }}
checksum/email: {{ lookup('ansible.builtin.template', 'email-configmap.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. --static-dir
# overlays the eom.dev system e-mail header/footer (base.html).
command:
- sh
- -c
- >-
./listmonk --install --idempotent --yes --config '' &&
./listmonk --upgrade --yes --config '' &&
exec ./listmonk --config '' --static-dir /listmonk/static-eom
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
# Mount the single file: a ConfigMap directory holds ..data
# symlink dirs that listmonk's static loader refuses to read.
# (Not live-updated; checksum/email rolls the pod instead.)
- name: email-templates
mountPath: /listmonk/static-eom/email-templates/base.html
subPath: base.html
readOnly: true
volumes:
- name: email-templates
configMap:
name: {{ listmonk_name }}-email-templates
- 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