Mailcow: Move to Nix and Docker-Compose.
diff --git a/mailcow/mailcow.yaml b/mailcow/mailcow.yaml
new file mode 100644
index 0000000..a403259
--- /dev/null
+++ b/mailcow/mailcow.yaml
@@ -0,0 +1,475 @@
+---
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+  name: mailcow
+  namespace: mulk
+  labels:
+    name: mailcow
+    k8s-app: mailcow
+  annotations:
+    kubernetes.io/ingress.class: traefik
+    traefik.ingress.kubernetes.io/preserve-host: "true"
+spec:
+  rules:
+    - host: mail.benkard.de
+      http:
+        paths:
+          - path: /
+            backend:
+              serviceName: mailcow
+              servicePort: 80
+    - host: autodiscover.benkard.de
+      http:
+        paths:
+          - path: /
+            backend:
+              serviceName: mailcow
+              servicePort: 80
+
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: mailcow-pub
+  namespace: mulk
+  labels:
+    name: mailcow-pub
+    k8s-app: mailcow
+spec:
+  selector:
+    name: mailcow
+  type: NodePort
+  externalTrafficPolicy: Local
+  ports:
+    - name: smtp-alt
+      port: 31025
+      targetPort: 25
+      protocol: TCP
+      nodePort: 31025
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: mailcow
+  namespace: mulk
+  labels:
+    name: mailcow
+    k8s-app: mailcow
+spec:
+  selector:
+    name: mailcow
+  type: ClusterIP
+  ports:
+    - name: http
+      port: 80
+      targetPort: 80
+      protocol: TCP
+
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: mailcow
+  namespace: mulk
+  labels:
+    name: mailcow
+    k8s-app: mailcow
+
+spec:
+  replicas: 1
+
+  strategy:
+    rollingUpdate:
+      maxSurge: 1
+      maxUnavailable: 1
+
+  selector:
+    matchLabels:
+      k8s-app: mailcow
+      name: mailcow
+
+  template:
+    metadata:
+      labels:
+        name: mailcow
+        k8s-app: mailcow
+
+    spec:
+      imagePullSecrets:
+        - name: portus-token
+
+      runtimeClassName: kata
+
+      containers:
+        - name: master
+          image: docker.benkard.de/mulk/mailcow:latest
+
+          securityContext:
+            # In a Kata container, this only gives the container full
+            # access to the guest VM rather than the host.  (To ensure
+            # this, it is important to set privileged_without_host_devices
+            # = true in the [plugins.cri.containerd.runtimes.kata] section
+            # of containerd's config.toml.)
+            privileged: true
+
+          env:
+            - name: COMPOSE_HTTP_TIMEOUT
+              value: "600"
+
+          ports:
+            - name: http
+              containerPort: 80
+            - name: smtp
+              hostPort: 25
+              containerPort: 25
+            - name: pop
+              hostPort: 110
+              containerPort: 110
+            - name: imap
+              hostPort: 143
+              containerPort: 143
+            - name: smtps
+              hostPort: 465
+              containerPort: 465
+            - name: submission
+              hostPort: 587
+              containerPort: 587
+            - name: imaps
+              hostPort: 993
+              containerPort: 993
+            - name: pops
+              hostPort: 995
+              containerPort: 995
+            - name: sieve
+              hostPort: 4190
+              containerPort: 4190
+            - name: doveadm
+              hostPort: 19991
+              containerPort: 12345
+
+          volumeMounts:
+            # Configuration data.
+            - name: assets
+              subPath: ssl
+              mountPath: /mailcow-dockerized/data/assets/ssl
+            - name: config
+              mountPath: /mailcow-dockerized/data/conf
+            - name: secrets
+              subPath: mailcow.conf
+              mountPath: /mailcow-dockerized/mailcow.conf
+
+            # State.
+            - name: crypt-data
+              mountPath: /vol/crypt-data
+            - name: postfix-data
+              mountPath: /vol/postfix-data
+            - name: redis-data
+              mountPath: /vol/redis-data
+            - name: rspamd-data
+              mountPath: /vol/rspamd-data
+            - name: solr-data
+              mountPath: /vol/solr-data
+            - name: sogo-web
+              mountPath: /vol/sogo-web
+            - name: sogo-userdata-backup
+              mountPath: /vol/sogo-userdata-backup
+            - name: vmail
+              mountPath: /vol/vmail
+            - name: vmail-index
+              mountPath: /vol/vmail-index
+            - name: web-data
+              mountPath: /vol/web-data
+            #- name: docker-data
+            #  subPath: vfs
+            #  mountPath: /var/lib/docker/vfs
+            #- name: docker-data
+            #  subPath: image
+            #  mountPath: /var/lib/docker/image
+            #- name: docker-data
+            #  subPath: overlay2
+            #  mountPath: /var/lib/docker/overlay2
+            #- name: docker-data
+            #  mountPath: /var/lib/docker
+            - name: docker-data
+              mountPath: /vol/docker-data
+
+      volumes:
+        - name: assets
+          persistentVolumeClaim:
+            claimName: mailcow-assets
+        - name: config
+          persistentVolumeClaim:
+            claimName: mailcow-config-v2
+        - name: crypt-data
+          persistentVolumeClaim:
+            claimName: mailcow-crypt
+        - name: postfix-data
+          persistentVolumeClaim:
+            claimName: mailcow-postfix
+        - name: redis-data
+          persistentVolumeClaim:
+            claimName: mailcow-redis
+        - name: rspamd-data
+          persistentVolumeClaim:
+            claimName: mailcow-rspamd
+        - name: solr-data
+          persistentVolumeClaim:
+            claimName: mailcow-solr
+        - name: sogo-web
+          persistentVolumeClaim:
+            claimName: mailcow-sogo-web
+        - name: sogo-userdata-backup
+          persistentVolumeClaim:
+            claimName: mailcow-sogo-userdata-backup
+        - name: vmail
+          persistentVolumeClaim:
+            claimName: mailcow-vmail
+        - name: vmail-index
+          persistentVolumeClaim:
+            claimName: mailcow-vmail-index
+        - name: web-data
+          persistentVolumeClaim:
+            claimName: mailcow-web
+        - name: docker-data
+          persistentVolumeClaim:
+            claimName: mailcow-docker
+        - name: secrets
+          secret:
+            secretName: mailcow-secrets
+
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: mailcow-web
+  namespace: mulk
+  labels:
+    k8s-app: mailcow
+  annotations:
+    volume.beta.kubernetes.io/storage-provisioner: rancher.io/local-path
+    volume.kubernetes.io/selected-node: ifirn
+spec:
+  storageClassName: local-path
+  accessModes:
+    - ReadWriteOnce
+  resources:
+    requests:
+      storage: 1Gi
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: mailcow-docker
+  namespace: mulk
+  labels:
+    k8s-app: mailcow
+  annotations:
+    volume.beta.kubernetes.io/storage-provisioner: rancher.io/local-path
+    volume.kubernetes.io/selected-node: ifirn
+spec:
+  storageClassName: local-path
+  accessModes:
+    - ReadWriteOnce
+  resources:
+    requests:
+      storage: 1Gi
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: mailcow-assets
+  namespace: mulk
+  labels:
+    k8s-app: mailcow
+  annotations:
+    volume.beta.kubernetes.io/storage-provisioner: rancher.io/local-path
+    volume.kubernetes.io/selected-node: ifirn
+spec:
+  storageClassName: local-path
+  accessModes:
+    - ReadWriteOnce
+  resources:
+    requests:
+      storage: 1Gi
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: mailcow-solr
+  namespace: mulk
+  labels:
+    k8s-app: mailcow
+  annotations:
+    volume.beta.kubernetes.io/storage-provisioner: rancher.io/local-path
+    volume.kubernetes.io/selected-node: ifirn
+spec:
+  storageClassName: local-path
+  accessModes:
+    - ReadWriteOnce
+  resources:
+    requests:
+      storage: 1Gi
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: mailcow-sogo-web
+  namespace: mulk
+  labels:
+    k8s-app: mailcow
+  annotations:
+    volume.beta.kubernetes.io/storage-provisioner: rancher.io/local-path
+    volume.kubernetes.io/selected-node: ifirn
+spec:
+  storageClassName: local-path
+  accessModes:
+    - ReadWriteOnce
+  resources:
+    requests:
+      storage: 1Gi
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: mailcow-sogo-userdata-backup
+  namespace: mulk
+  labels:
+    k8s-app: mailcow
+  annotations:
+    volume.beta.kubernetes.io/storage-provisioner: rancher.io/local-path
+    volume.kubernetes.io/selected-node: ifirn
+spec:
+  storageClassName: local-path
+  accessModes:
+    - ReadWriteOnce
+  resources:
+    requests:
+      storage: 1Gi
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: mailcow-vmail
+  namespace: mulk
+  labels:
+    k8s-app: mailcow
+  annotations:
+    volume.beta.kubernetes.io/storage-provisioner: rancher.io/local-path
+    volume.kubernetes.io/selected-node: ifirn
+spec:
+  storageClassName: local-path
+  accessModes:
+    - ReadWriteOnce
+  resources:
+    requests:
+      storage: 1Gi
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: mailcow-vmail-index
+  namespace: mulk
+  labels:
+    k8s-app: mailcow
+  annotations:
+    volume.beta.kubernetes.io/storage-provisioner: rancher.io/local-path
+    volume.kubernetes.io/selected-node: ifirn
+spec:
+  storageClassName: local-path
+  accessModes:
+    - ReadWriteOnce
+  resources:
+    requests:
+      storage: 1Gi
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: mailcow-redis
+  namespace: mulk
+  labels:
+    k8s-app: mailcow
+  annotations:
+    volume.beta.kubernetes.io/storage-provisioner: rancher.io/local-path
+    volume.kubernetes.io/selected-node: ifirn
+spec:
+  storageClassName: local-path
+  accessModes:
+    - ReadWriteOnce
+  resources:
+    requests:
+      storage: 1Gi
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: mailcow-rspamd
+  namespace: mulk
+  labels:
+    k8s-app: mailcow
+  annotations:
+    volume.beta.kubernetes.io/storage-provisioner: rancher.io/local-path
+    volume.kubernetes.io/selected-node: ifirn
+spec:
+  storageClassName: local-path
+  accessModes:
+    - ReadWriteOnce
+  resources:
+    requests:
+      storage: 1Gi
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: mailcow-postfix
+  namespace: mulk
+  labels:
+    k8s-app: mailcow
+  annotations:
+    volume.beta.kubernetes.io/storage-provisioner: rancher.io/local-path
+    volume.kubernetes.io/selected-node: ifirn
+spec:
+  storageClassName: local-path
+  accessModes:
+    - ReadWriteOnce
+  resources:
+    requests:
+      storage: 1Gi
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: mailcow-crypt
+  namespace: mulk
+  labels:
+    k8s-app: mailcow
+  annotations:
+    volume.beta.kubernetes.io/storage-provisioner: rancher.io/local-path
+    volume.kubernetes.io/selected-node: ifirn
+spec:
+  storageClassName: local-path
+  accessModes:
+    - ReadWriteOnce
+  resources:
+    requests:
+      storage: 1Gi
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: mailcow-config-v2
+  namespace: mulk
+  labels:
+    k8s-app: mailcow
+  annotations:
+    volume.beta.kubernetes.io/storage-provisioner: rancher.io/local-path
+    volume.kubernetes.io/selected-node: ifirn
+spec:
+  storageClassName: local-path
+  accessModes:
+    - ReadWriteOnce
+  resources:
+    requests:
+      storage: 1Gi
+---