Mailcow: Factor out main image into a separate Nix file.
diff --git a/mailcow/default.nix b/mailcow/default.nix
new file mode 100644
index 0000000..2691722
--- /dev/null
+++ b/mailcow/default.nix
@@ -0,0 +1,133 @@
+{ system ? builtins.currentSystem }:
+let
+  pkgs = import <nixpkgs> { inherit system; };
+
+in
+let
+  img = spec: {
+    streamed = pkgs.dockerTools.streamLayeredImage spec;
+    layered = pkgs.dockerTools.buildLayeredImage spec;
+    image = pkgs.dockerTools.buildImage spec;
+  };
+
+in
+let
+  dockerComposeOverrideYaml =
+    pkgs.writeTextDir "docker-compose.override.yml" ''
+      version: '2.1'
+
+      services:
+        mysql-mailcow:
+          image: alpine/socat:1.0.3
+          command:
+            - UNIX-LISTEN:/var/run/mysqld/mysqld.sock,reuseaddr,fork,unlink-early,mode=0777
+            - TCP-CONNECT:mysql.system.svc.cluster.local.:3306
+          volumes:
+            - mysql-socket-vol-1:/var/run/mysqld/:Z
+          restart: always
+
+        netfilter-mailcow:
+          build: ./data/Dockerfiles/netfilter
+
+        watchdog-mailcow:
+          build: ./data/Dockerfiles/watchdog
+
+      volumes:
+        vmail-vol-1:                {driver: local, driver_opts: {o: bind, type: none, device: "/vol/vmail"}}
+        vmail-index-vol-1:          {driver: local, driver_opts: {o: bind, type: none, device: "/vol/vmail-index"}}
+        mysql-vol-1:                {driver: local, driver_opts: {o: bind, type: none, device: "/run/mysql"}}
+        mysql-socket-vol-1:         {driver: local, driver_opts: {o: bind, type: none, device: "/run/mysql-socket"}}
+        redis-vol-1:                {driver: local, driver_opts: {o: bind, type: none, device: "/vol/redis-data"}}
+        rspamd-vol-1:               {driver: local, driver_opts: {o: bind, type: none, device: "/vol/rspamd-data"}}
+        solr-vol-1:                 {driver: local, driver_opts: {o: bind, type: none, device: "/vol/solr-data"}}
+        postfix-vol-1:              {driver: local, driver_opts: {o: bind, type: none, device: "/vol/postfix-data"}}
+        crypt-vol-1:                {driver: local, driver_opts: {o: bind, type: none, device: "/vol/crypt-data"}}
+        sogo-web-vol-1:             {driver: local, driver_opts: {o: bind, type: none, device: "/vol/sogo-web"}}
+        sogo-userdata-backup-vol-1: {driver: local, driver_opts: {o: bind, type: none, device: "/vol/sogo-userdata-backup"}}
+    '';
+
+  init =
+    pkgs.writeShellScriptBin "init" ''
+      set -xeuo pipefail
+
+      if ! [ -e /vol/docker-data/docker.ext4 ]; then
+          ${pkgs.busybox}/bin/dd if=/dev/zero of=/vol/docker-data/docker.ext4 bs=1G count=0 seek=30
+          ${pkgs.e2fsprogs}/bin/mkfs.ext4 /vol/docker-data/docker.ext4
+      fi
+      ${pkgs.e2fsprogs}/bin/e2fsck -y /vol/docker-data/docker.ext4
+      ${pkgs.busybox}/bin/mkdir -p /var/lib/docker
+      ${pkgs.busybox}/bin/mount -o loop,rw /vol/docker-data/docker.ext4 /var/lib/docker
+
+      ${pkgs.docker}/bin/dockerd --storage-driver=overlay2 &
+      sleep 10s
+
+      ${pkgs.docker}/bin/docker kill $(${pkgs.docker}/bin/docker ps -a -q) || :
+      ${pkgs.docker}/bin/docker system prune --volumes --force || :
+
+      ${pkgs.docker-compose}/bin/docker-compose -f /mailcow-dockerized/docker-compose.yml -f ${dockerComposeOverrideYaml}/docker-compose.override.yml build
+
+      ${pkgs.busybox}/bin/mkdir -p /tmp /run/{mysql,mysql-socket}
+      exec ${pkgs.docker-compose}/bin/docker-compose --env-file /mailcow-dockerized/mailcow.conf -f /mailcow-dockerized/docker-compose.yml -f ${dockerComposeOverrideYaml}/docker-compose.override.yml up --remove-orphans
+    '';
+
+  src = ./src;
+
+  extraDeps = with pkgs; [
+    # for Docker
+    cacert
+
+    # for update.sh
+    bash
+    coreutils
+    curl
+    docker
+    docker-compose
+    findutils
+    gawk
+    gitMinimal
+  ];
+
+  maintenanceDeps = with pkgs; [
+    bash
+    busybox
+    coreutils
+    findutils
+    pxattr
+    strace
+  ];
+
+in
+img {
+  name = "docker.benkard.de/mulk/mailcow";
+  tag = "latest";
+  maxLayers = 125;
+  contents = extraDeps ++ maintenanceDeps;
+  extraCommands =
+    ''
+      #!${pkgs.runtimeShell}
+
+      install -dm755 vol/{crypt-data,postfix-data,redis-data,rspamd-data,sogo-web,sogo-userdata-backup,solr-data,vmail,vmail-index,web-data}
+
+      cp -a ${src}/* .
+    '';
+  config = {
+    Entrypoint = [ "${init}/bin/init" ];
+    Cmd = [ ];
+    Workdir = "/mailcow-dockerized";
+    Volumes = {
+      "/mailcow-dockerized/data/conf" = { };
+      "/mailcow-dockerized/data/assets/ssl" = { };
+      "/vol/crypt-data" = { };
+      "/vol/docker-data" = { };
+      "/vol/postfix-data" = { };
+      "/vol/redis-data" = { };
+      "/vol/rspamd-data" = { };
+      "/vol/sogo-web" = { };
+      "/vol/sogo-userdata-backup" = { };
+      "/vol/solr-data" = { };
+      "/vol/vmail" = { };
+      "/vol/vmail-index" = { };
+      "/vol/web-data" = { };
+    };
+  };
+}