summary refs log tree commit diff
path: root/nixos/modules/services/web-apps/vikunja.nix
blob: 7575e96ca815d898ba07d40f5d7b55f15e1b799b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
{ pkgs, lib, config, ... }:

with lib;

let
  cfg = config.services.vikunja;
  format = pkgs.formats.yaml {};
  configFile = format.generate "config.yaml" cfg.settings;
  useMysql = cfg.database.type == "mysql";
  usePostgresql = cfg.database.type == "postgres";
in {
  options.services.vikunja = with lib; {
    enable = mkEnableOption "vikunja service";
    package-api = mkOption {
      default = pkgs.vikunja-api;
      type = types.package;
      defaultText = literalExpression "pkgs.vikunja-api";
      description = "vikunja-api derivation to use.";
    };
    package-frontend = mkOption {
      default = pkgs.vikunja-frontend;
      type = types.package;
      defaultText = literalExpression "pkgs.vikunja-frontend";
      description = "vikunja-frontend derivation to use.";
    };
    environmentFiles = mkOption {
      type = types.listOf types.path;
      default = [ ];
      description = ''
        List of environment files set in the vikunja systemd service.
        For example passwords should be set in one of these files.
      '';
    };
    setupNginx = mkOption {
      type = types.bool;
      default = config.services.nginx.enable;
      defaultText = literalExpression "config.services.nginx.enable";
      description = ''
        Whether to setup NGINX.
        Further nginx configuration can be done by changing
        <option>services.nginx.virtualHosts.&lt;frontendHostname&gt;</option>.
        This does not enable TLS or ACME by default. To enable this, set the
        <option>services.nginx.virtualHosts.&lt;frontendHostname&gt;.enableACME</option> to
        <literal>true</literal> and if appropriate do the same for
        <option>services.nginx.virtualHosts.&lt;frontendHostname&gt;.forceSSL</option>.
      '';
    };
    frontendScheme = mkOption {
      type = types.enum [ "http" "https" ];
      description = ''
        Whether the site is available via http or https.
        This does not configure https or ACME in nginx!
      '';
    };
    frontendHostname = mkOption {
      type = types.str;
      description = "The Hostname under which the frontend is running.";
    };

    settings = mkOption {
      type = format.type;
      default = {};
      description = ''
        Vikunja configuration. Refer to
        <link xlink:href="https://vikunja.io/docs/config-options/"/>
        for details on supported values.
        '';
    };
    database = {
      type = mkOption {
        type = types.enum [ "sqlite" "mysql" "postgres" ];
        example = "postgres";
        default = "sqlite";
        description = "Database engine to use.";
      };
      host = mkOption {
        type = types.str;
        default = "localhost";
        description = "Database host address. Can also be a socket.";
      };
      user = mkOption {
        type = types.str;
        default = "vikunja";
        description = "Database user.";
      };
      database = mkOption {
        type = types.str;
        default = "vikunja";
        description = "Database name.";
      };
      path = mkOption {
        type = types.str;
        default = "/var/lib/vikunja/vikunja.db";
        description = "Path to the sqlite3 database file.";
      };
    };
  };
  config = lib.mkIf cfg.enable {
    services.vikunja.settings = {
      database = {
        inherit (cfg.database) type host user database path;
      };
      service = {
        frontendurl = "${cfg.frontendScheme}://${cfg.frontendHostname}/";
      };
      files = {
        basepath = "/var/lib/vikunja/files";
      };
    };

    systemd.services.vikunja-api = {
      description = "vikunja-api";
      after = [ "network.target" ] ++ lib.optional usePostgresql "postgresql.service" ++ lib.optional useMysql "mysql.service";
      wantedBy = [ "multi-user.target" ];
      path = [ cfg.package-api ];
      restartTriggers = [ configFile ];

      serviceConfig = {
        Type = "simple";
        DynamicUser = true;
        StateDirectory = "vikunja";
        ExecStart = "${cfg.package-api}/bin/vikunja";
        Restart = "always";
        EnvironmentFile = cfg.environmentFiles;
      };
    };

    services.nginx.virtualHosts."${cfg.frontendHostname}" = mkIf cfg.setupNginx {
      locations = {
        "/" = {
          root = cfg.package-frontend;
          tryFiles = "try_files $uri $uri/ /";
        };
        "~* ^/(api|dav|\\.well-known)/" = {
          proxyPass = "http://localhost:3456";
          extraConfig = ''
            client_max_body_size 20M;
          '';
        };
      };
    };

    environment.etc."vikunja/config.yaml".source = configFile;
  };
}