{ config, lib, pkgs, ... }: with lib; let cfg = config.modules.services.misskey; inherit (lib.my) wrapFile; in { options.modules.services.misskey = { enable = mkEnableOption "Misskey, an interplanetary microblogging platform [container]"; domain = mkOption { type = types.str; }; realHost = mkOption { type = types.str; }; }; config = mkIf cfg.enable { # TODO: refactor # Misskey sets uid/gid to 991 in container, user is created here to # ensure that misskey files directory is accessible by the container user. users = { users.misskey = { description = "Misskey user"; group = "misskey"; extraGroups = [ "podman" ]; isSystemUser = true; uid = 991; }; groups.misskey = { gid = 991; }; }; virtualisation.podman.extraPackages = [ pkgs.zfs ]; # Packaging misskey is too much of a hassle, so we're using containers for now. virtualisation.oci-containers.containers.misskey = { volumes = [ "/var/lib/misskey-files:/misskey/files" # TODO: manage this with nix "${wrapFile ".config" ./config}:/misskey/.config:ro" ]; image = "misskey/misskey:13.10.3"; ports = [ "3000:3000" ]; extraOptions = [ "--network=host" ]; }; environment.persistence."/persist".directories = [ "/var/lib/containers" "/var/lib/misskey-files" "/var/lib/redis-misskey" ]; systemd.tmpfiles.rules = [ "d /var/lib/misskey-files 0755 misskey misskey -" ]; services.postgresql.enable = true; services.postgresql.ensureDatabases = [ "misskey" ]; services.postgresql.ensureUsers = [ { name = "misskey"; ensurePermissions."DATABASE misskey" = "ALL PRIVILEGES"; } ]; services.redis.servers.misskey = { enable = true; bind = "127.0.0.1"; port = 16434; }; services.nginx.virtualHosts.${cfg.realHost} = { forceSSL = true; useACMEHost = cfg.domain; locations."/" = { proxyPass = "http://127.0.0.1:3000"; proxyWebsockets = true; }; extraConfig = '' proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; ''; }; }; }