From a26ed33b42f53faf893f88079d9a65df569455f4 Mon Sep 17 00:00:00 2001 From: Eli Ribble Date: Fri, 18 Jul 2025 22:45:02 +0000 Subject: [PATCH] Switch to caddy, remove onlyoffice, add collabora Most things work on this commit, except the integration between collabora and seafile. I think it might be related to the timezone change I made and a lack of access_token being passed in the URL. I'm going to test that with a reboot. But first, checkpoint! --- flake.nix | 9 - host/corp/configuration.nix | 84 +------- modules/system/authentik.nix | 3 + modules/system/base.nix | 2 +- modules/system/caddy.nix | 20 ++ modules/system/collabora.nix | 35 ++-- modules/system/default.nix | 4 +- modules/system/element-web.nix | 17 ++ modules/system/onlyoffice.nix | 350 --------------------------------- modules/system/seafile.nix | 96 +++------ modules/system/synapse.nix | 91 ++------- modules/system/vikunja.nix | 31 +++ 12 files changed, 142 insertions(+), 600 deletions(-) create mode 100644 modules/system/caddy.nix create mode 100644 modules/system/element-web.nix delete mode 100644 modules/system/onlyoffice.nix create mode 100644 modules/system/vikunja.nix diff --git a/flake.nix b/flake.nix index d3f3bec..647d35a 100644 --- a/flake.nix +++ b/flake.nix @@ -59,15 +59,6 @@ restartUnits = [ "matrix-synapse.service" ]; sopsFile = ./host/corp/secrets/matrix.yaml; }; - secrets.vikunja = { - format = "yaml"; - group = "vikunja"; - key = ""; - owner = "vikunja"; - path = "/etc/vikunja/config.yaml"; - restartUnits = [ "vikunja.service" ]; - sopsFile = ./host/corp/secrets/vikunja.yaml; - }; }; } ./users diff --git a/host/corp/configuration.nix b/host/corp/configuration.nix index 266bac7..17d8690 100644 --- a/host/corp/configuration.nix +++ b/host/corp/configuration.nix @@ -6,7 +6,6 @@ environment.systemPackages = with pkgs; [ age - element-web fish git htop @@ -20,94 +19,19 @@ ]; myModules = { authentik.enable = true; - onlyoffice.enable = true; + caddy.enable = true; + collabora.enable = true; + element-web.enable = true; seafile.enable = true; synapse.enable = true; timecardbot.enable = true; - }; - security.acme = { - acceptTerms = true; - defaults.email = "eli@gleipnir.technology"; - }; - services.nginx = { - # This adds the 'recommendedProxyConfig' without actually adding it since if I do add it, - # it'll include $nginx-recommended-proxy_set_headers-headers.conf at the http level, outside - # a server block, which breaks everything. - appendHttpConfig = '' - proxy_redirect off; - proxy_connect_timeout 60s; - proxy_send_timeout 60s; - proxy_read_timeout 60s; - proxy_http_version 1.1; - # don't let clients close the keep-alive connection to upstream. See the nginx blog for details: - # https://www.nginx.com/blog/avoiding-top-10-nginx-configuration-mistakes/#no-keepalives - proxy_set_header "Connection" ""; - ''; - enable = true; - recommendedGzipSettings = true; - recommendedProxySettings = false; - virtualHosts."auth.gleipnir.technology" = { - addSSL = true; - enableACME = true; - locations."/" = { - extraConfig = '' - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - include /etc/nginx/proxy.conf; - ''; - proxyPass = "http://127.0.0.1:10000"; - }; - root = "/var/www/auth"; - }; - virtualHosts."static.gleipnir.technology" = { - addSSL = true; - enableACME = true; - locations."/" = { - index = "index.html"; - }; - root = "/var/www/static"; - }; - virtualHosts."todo.gleipnir.technology" = { - addSSL = true; - enableACME = true; - locations."/" = { - extraConfig = '' - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - include /etc/nginx/proxy.conf; - ''; - proxyPass = "http://127.0.0.1:10010"; - }; - root = "/var/www/todo"; - }; + vikunja.enable = true; }; services.openssh.enable = true; - services.redis = { - servers."" = { - bind = "127.0.0.1"; - enable = true; - }; - }; - services.vikunja = { - enable = true; - frontendHostname = "todo.gleipnir.technology"; - frontendScheme = "https"; - }; - - users.groups.vikunja = {}; users.users.deploy = { extraGroups = [ "deploy" ]; isNormalUser = true; }; - users.users.vikunja = { - group = "vikunja"; - isNormalUser = false; - isSystemUser = true; - }; zramSwap.enable = true; # Copy the NixOS configuration file and link it from the resulting system diff --git a/modules/system/authentik.nix b/modules/system/authentik.nix index f397918..81e4136 100644 --- a/modules/system/authentik.nix +++ b/modules/system/authentik.nix @@ -4,6 +4,9 @@ with lib; options.myModules.authentik.enable = mkEnableOption "custom authentik configuration"; config = mkIf config.myModules.authentik.enable { + services.caddy.virtualHosts."auth.gleipnir.technology".extraConfig = '' + reverse_proxy http://127.0.0.1:10000 + ''; sops.secrets.authentik-env = with config.virtualisation.oci-containers; { format = "dotenv"; group = "authentik"; diff --git a/modules/system/base.nix b/modules/system/base.nix index 9990561..51e81d8 100644 --- a/modules/system/base.nix +++ b/modules/system/base.nix @@ -35,5 +35,5 @@ # and migrated your data accordingly. # # For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion . - system.stateVersion = "25.05"; + #system.stateVersion = "25.05"; } diff --git a/modules/system/caddy.nix b/modules/system/caddy.nix new file mode 100644 index 0000000..9bcd0f4 --- /dev/null +++ b/modules/system/caddy.nix @@ -0,0 +1,20 @@ +{ config, lib, pkgs, configPath, ... }: + +with lib; + +{ + options.myModules.caddy.enable = mkEnableOption "custom caddy configuration"; + + config = mkIf config.myModules.caddy.enable { + security.acme = { + acceptTerms = true; + defaults.email = "eli@gleipnir.technology"; + }; + services.caddy = { + enable = true; + logFormat = '' + level WARN + ''; + }; + }; +} diff --git a/modules/system/collabora.nix b/modules/system/collabora.nix index 8b7ebdb..67190b8 100644 --- a/modules/system/collabora.nix +++ b/modules/system/collabora.nix @@ -1,22 +1,25 @@ -{ config, lib, pkgs, ... }: +{ config, lib, pkgs, configPath, ... }: with lib; { - options.myModules.collabora.enable = mkEnableOption "custom collabora configuration"; - - config = mkIf config.myModules.collabora.enable { - virtualisation.oci-containers.containers.collabora = { - image = "collabora/code"; - ports = [ "127.0.0.1:10010:9980" ]; - environment = { - domain = "collabora.gleipnir.technology"; - extra_params = "--o:ssl.enable=false --o:ssl.termination=true"; - }; - extraOptions = [ - "--cap-add" - "MKNOD" - ]; - }; + options.myModules.collabora.enable = mkEnableOption "custom collabora configuration"; + config = mkIf config.myModules.collabora.enable { + services.caddy.virtualHosts."collabora.gleipnir.technology".extraConfig = '' + reverse_proxy http://127.0.0.1:10020 + ''; + virtualisation.oci-containers.containers.collabora = { + image = "collabora/code"; + ports = [ "127.0.0.1:10020:9980" ]; + environment = { + domain = "collabora.gleipnir.technology"; + extra_params = "--o:ssl.enable=false --o:ssl.termination=true"; + }; + extraOptions = [ + "--cap-add" + "MKNOD" + ]; + }; + }; } diff --git a/modules/system/default.nix b/modules/system/default.nix index 4951450..f3ac202 100644 --- a/modules/system/default.nix +++ b/modules/system/default.nix @@ -2,11 +2,12 @@ imports = [ ./authentik.nix ./base.nix + ./caddy.nix ./cloud-init.nix ./collabora.nix ./do-agent.nix + ./element-web.nix ./fish.nix - ./onlyoffice.nix ./openssh.nix ./podman.nix ./seafile.nix @@ -14,5 +15,6 @@ ./synapse.nix ./timecardbot.nix ./tmux.nix + ./vikunja.nix ]; } diff --git a/modules/system/element-web.nix b/modules/system/element-web.nix new file mode 100644 index 0000000..38e5078 --- /dev/null +++ b/modules/system/element-web.nix @@ -0,0 +1,17 @@ +{ pkgs, lib, config, ... }: +with lib; +let + clientConfig."m.homeserver".base_url = baseUrl; +in { + options.myModules.element-web.enable = mkEnableOption "custom element-web configuration"; + + config = mkIf config.myModules.element-web.enable { + environment.systemPackages = with pkgs; [ + element-web + ]; + services.caddy.virtualHosts."chat.gleipnir.technology".extraConfig = '' + file_server + root * ${pkgs.element-web} + ''; + }; +} diff --git a/modules/system/onlyoffice.nix b/modules/system/onlyoffice.nix deleted file mode 100644 index 2ef8d9a..0000000 --- a/modules/system/onlyoffice.nix +++ /dev/null @@ -1,350 +0,0 @@ -{ config, lib, pkgs, ... }: -with lib; -let - cfg = config.services.onlyoffice; -in -{ - disabledModules = [ - "services/web-apps/onlyoffice.nix" - ]; - # Override built-in onlyoffice definition to enable WOPI - options.services.onlyoffice = { - enable = lib.mkEnableOption "OnlyOffice DocumentServer"; - - enableExampleServer = lib.mkEnableOption "OnlyOffice example server"; - - hostname = lib.mkOption { - type = lib.types.str; - default = "localhost"; - description = "FQDN for the OnlyOffice instance."; - }; - - jwtSecretFile = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - description = '' - Path to a file that contains the secret to sign web requests using JSON Web Tokens. - If left at the default value null signing is disabled. - ''; - }; - - package = lib.mkPackageOption pkgs "onlyoffice-documentserver" { }; - - x2t = lib.mkPackageOption pkgs "x2t" { }; - - port = lib.mkOption { - type = lib.types.port; - default = 8000; - description = "Port the OnlyOffice document server should listen on."; - }; - - examplePort = lib.mkOption { - type = lib.types.port; - default = null; - description = "Port the OnlyOffice example server should listen on."; - }; - - postgresHost = lib.mkOption { - type = lib.types.str; - default = "/run/postgresql"; - description = "The Postgresql hostname or socket path OnlyOffice should connect to."; - }; - - postgresName = lib.mkOption { - type = lib.types.str; - default = "onlyoffice"; - description = "The name of database OnlyOffice should use."; - }; - - postgresPasswordFile = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - description = '' - Path to a file that contains the password OnlyOffice should use to connect to Postgresql. - Unused when using socket authentication. - ''; - }; - - postgresUser = lib.mkOption { - type = lib.types.str; - default = "onlyoffice"; - description = '' - The username OnlyOffice should use to connect to Postgresql. - Unused when using socket authentication. - ''; - }; - - rabbitmqUrl = lib.mkOption { - type = lib.types.str; - default = "amqp://guest:guest@localhost:5672"; - description = "The Rabbitmq in amqp URI style OnlyOffice should connect to."; - }; - - wopi = lib.mkEnableOption "Enable WOPI support"; - }; - options.myModules.onlyoffice.enable = mkEnableOption "custom onlyoffice configuration"; - - config = mkIf config.myModules.onlyoffice.enable { - services = { - nginx = { - enable = lib.mkDefault true; - # misses text/csv, font/ttf, application/x-font-ttf, application/rtf, application/wasm - recommendedGzipSettings = lib.mkDefault true; - recommendedProxySettings = lib.mkDefault true; - - upstreams = { - # /etc/nginx/includes/http-common.conf - onlyoffice-docservice = { - servers = { - "localhost:${toString cfg.port}" = { }; - }; - }; - onlyoffice-example = lib.mkIf cfg.enableExampleServer { - servers = { - "localhost:${toString cfg.examplePort}" = { }; - }; - }; - }; - - virtualHosts.${cfg.hostname} = { - locations = { - # resources that are generated and thus cannot be taken from the cfg.package yet: - "~ ^(\\/[\\d]+\\.[\\d]+\\.[\\d]+[\\.|-][\\w]+)?\\/(sdkjs/common/AllFonts.js)$".extraConfig = '' - proxy_pass http://onlyoffice-docservice/$2$3; - ''; - "~ ^(\\/[\\d]+\\.[\\d]+\\.[\\d]+[\\.|-][\\w]+)?\\/(fonts/.*)$".extraConfig = '' - proxy_pass http://onlyoffice-docservice/$2$3; - ''; - # /etc/nginx/includes/ds-docservice.conf - # disable caching for api.js - "~ ^(\\/[\\d]+\\.[\\d]+\\.[\\d]+[\\.|-][\\w]+)?\\/(web-apps\\/apps\\/api\\/documents\\/api\\.js)$".extraConfig = - '' - expires -1; - # gzip_static on; - alias ${cfg.package}/var/www/onlyoffice/documentserver/$2; - ''; - "~ ^(\\/[\\d]+\\.[\\d]+\\.[\\d]+[\\.|-][\\w]+)?\\/(document_editor_service_worker\\.js)$".extraConfig = - '' - expires 365d; - alias ${cfg.package}/var/www/onlyoffice/documentserver/sdkjs/common/serviceworker/$2; - ''; - # suppress logging the unsupported locale error in web-apps - "~ ^(\\/[\\d]+\\.[\\d]+\\.[\\d]+[\\.|-][\\w]+)?\\/(web-apps)(\\/.*\\.json)$".extraConfig = '' - expires 365d; - error_log /dev/null crit; - alias ${cfg.package}/var/www/onlyoffice/documentserver/$2$3; - ''; - # suppress logging the unsupported locale error in plugins - "~ ^(\\/[\\d]+\\.[\\d]+\\.[\\d]+[\\.|-][\\w]+)?\\/(sdkjs-plugins)(\\/.*\\.json)$".extraConfig = '' - expires 365d; - error_log /dev/null crit; - alias ${cfg.package}/var/www/onlyoffice/documentserver/$2$3; - ''; - "~ ^(\\/[\\d]+\\.[\\d]+\\.[\\d]+[\\.|-][\\w]+)?\\/(web-apps|sdkjs|sdkjs-plugins|fonts|dictionaries)(\\/.*)$".extraConfig = - '' - expires 365d; - alias ${cfg.package}/var/www/onlyoffice/documentserver/$2$3; - ''; - "~* ^(\\/cache\\/files.*)(\\/.*)".extraConfig = '' - alias /var/lib/onlyoffice/documentserver/App_Data$1; - add_header Content-Disposition "attachment; filename*=UTF-8''$arg_filename"; - - set $secure_link_secret verysecretstring; - secure_link $arg_md5,$arg_expires; - secure_link_md5 "$secure_link_expires$uri$secure_link_secret"; - - if ($secure_link = "") { - return 403; - } - - if ($secure_link = "0") { - return 410; - } - ''; - # Allow "/internal" interface only from 127.0.0.1 - # Don't comment out the section below for the security reason! - "~* ^(\\/[\\d]+\\.[\\d]+\\.[\\d]+[\\.|-][\\w]+)?\\/(internal)(\\/.*)$".extraConfig = '' - allow 127.0.0.1; - deny all; - proxy_pass http://onlyoffice-docservice/$2$3; - ''; - # Allow "/info" interface only from 127.0.0.1 by default - # Comment out lines allow 127.0.0.1; and deny all; - # of below section to turn on the info page - "~* ^(\\/[\\d]+\\.[\\d]+\\.[\\d]+[\\.|-][\\w]+)?\\/(info)(\\/.*)$".extraConfig = '' - allow 127.0.0.1; - deny all; - proxy_pass http://onlyoffice-docservice/$2$3; - ''; - "/".extraConfig = '' - proxy_pass http://onlyoffice-docservice; - ''; - "~ ^(\\/[\\d]+\\.[\\d]+\\.[\\d]+[\\.|-][\\w]+)?(\\/(doc|downloadas)\\/.*)".extraConfig = '' - proxy_pass http://onlyoffice-docservice$2$is_args$args; - proxy_http_version 1.1; - ''; - # end of /etc/nginx/includes/ds-docservice.conf - "/${cfg.package.version}/".extraConfig = '' - proxy_pass http://onlyoffice-docservice/; - ''; - # /etc/nginx/includes/ds-example.conf - "~ ^(\\/welcome\\/.*)$".extraConfig = lib.mkIf cfg.enableExampleServer '' - expires 365d; - alias ${cfg.package}/var/www/onlyoffice/documentserver-example$1; - index docker.html; - ''; - "/example/".extraConfig = lib.mkIf cfg.enableExampleServer '' - proxy_pass http://onlyoffice-example/; - proxy_set_header X-Forwarded-Path /example; - ''; - }; - extraConfig = '' - rewrite ^/$ /welcome/ redirect; - rewrite ^\/OfficeWeb(\/apps\/.*)$ /${cfg.package.version}/web-apps$1 redirect; - rewrite ^(\/web-apps\/apps\/(?!api\/).*)$ /${cfg.package.version}$1 redirect; - - # based on https://github.com/ONLYOFFICE/document-server-package/blob/master/common/documentserver/nginx/includes/http-common.conf.m4#L29-L34 - # without variable indirection and correct variable names - proxy_set_header Host $host; - proxy_set_header X-Forwarded-Host $host; - proxy_set_header X-Forwarded-Proto $scheme; - # required for CSP to take effect - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # required for websocket - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - ''; - }; - }; - - rabbitmq.enable = lib.mkDefault true; - - postgresql = { - enable = lib.mkDefault true; - ensureDatabases = [ "onlyoffice" ]; - ensureUsers = [ - { - name = "onlyoffice"; - ensureDBOwnership = true; - } - ]; - }; - }; - - systemd.services = { - onlyoffice-converter = { - description = "onlyoffice converter"; - after = [ - "network.target" - "onlyoffice-docservice.service" - "postgresql.service" - ]; - requires = [ - "network.target" - "onlyoffice-docservice.service" - "postgresql.service" - ]; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - ExecStart = "${cfg.package.fhs}/bin/onlyoffice-wrapper FileConverter/converter /run/onlyoffice/config"; - Group = "onlyoffice"; - Restart = "always"; - RuntimeDirectory = "onlyoffice"; - StateDirectory = "onlyoffice"; - Type = "simple"; - User = "onlyoffice"; - }; - }; - - onlyoffice-docservice = - let - onlyoffice-prestart = pkgs.writeShellScript "onlyoffice-prestart" '' - PATH=$PATH:${ - lib.makeBinPath ( - with pkgs; - [ - jq - moreutils - config.services.postgresql.package - ] - ) - } - umask 077 - mkdir -p /run/onlyoffice/config/ /var/lib/onlyoffice/documentserver/sdkjs/{slide/themes,common}/ /var/lib/onlyoffice/documentserver/{fonts,server/FileConverter/bin}/ - cp -r ${cfg.package}/etc/onlyoffice/documentserver/* /run/onlyoffice/config/ - chmod u+w /run/onlyoffice/config/default.json - - # Allow members of the onlyoffice group to serve files under /var/lib/onlyoffice/documentserver/App_Data - chmod g+x /var/lib/onlyoffice/documentserver - - cp /run/onlyoffice/config/default.json{,.orig} - - # for a mapping of environment variables from the docker container to json options see - # https://github.com/ONLYOFFICE/Docker-DocumentServer/blob/master/run-document-server.sh - jq ' - .services.CoAuthoring.server.port = ${toString cfg.port} | - .services.CoAuthoring.sql.dbHost = "${cfg.postgresHost}" | - .services.CoAuthoring.sql.dbName = "${cfg.postgresName}" | - ${lib.optionalString (cfg.postgresPasswordFile != null) '' - .services.CoAuthoring.sql.dbPass = "'"$(cat ${cfg.postgresPasswordFile})"'" | - ''} - .services.CoAuthoring.sql.dbUser = "${cfg.postgresUser}" | - ${lib.optionalString (cfg.jwtSecretFile != null) '' - .services.CoAuthoring.token.enable.browser = true | - .services.CoAuthoring.token.enable.request.inbox = true | - .services.CoAuthoring.token.enable.request.outbox = true | - .services.CoAuthoring.secret.inbox.string = "'"$(cat ${cfg.jwtSecretFile})"'" | - .services.CoAuthoring.secret.outbox.string = "'"$(cat ${cfg.jwtSecretFile})"'" | - .services.CoAuthoring.secret.session.string = "'"$(cat ${cfg.jwtSecretFile})"'" | - ''} - .rabbitmq.url = "${cfg.rabbitmqUrl}" | - .wopi.enable = "${toString cfg.wopi}" - ' /run/onlyoffice/config/default.json | sponge /run/onlyoffice/config/default.json - - chmod u+w /run/onlyoffice/config/production-linux.json - jq '.FileConverter.converter.x2tPath = "${cfg.x2t}/bin/x2t"' \ - /run/onlyoffice/config/production-linux.json | sponge /run/onlyoffice/config/production-linux.json - - if psql -d onlyoffice -c "SELECT 'task_result'::regclass;" >/dev/null; then - psql -f ${cfg.package}/var/www/onlyoffice/documentserver/server/schema/postgresql/removetbl.sql - psql -f ${cfg.package}/var/www/onlyoffice/documentserver/server/schema/postgresql/createdb.sql - else - psql -f ${cfg.package}/var/www/onlyoffice/documentserver/server/schema/postgresql/createdb.sql - fi - ''; - in - { - description = "onlyoffice documentserver"; - after = [ - "network.target" - "postgresql.service" - ]; - requires = [ "postgresql.service" ]; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - ExecStart = "${cfg.package.fhs}/bin/onlyoffice-wrapper DocService/docservice /run/onlyoffice/config"; - ExecStartPre = [ onlyoffice-prestart ]; - Group = "onlyoffice"; - Restart = "always"; - RuntimeDirectory = "onlyoffice"; - StateDirectory = "onlyoffice"; - Type = "simple"; - User = "onlyoffice"; - }; - }; - }; - - users.users = { - onlyoffice = { - description = "OnlyOffice Service"; - group = "onlyoffice"; - isSystemUser = true; - }; - - nginx.extraGroups = [ "onlyoffice" ]; - }; - - users.groups.onlyoffice = { }; - - }; -} diff --git a/modules/system/seafile.nix b/modules/system/seafile.nix index cfc313d..e215014 100644 --- a/modules/system/seafile.nix +++ b/modules/system/seafile.nix @@ -2,7 +2,6 @@ with lib; let domain = "files.gleipnir.technology"; - domain2 = "filez.gleipnir.technology"; stripTabs = text: let # Whether all lines start with a tab (or is empty) shouldStripTab = lines: builtins.all (line: (line == "") || (pkgs.lib.strings.hasPrefix " " line)) lines; @@ -16,57 +15,14 @@ let in { options.myModules.seafile.enable = mkEnableOption "custom seafile configuration"; config = mkIf config.myModules.seafile.enable { - services.nginx = { - virtualHosts."${domain}" = { - enableACME = true; - forceSSL = true; - locations = { - "/" = { - proxyPass = "http://unix:/run/seahub/gunicorn.sock"; - 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-Host $server_name; - proxy_set_header X-Forwarded-Proto https; - proxy_read_timeout 1200s; - client_max_body_size 0; - ''; - }; - "/seafhttp" = { - proxyPass = "http://unix:/run/seafile/server.sock"; - extraConfig = '' - rewrite ^/seafhttp(.*)$ $1 break; - client_max_body_size 0; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto https; - proxy_connect_timeout 36000s; - proxy_read_timeout 36000s; - proxy_send_timeout 36000s; - send_timeout 36000s; - ''; - }; - }; - }; - virtualHosts."${domain2}" = { - enableACME = true; - forceSSL = true; - locations = { - "/" = { - proxyPass = "http://[::1]:10030"; - 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-Host $server_name; - proxy_set_header X-Forwarded-Proto https; - proxy_read_timeout 1200s; - client_max_body_size 0; - ''; - }; - }; - }; - }; + services.caddy.virtualHosts."files.gleipnir.technology".extraConfig = '' + handle /seafhttp* { + reverse_proxy unix//run/seafile/server.sock + } + handle { + reverse_proxy unix//run/seahub/gunicorn.sock + } + ''; services.seafile = { adminEmail = "eli@gleipnir.technology"; ccnetSettings = { @@ -88,8 +44,25 @@ in { quota.default = "50"; # Amount of GB allotted to users }; seahubExtraConf = stripTabs('' + DEBUG = True + # Enable edit files through LibreOffice Online + ENABLE_OFFICE_WEB_APP_EDIT = True + + # types of files should be editable through LibreOffice Online + ENABLE_OFFICE_WEB_APP = True + OFFICE_SERVER_TYPE = 'CollaboraOffice' + OFFICE_WEB_APP_BASE_URL = 'https://collabora.gleipnir.technology/hosting/discovery' + OFFICE_WEB_APP_EDIT_FILE_EXTENSION = ('odp', 'ods', 'odt', 'xls', 'xlsb', 'xlsm', 'xlsx','ppsx', 'ppt', 'pptm', 'pptx', 'doc', 'docm', 'docx') + OFFICE_WEB_APP_FILE_EXTENSION = ('odp', 'ods', 'odt', 'xls', 'xlsb', 'xlsm', 'xlsx','ppsx', 'ppt', 'pptm', 'pptx', 'doc', 'docm', 'docx') + # Expiration of WOPI access token + # WOPI access token is a string used by Seafile to determine the file's + # identity and permissions when use LibreOffice Online view it online + # And for security reason, this token should expire after a set time period + WOPI_ACCESS_TOKEN_EXPIRATION = 30 * 60 # seconds + + + ENABLE_OAUTH = True - ENABLE_ONLYOFFICE = True # If create new user when he/she logs in Seafile for the first time, defalut `True`. OAUTH_CREATE_UNKNOWN_USER = True @@ -121,23 +94,6 @@ in { "email": (True, "email"), } SEAHUB_DATA_ROOT = "/var/lib/seafile/seahub/data" - - OFFICE_SERVER_TYPE = 'CollaboraOffice' - ENABLE_OFFICE_WEB_APP = True - OFFICE_WEB_APP_BASE_URL = 'https://docs.gleipnir.technology/hosting/discovery' - - # Expiration of WOPI access token - # WOPI access token is a string used by Seafile to determine the file's - # identity and permissions when use LibreOffice Online view it online - # And for security reason, this token should expire after a set time period - WOPI_ACCESS_TOKEN_EXPIRATION = 30 * 60 # seconds - - VERIFY_ONLYOFFICE_CERTIFICATE = False - ONLYOFFICE_APIJS_URL = 'https://docs.gleipnir.technology/web-apps/apps/api/documents/api.js' - ONLYOFFICE_FILE_EXTENSION = ('doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'odt', 'fodt', 'odp', 'fodp', 'ods', 'fods') - ONLYOFFICE_EDIT_FILE_EXTENSION = ('docx', 'pptx', 'xlsx') - ONLYOFFICE_FORCE_SAVE = True - ''); }; }; diff --git a/modules/system/synapse.nix b/modules/system/synapse.nix index 689cdb3..a8cac88 100644 --- a/modules/system/synapse.nix +++ b/modules/system/synapse.nix @@ -5,83 +5,28 @@ let baseUrl = "https://${fqdn}"; clientConfig."m.homeserver".base_url = baseUrl; serverConfig."m.server" = "${fqdn}:443"; - mkWellKnown = data: '' - default_type application/json; - add_header Access-Control-Allow-Origin *; - return 200 '${builtins.toJSON data}'; - ''; in { options.myModules.synapse.enable = mkEnableOption "custom synapse configuration"; config = mkIf config.myModules.synapse.enable { - services.nginx = { - virtualHosts."chat.gleipnir.technology" = { - enableACME = true; - forceSSL = true; - # Host element web client at the root - root = pkgs.element-web.override { - conf = { - default_server_config = clientConfig; - }; - }; - }; - virtualHosts."corp.gleipnir.technology" = { - enableACME = true; - forceSSL = true; - # This section is not needed if the server_name of matrix-synapse is equal to - # the domain (i.e. example.org from @foo:example.org) and the federation port - # is 8448. - # Further reference can be found in the docs about delegation under - # https://element-hq.github.io/synapse/latest/delegate.html - locations."= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig; - # This is usually needed for homeserver discovery (from e.g. other Matrix clients). - # Further reference can be found in the upstream docs at - # https://spec.matrix.org/latest/client-server-api/#getwell-knownmatrixclient - locations."= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig; - }; - virtualHosts."matrix.gleipnir.technology" = { - enableACME = true; - forceSSL = true; - # It's also possible to do a redirect here or something else, this vhost is not - # needed for Matrix. It's recommended though to *not put* element - # here, see also the section about Element. - locations."/".extraConfig = '' - return 404; - ''; - # Forward all Matrix API calls to the synapse Matrix homeserver. A trailing slash - # *must not* be used here. - locations."/_matrix" = { - extraConfig = '' - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - include /etc/nginx/proxy.conf; - ''; - proxyPass = "http://[::1]:8008"; - }; - - # Forward requests for e.g. SSO and password-resets. - locations."/_synapse/client" = { - extraConfig = '' - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - include /etc/nginx/proxy.conf; - ''; - proxyPass = "http://[::1]:8008"; - }; - }; - virtualHosts."matrix-bot.gleipnir.technology" = { - enableACME = true; - forceSSL = true; - locations."/" = { - extraConfig = '' - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - include /etc/nginx/proxy.conf; - ''; - proxyPass = "http://[::1]:10050"; - }; - }; - }; + services.caddy.virtualHosts."corp.gleipnir.technology".extraConfig = '' + # This is usually needed for homeserver discovery (from e.g. other Matrix clients). + # Further reference can be found in the upstream docs at + # https://spec.matrix.org/latest/client-server-api/#getwell-knownmatrixclient + # This section is not needed if the server_name of matrix-synapse is equal to + # the domain (i.e. example.org from @foo:example.org) and the federation port + # is 8448. + # Further reference can be found in the docs about delegation under + # https://element-hq.github.io/synapse/latest/delegate.html + #Headers & Well-known for Matrix & Element Call + header /.well-known/matrix/* Content-Type application/json + header /.well-known/matrix/* Access-Control-Allow-Origin * + respond /.well-known/matrix/server `{"m.server": "matrix.gleipnir.technology:443"}` + respond /.well-known/matrix/client `{"m.homeserver": {"base_url": "https://matrix.gleipnir.technology"}, "org.matrix.msc4143.rtc_foci": [{"type": "livekit", "livekit_service_url": "https://livekit.gleipnir.technology"}]}` + ''; + services.caddy.virtualHosts."matrix.gleipnir.technology".extraConfig = '' + reverse_proxy http://[::1]:8008 + ''; services.matrix-synapse = { enable = true; diff --git a/modules/system/vikunja.nix b/modules/system/vikunja.nix new file mode 100644 index 0000000..1f797d7 --- /dev/null +++ b/modules/system/vikunja.nix @@ -0,0 +1,31 @@ +{ pkgs, lib, config, ... }: +with lib; +{ + options.myModules.vikunja.enable = mkEnableOption "custom vikunja configuration"; + + config = mkIf config.myModules.vikunja.enable { + services.caddy.virtualHosts."todo.gleipnir.technology".extraConfig = '' + reverse_proxy http://127.0.0.1:10010 + ''; + services.vikunja = { + enable = true; + frontendHostname = "todo.gleipnir.technology"; + frontendScheme = "https"; + }; + sops.secrets.vikunja = { + format = "yaml"; + group = "vikunja"; + key = ""; + owner = "vikunja"; + path = "/etc/vikunja/config.yaml"; + restartUnits = [ "vikunja.service" ]; + sopsFile = ../../host/corp/secrets/vikunja.yaml; + }; + users.groups.vikunja = {}; + users.users.vikunja = { + group = "vikunja"; + isNormalUser = false; + isSystemUser = true; + }; + }; +}