{ lib, pkgs, unstablePkgs, ... }: let inherit (pkgs) dockerTools; akkomaLocalPort = "1111"; akkomaDir = "/srv/akkoma"; akkoma = unstablePkgs.akkoma.overrideAttrs { patches = [ ./docker-entrypoint.patch ]; postInstall = '' cp docker-entrypoint.sh $out/docker-entrypoint.sh ''; }; baseImageArm = dockerTools.pullImage { imageName = "alpine"; imageDigest = "sha256:1e42bbe2508154c9126d48c2b8a75420c3544343bf86fd041fb7527e017a4b4a"; sha256 = "06c0q5kk60i89y1d83a28wk282ymp806xjcsmlca4cwwqp590j0q"; finalImageName = "alpine"; finalImageTag = "3.20.3"; os = "linux"; arch = "arm64"; }; akkomaImage = dockerTools.buildLayeredImage { name = "akkoma"; tag = akkoma.version; fromImage = baseImageArm; contents = with unstablePkgs; [ exiftool imagemagick ffmpeg_7-headless postgresql elixir ] ++ [ akkoma ]; extraCommands = '' mkdir -p opt/akkoma ''; }; in { virtualisation.oci-containers.containers = { akkoma = { imageFile = akkomaImage; image = "akkoma:${akkoma.version}"; ports = [ "127.0.0.1:${akkomaLocalPort}:4000"]; volumes = [ "${akkomaDir}/data:/var/lib/akkoma" "${akkomaDir}/config:/opt/akkoma/config" ]; # TODO: remove redundant variables environment = { "RUNTIME_DIRECTORY" = "/opt/akkoma"; "AKKOMA_CONFIG_PATH" = "/opt/akkoma/config/config.exs"; "RELEASE_COOKIE" = "99ff9ca022574585269e737cdc4fa28b"; "RELEASE_NAME" = "akkoma"; "MIX_ENV" = "prod"; "DB_NAME" = "akkoma"; "DB_USER" = "akkoma"; "DB_PASS" = "akkoma"; "DB_HOST" = "db"; }; entrypoint = "${akkoma}/docker-entrypoint.sh"; workdir = "${akkoma}"; extraOptions = [ "--network-alias=akkoma" "--network=akkoma" ]; }; akkoma-db = { # TODO: pull through `dockerTools`. image = "postgres:14-alpine"; volumes = [ "${akkomaDir}/pgdata:/var/lib/postgresql/data" ]; environment = { "POSTGRES_DB" = "akkoma"; "POSTGRES_USER" = "akkoma"; "POSTGRES_PASSWORD" = "akkoma"; }; extraOptions = [ "--network-alias=db" "--network=akkoma" ]; }; }; # systemd configuration to combine containers. # mostly condensed from compose2nix output. # TODO: make this automatic!! systemd = let root = "docker-akkoma-root"; network = "docker-akkoma-network"; containerService = { serviceConfig = { Restart = lib.mkOverride 90 "always"; RestartMaxDelaySec = lib.mkOverride 90 "1m"; RestartSec = lib.mkOverride 90 "100ms"; RestartSteps = lib.mkOverride 90 9; }; after = [ "${network}.service" ]; requires = [ "${network}.service" ]; partOf = [ "${root}.target" ]; wantedBy = [ "${root}.target" ]; }; in { services = { "docker-akkoma-db" = containerService; "docker-akkoma" = containerService; "${network}" = { path = [ pkgs.docker ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; ExecStop = "docker network rm -f akkoma"; }; script = '' docker network inspect akkoma || docker network create akkoma --driver=bridge ''; partOf = [ "${root}.target" ]; wantedBy = [ "${root}.target" ]; }; }; targets = { "${root}" = { wantedBy = [ "multi-user.target" ]; }; }; }; }