Mailcow: Move to Nix and Docker-Compose.
diff --git a/images.nix b/images.nix
new file mode 100644
index 0000000..186dcf1
--- /dev/null
+++ b/images.nix
@@ -0,0 +1,417 @@
+{ 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
+{
+
+ # ejabberd = pkgs.dockerTools.buildImage {
+ # name = "docker.benkard.de/mulk/ejabberd";
+ # tag = "latest";
+ # contents = [
+ # pkgs.ejabberd
+ # pkgs.bash
+ # pkgs.nano
+ # ];
+ # config = {
+ # Env = [ ];
+ # ExposedPorts = { };
+ # WorkingDir = "/";
+ # Volumes = {
+ # "/data" = { };
+ # };
+ # };
+ # };
+
+ prosody = img {
+ name = "docker.benkard.de/mulk/prosody";
+ #tag = "latest";
+ contents = with pkgs; [
+ prosody
+ bash
+ coreutils
+ nano
+ ];
+ config = {
+ Entrypoint = [ "/bin/bash" ];
+ Cmd = [ ];
+ Env = [ ];
+ ExposedPorts = { };
+ WorkingDir = "/";
+ Volumes = {
+ "/data" = { };
+ };
+ };
+ };
+
+ mailcow =
+ let
+ dockerComposeOverrideYaml =
+ pkgs.writeTextDir "docker-compose.override.yml" ''
+ 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
+
+ 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.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 = ./mailcow/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" = { };
+ };
+ };
+ };
+
+ nextcloud = img {
+ name = "docker.benkard.de/mulk/nextcloud";
+ contents =
+ let
+ baseDependencies = with pkgs; [
+ # Service dependencies.
+ apacheHttpd
+ apacheHttpdPackages.php
+
+ # Optional dependencies.
+ ffmpeg
+
+ # Maintenance and manual upgrades.
+ bash
+ coreutils
+ php
+ unzip
+ ];
+
+ phpModules = with pkgs.php74Extensions; [
+ # Required dependencies.
+ ctype
+ curl
+ dom
+ gd
+ iconv
+ json
+ mbstring
+ openssl
+ pdo_pgsql
+ posix
+ session
+ simplexml
+ xml
+ xmlreader
+ xmlwriter
+ zip
+ zlib
+
+ # Recommended dependencies.
+ bz2
+ intl
+ fileinfo
+
+ # Optional dependencies.
+ apcu
+ bcmath
+ ftp
+ gmp
+ imagick
+ memcached
+ pcntl
+ redis
+ #smbclient
+ ];
+ in
+ baseDependencies ++ phpModules;
+ config = {
+ WorkingDir = "/var/www/html";
+ Volumes = {
+ "/var/www/html" = { };
+ };
+ };
+ };
+
+ webcron = img {
+ name = "docker.benkard.de/mulk/webcron";
+ contents =
+ with pkgs; [
+ # Entry points.
+ curl
+ ];
+ config = {
+ Entrypoint = [ "curl" "-fsS" ];
+ Cmd = [ ];
+ Volumes = { };
+ };
+ };
+
+ samba =
+ let
+ runner =
+ pkgs.stdenv.mkDerivation {
+ name = "mulk-samba-runner";
+ buildInputs = with pkgs; [ bash ];
+ src = ./samba;
+ builder = builtins.toFile "builder.sh" ''
+ source $stdenv/setup
+ set -euo pipefail
+ set -x
+
+ install -Dm755 $src/init $out/init
+
+ for svc in avahi dbus nmbd smbd; do
+ install -Dm755 $src/service/$svc/run $out/service/$svc/run
+ done
+
+ set +x
+ '';
+ };
+
+ in
+ img {
+ name = "docker.benkard.de/mulk/samba";
+ contents = with pkgs; [
+ # Services.
+ avahi
+ dbus
+ #samba4Full
+ (samba.override { enableMDNS = true; enableProfiling = false; enableRegedit = false; })
+
+ # Control.
+ execline
+ gnused
+ runner
+ s6
+
+ # Maintenance.
+ busybox
+ ];
+ extraCommands =
+ let
+ dbusSystemConf =
+ builtins.toFile "dbus-1-system.conf" ''
+ <!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+ <busconfig>
+ <type>system</type>
+ <auth>ANONYMOUS</auth>
+ <!-- <auth>EXTERNAL</auth> -->
+ <allow_anonymous/>
+ <listen>unix:path=/run/dbus/system_bus_socket</listen>
+ <standard_system_servicedirs/>
+
+ <policy context="default">
+ <allow user="*"/>
+
+ <deny own="*"/>
+ <deny send_type="method_call"/>
+
+ <allow send_type="signal"/>
+ <allow send_requested_reply="true" send_type="method_return"/>
+ <allow send_requested_reply="true" send_type="error"/>
+
+ <allow receive_type="method_call"/>
+ <allow receive_type="method_return"/>
+ <allow receive_type="error"/>
+ <allow receive_type="signal"/>
+
+ <allow send_destination="org.freedesktop.DBus"
+ send_interface="org.freedesktop.DBus" />
+ <allow send_destination="org.freedesktop.DBus"
+ send_interface="org.freedesktop.DBus.Introspectable"/>
+ <allow send_destination="org.freedesktop.DBus"
+ send_interface="org.freedesktop.DBus.Properties"/>
+
+ <deny send_destination="org.freedesktop.DBus"
+ send_interface="org.freedesktop.DBus"
+ send_member="UpdateActivationEnvironment"/>
+ <deny send_destination="org.freedesktop.DBus"
+ send_interface="org.freedesktop.DBus.Debug.Stats"/>
+ <deny send_destination="org.freedesktop.DBus"
+ send_interface="org.freedesktop.systemd1.Activator"/>
+ </policy>
+
+ <policy context="default">
+ <allow own="org.freedesktop.Avahi"/>
+ </policy>
+
+ <includedir>/share/dbus-1/system.d</includedir>
+ </busconfig>
+ '';
+
+ avahiDaemonConf =
+ builtins.toFile "avahi-daemon.conf" ''
+ [server]
+ use-ipv4=yes
+ use-ipv6=yes
+ enable-dbus=yes
+ ratelimit-interval-usec=1000000
+ ratelimit-burst=1000
+
+ [wide-area]
+ enable-wide-area=no
+
+ [publish]
+ add-service-cookie=no
+ publish-addresses=no
+ publish-hinfo=no
+ publish-workstation=no
+ publish-domain=no
+ publish-aaaa-on-ipv4=yes
+ publish-a-on-ipv6=no
+
+ [reflector]
+
+ [rlimits]
+ '';
+
+ group =
+ builtins.toFile "group" ''
+ dbus::997:
+ avahi::998:
+ '';
+
+ passwd =
+ builtins.toFile "passwd" ''
+ dbus::997:997::/tmp:/nonexistent
+ avahi::998:998::/tmp:/nonexistent
+ nobody::999:999::/tmp:/nonexistent
+ '';
+ in
+ ''
+ #!${pkgs.runtimeShell}
+
+ rm -rf -- etc/avahi/services/*
+
+ install -dm755 tmp run run/dbus var/run/samba var/log/samba var/lock/samba var/locks/samba var/lib/samba/private var/cache/samba
+
+ touch var/lib/samba/registry.tdb var/lib/samba/account_policy.tdb
+
+ install -Dm644 ${dbusSystemConf} etc/dbus-1/system.conf
+ install -Dm644 ${avahiDaemonConf} etc/avahi/avahi-daemon.conf
+ install -Dm644 ${group} etc/group
+ install -Dm644 ${passwd} etc/passwd
+ '';
+ config = {
+ Entrypoint = [ "/init" ];
+ Cmd = [ ];
+ Volumes = {
+ "/vol/shares" = { };
+ };
+ };
+ };
+
+ # nano = img {
+ # name = "docker.benkard.de/mulk/nano";
+ # tag = "latest";
+ # contents = [
+ # pkgs.nano
+ # ];
+ # };
+ #
+ # vim = img {
+ # name = "docker.benkard.de/mulk/vim";
+ # tag = "latest";
+ # contents = [
+ # pkgs.vim
+ # ];
+ # };
+
+}