8 cfg = config.services.gancio;
9 settingsFormat = pkgs.formats.json { };
27 options.services.gancio = {
28 enable = mkEnableOption "Gancio, a shared agenda for local communities";
30 package = mkPackageOption pkgs "gancio" { };
33 type = with types; listOf package;
35 example = literalExpression "[ pkgs.gancioPlugins.telegram-bridge ]";
37 Paths of gancio plugins to activate (linked under $WorkingDirectory/plugins/).
43 description = "The user (and PostgreSQL database name) used to run the gancio server";
47 settings = mkOption rec {
48 type = types.submodule {
49 freeformType = settingsFormat.type;
53 description = "The domain name under which the server is reachable.";
58 lib.optionalString config.services.nginx.virtualHosts."${cfg.settings.hostname}".enableACME "s"
59 }://${cfg.settings.hostname}";
60 defaultText = lib.literalExpression ''"https://''${cfg.settings.hostname}"'';
61 example = "https://demo.gancio.org/gancio";
62 description = "The full URL under which the server is reachable.";
68 default = "/run/gancio/socket";
70 The unix socket for the gancio server to listen on.
82 The database dialect to use
87 Location for the SQLite database.
90 type = types.nullOr types.str;
91 default = if cfg.settings.db.dialect == "sqlite" then "/var/lib/gancio/db.sqlite" else null;
93 if cfg.settings.db.dialect == "sqlite" then "/var/lib/gancio/db.sqlite" else null
98 Connection string for the PostgreSQL database
101 type = types.nullOr types.str;
102 default = if cfg.settings.db.dialect == "postgres" then "/run/postgresql" else null;
104 if cfg.settings.db.dialect == "postgres" then "/run/postgresql" else null
107 database = mkOption {
109 Name of the PostgreSQL database
112 type = types.nullOr types.str;
113 default = if cfg.settings.db.dialect == "postgres" then cfg.user else null;
115 if cfg.settings.db.dialect == "postgres" then cfg.user else null
119 log_level = mkOption {
120 description = "Gancio log level.";
129 # FIXME upstream proper journald logging
130 log_path = mkOption {
131 description = "Directory Gancio logs into";
134 default = "/var/log/gancio";
139 Configuration for Gancio, see <https://gancio.org/install/config> for supported values.
143 userLocale = mkOption {
144 type = with types; attrsOf (attrsOf (attrsOf str));
147 en.register.description = "My new registration page description";
150 Override default locales within gancio.
151 See [https://framagit.org/les/gancio/tree/master/locales](default languages and locales).
156 type = types.submodule (
157 lib.recursiveUpdate (import ../web-servers/nginx/vhost-options.nix { inherit config lib; }) {
158 # enable encryption by default,
159 # as sensitive login credentials should not be transmitted in clear text.
160 options.forceSSL.default = true;
161 options.enableACME.default = true;
169 description = "Extra configuration for the nginx virtual host of gancio.";
173 config = mkIf cfg.enable {
174 environment.systemPackages = [ cfg.package ];
176 users.users.gancio = lib.mkIf (cfg.user == "gancio") {
179 home = "/var/lib/gancio";
181 users.groups.gancio = lib.mkIf (cfg.user == "gancio") { };
183 systemd.tmpfiles.settings."10-gancio" =
188 group = config.users.users.${cfg.user}.group;
192 "/var/lib/gancio/user_locale".d = rules;
193 "/var/lib/gancio/plugins".d = rules;
196 systemd.services.gancio =
198 configFile = settingsFormat.generate "gancio-config.json" cfg.settings;
201 description = "Gancio server";
202 documentation = [ "https://gancio.org/" ];
204 wantedBy = [ "multi-user.target" ];
207 ] ++ optional (cfg.settings.db.dialect == "postgres") "postgresql.service";
210 NODE_ENV = "production";
214 # We need this so the gancio executable run by the user finds the right settings.
215 ln -sf ${configFile} config.json
218 ${concatStringsSep "\n" (
220 l: c: "ln -sf ${settingsFormat.generate "gancio-${l}-locale.json" c} user_locale/${l}.json"
225 ${concatMapStringsSep "\n" (p: "ln -sf ${p} plugins/") cfg.plugins}
229 ExecStart = "${getExe cfg.package} start ${configFile}";
230 # set umask so that nginx can write to the server socket
231 # FIXME: upstream socket permission configuration in Nuxt
233 RuntimeDirectory = "gancio";
234 StateDirectory = "gancio";
235 WorkingDirectory = "/var/lib/gancio";
236 LogsDirectory = "gancio";
239 RestrictRealtime = true;
240 RestrictNamespaces = true;
241 LockPersonality = true;
242 ProtectKernelModules = true;
243 ProtectKernelTunables = true;
244 ProtectKernelLogs = true;
245 ProtectControlGroups = true;
247 RestrictSUIDSGID = true;
248 SystemCallArchitectures = "native";
249 CapabilityBoundingSet = "";
250 ProtectProc = "invisible";
254 services.postgresql = mkIf (cfg.settings.db.dialect == "postgres") {
256 ensureDatabases = [ cfg.user ];
260 ensureDBOwnership = true;
267 virtualHosts."${cfg.settings.hostname}" = mkMerge [
272 index = "index.html";
273 tryFiles = "$uri $uri @proxy";
276 proxyWebsockets = true;
277 proxyPass = "http://unix:${cfg.settings.server.socket}";
278 recommendedProxySettings = true;
284 # for nginx to access gancio socket
285 users.users."${config.services.nginx.user}".extraGroups = [ config.users.users.${cfg.user}.group ];