From f819c8c5e3a8299fdaf2ab82bde68dedd4b275b5 Mon Sep 17 00:00:00 2001 From: Nikolaos Karaolidis Date: Mon, 16 Jun 2025 00:40:24 +0100 Subject: [PATCH] Add nextcloud Signed-off-by: Nikolaos Karaolidis --- hosts/common/configs/user/default.nix | 4 +- hosts/himalia/hardware/keybinds.nix | 4 +- hosts/himalia/hardware/scripts/farm-aura.sh | 2 + .../console/podman/authelia/default.nix | 12 +- .../storm/configs/console/podman/default.nix | 1 + .../configs/console/podman/gitea/default.nix | 14 +- .../console/podman/nextcloud/default.nix | 221 ++++++++++++++++++ .../console/podman/outline/default.nix | 15 +- .../console/podman/traefik/default.nix | 2 +- lib/fetchers/sshKnownHosts/default.nix | 2 +- packages/default.nix | 5 +- packages/docker/authelia/default.nix | 2 +- packages/docker/base/default.nix | 5 + packages/docker/gitea/default.nix | 2 +- .../docker/grafana-image-renderer/default.nix | 2 +- packages/docker/grafana/default.nix | 2 +- packages/docker/mariadb/default.nix | 2 +- .../nextcloud/declarative-secrets.patch | 34 +++ packages/docker/nextcloud/default.nix | 181 ++++++++++++++ packages/docker/nextcloud/entrypoint.sh | 72 ++++++ packages/docker/ntfy/default.nix | 2 +- packages/docker/oidcwarden/default.nix | 2 +- packages/docker/outline/default.nix | 2 +- packages/docker/postgresql/default.nix | 2 +- .../prometheus-fail2ban-exporter/default.nix | 2 +- .../entrypoint.sh | 2 +- .../prometheus-node-exporter/default.nix | 2 +- .../prometheus-podman-exporter/default.nix | 2 +- .../prometheus-podman-exporter/entrypoint.sh | 2 +- .../prometheus-smartctl-exporter/default.nix | 2 +- packages/docker/prometheus/default.nix | 2 +- packages/docker/redis/default.nix | 2 +- packages/docker/sish/default.nix | 2 +- packages/docker/traefik/default.nix | 2 +- packages/docker/whoami/default.nix | 2 +- packages/docker/yq/default.nix | 2 +- 36 files changed, 572 insertions(+), 44 deletions(-) create mode 100644 hosts/jupiter/users/storm/configs/console/podman/nextcloud/default.nix create mode 100644 packages/docker/nextcloud/declarative-secrets.patch create mode 100644 packages/docker/nextcloud/default.nix create mode 100644 packages/docker/nextcloud/entrypoint.sh diff --git a/hosts/common/configs/user/default.nix b/hosts/common/configs/user/default.nix index 1216b65..483dfed 100644 --- a/hosts/common/configs/user/default.nix +++ b/hosts/common/configs/user/default.nix @@ -4,9 +4,7 @@ }: { ... }: { - imports = [ - ./options.nix - ]; + imports = [ ./options.nix ]; home-manager.users.${user}.imports = [ ./console/zsh/options.nix diff --git a/hosts/himalia/hardware/keybinds.nix b/hosts/himalia/hardware/keybinds.nix index 6bbce15..17ac04d 100644 --- a/hosts/himalia/hardware/keybinds.nix +++ b/hosts/himalia/hardware/keybinds.nix @@ -37,9 +37,7 @@ } ); in - [ - ", XF86Launch3, exec, uwsm app -- $term ${farmAura}" - ]; + [ ", XF86Launch3, exec, uwsm app -- $term ${farmAura}" ]; }; } ]; diff --git a/hosts/himalia/hardware/scripts/farm-aura.sh b/hosts/himalia/hardware/scripts/farm-aura.sh index eaaa431..c8c3c79 100755 --- a/hosts/himalia/hardware/scripts/farm-aura.sh +++ b/hosts/himalia/hardware/scripts/farm-aura.sh @@ -1,3 +1,5 @@ +# shellcheck shell=bash + SESSION_NAME="aura-farm-$$" tmux new-session -d -s "$SESSION_NAME" "genact -s 25" diff --git a/hosts/jupiter/users/storm/configs/console/podman/authelia/default.nix b/hosts/jupiter/users/storm/configs/console/podman/authelia/default.nix index 4b4e274..e6c5394 100644 --- a/hosts/jupiter/users/storm/configs/console/podman/authelia/default.nix +++ b/hosts/jupiter/users/storm/configs/console/podman/authelia/default.nix @@ -68,6 +68,8 @@ in identity_validation.reset_password.jwt_secret = hmConfig.sops.placeholder."authelia/resetPasswordJwt"; + definitions.user_attributes.is_admin.expression = "\"admins\" in groups"; + identity_providers.oidc = { hmac_secret = hmConfig.sops.placeholder."authelia/oidcHmac"; @@ -94,6 +96,11 @@ in ]; }; }; + + claims_policies.is_admin.custom_claims.is_admin = { }; + + # FIXME: Add scope description + scopes.is_admin.claims = [ "is_admin" ]; }; storage = { @@ -128,9 +135,10 @@ in email = "nick@karaolidis.com"; groups = [ "admins" - "git" - "docs" + "gitea" + "outline" "vaultwarden" + "nextcloud" ]; }; } diff --git a/hosts/jupiter/users/storm/configs/console/podman/default.nix b/hosts/jupiter/users/storm/configs/console/podman/default.nix index a80fe7c..ca51872 100644 --- a/hosts/jupiter/users/storm/configs/console/podman/default.nix +++ b/hosts/jupiter/users/storm/configs/console/podman/default.nix @@ -11,6 +11,7 @@ in (import ./authelia { inherit user home; }) (import ./gitea { inherit user home; }) (import ./grafana { inherit user home; }) + (import ./nextcloud { inherit user home; }) (import ./ntfy { inherit user home; }) (import ./outline { inherit user home; }) (import ./prometheus { inherit user home; }) diff --git a/hosts/jupiter/users/storm/configs/console/podman/gitea/default.nix b/hosts/jupiter/users/storm/configs/console/podman/gitea/default.nix index 64e2ca1..67da6a1 100644 --- a/hosts/jupiter/users/storm/configs/console/podman/gitea/default.nix +++ b/hosts/jupiter/users/storm/configs/console/podman/gitea/default.nix @@ -13,7 +13,7 @@ let selfPkgs = inputs.self.packages.${system}; hmConfig = config.home-manager.users.${user}; - inherit (hmConfig.virtualisation.quadlet) volumes networks; + inherit (hmConfig.virtualisation.quadlet) containers volumes networks; autheliaClientId = "I2ZYDFGWP1bzfiauXe94IaiReZF6SqoEskSp6phoL2L8l16Cq7YX3Vr4pkQOSYfNDOwuFjTRIpqQ8eAqK0M93NeEgpr8YoPhKHyR"; podman = lib.meta.getExe pkgs.podman; podmanAsUser = "${config.security.wrapperDir}/git-sudo -u ${user} ${podman}"; @@ -166,12 +166,12 @@ in authelia-gitea.content = builtins.readFile ( (pkgs.formats.yaml { }).generate "gitea.yaml" { identity_providers.oidc = { - authorization_policies.git = { + authorization_policies.gitea = { default_policy = "deny"; rules = [ { policy = "one_factor"; - subject = "group:git"; + subject = "group:gitea"; } ]; }; @@ -182,7 +182,7 @@ in client_name = "Gitea"; client_secret = hmConfig.sops.placeholder."gitea/authelia/digest"; redirect_uris = [ "https://git.karaolidis.com/user/oauth2/authelia/callback" ]; - authorization_policy = "git"; + authorization_policy = "gitea"; } ]; }; @@ -196,6 +196,7 @@ in volumes = { gitea-postgresql = { }; + # TODO: Move LFS to mass storage gitea = { }; }; @@ -229,7 +230,10 @@ in ]; }; - unitConfig.After = [ "sops-nix.service" ]; + unitConfig.After = [ + "${containers.gitea-postgresql._serviceName}.service" + "sops-nix.service" + ]; }; gitea-postgresql = { diff --git a/hosts/jupiter/users/storm/configs/console/podman/nextcloud/default.nix b/hosts/jupiter/users/storm/configs/console/podman/nextcloud/default.nix new file mode 100644 index 0000000..7d916a0 --- /dev/null +++ b/hosts/jupiter/users/storm/configs/console/podman/nextcloud/default.nix @@ -0,0 +1,221 @@ +{ + user ? throw "user argument is required", + home ? throw "home argument is required", +}: +{ + config, + inputs, + pkgs, + system, + ... +}: +let + selfPkgs = inputs.self.packages.${system}; + hmConfig = config.home-manager.users.${user}; + inherit (hmConfig.virtualisation.quadlet) containers volumes networks; + autheliaClientId = "7DXUBtkdLUUkmyV8oSXidP0XiU6W7usLvYRJ9TrbHy7IflFwWPmHVmU26oLahrj8bVURiexGfAr3bIey6vnlvirnYQ8HMo55NnqH"; +in +{ + home-manager.users.${user} = { + sops = { + secrets = { + "nextcloud/salt".sopsFile = ../../../../../../secrets/secrets.yaml; + "nextcloud/secret".sopsFile = ../../../../../../secrets/secrets.yaml; + "nextcloud/smtp".sopsFile = ../../../../../../secrets/secrets.yaml; + "nextcloud/postgresql".sopsFile = ../../../../../../secrets/secrets.yaml; + "nextcloud/authelia/password".sopsFile = ../../../../../../secrets/secrets.yaml; + "nextcloud/authelia/digest".sopsFile = ../../../../../../secrets/secrets.yaml; + }; + + templates = { + nextcloud-postgresql-env.content = '' + POSTGRES_PASSWORD=${hmConfig.sops.placeholder."nextcloud/postgresql"} + ''; + + nextcloud-env.content = '' + POSTGRES_PASSWORD=${hmConfig.sops.placeholder."nextcloud/postgresql"} + ''; + + nextcloud.content = '' + '${config.networking.hostName}', + + 'passwordsalt' => '${hmConfig.sops.placeholder."nextcloud/salt"}', + 'secret' => '${hmConfig.sops.placeholder."nextcloud/secret"}', + + 'setup_create_db_user' => false, + 'upgrade.disable-web' => true, + 'integrity.check.disabled' => true, + + 'trusted_domains' => array ( + 0 => 'cloud.karaolidis.com', + ), + 'trusted_proxies' => [ + '10.89.0.0/13', + '10.96.0.0/11', + '10.128.0.0/9' + ], + 'overwrite.cli.url' => 'https://cloud.karaolidis.com/', + 'htaccess.RewriteBase' => '/', + 'overwritehost' => 'cloud.karaolidis.com', + 'overwriteprotocol' => 'https', + 'overwritewebroot' => '/', + + 'memcache.local' => '\\OC\\Memcache\\APCu', + 'maintenance_window_start' => 1, + + 'skeletondirectory' => ''', + 'templatedirectory' => ''', + + 'mail_from_address' => 'jupiter', + 'mail_smtpmode' => 'smtp', + 'mail_sendmailmode' => 'smtp', + 'mail_domain' => 'karaolidis.com', + 'mail_smtphost' => 'smtp.protonmail.ch', + 'mail_smtpport' => '587', + 'mail_smtpauth' => true, + 'mail_smtpname' => 'jupiter@karaolidis.com', + 'mail_smtppassword' => '${hmConfig.sops.placeholder."nextcloud/smtp"}', + + 'allow_user_to_change_display_name' => false, + 'lost_password_link' => 'disabled', + + 'oidc_login_provider_url' => 'https://id.karaolidis.com', + 'oidc_login_client_id' => '${autheliaClientId}', + 'oidc_login_client_secret' => '${hmConfig.sops.placeholder."nextcloud/authelia/password"}', + 'oidc_login_auto_redirect' => true, + 'oidc_login_logout_url' => 'https://id.karaolidis.com/logout', + 'oidc_login_end_session_redirect' => false, + 'oidc_login_button_text' => 'Log in with Authelia', + 'oidc_login_hide_password_form' => true, + 'oidc_login_use_id_token' => false, + 'oidc_login_attributes' => array ( + 'id' => 'preferred_username', + 'name' => 'name', + 'mail' => 'email', + 'groups' => 'groups', + 'is_admin' => 'is_admin', + ), + 'oidc_login_use_external_storage' => false, + 'oidc_login_scope' => 'openid profile email groups is_admin', + 'oidc_login_proxy_ldap' => false, + 'oidc_login_disable_registration' => false, + 'oidc_login_redir_fallback' => false, + 'oidc_login_tls_verify' => true, + 'oidc_create_groups' => false, + 'oidc_login_webdav_enabled' => true, + 'oidc_login_password_authentication' => true, + 'oidc_login_min_time_between_jwks_requests' => 10, + 'oidc_login_update_avatar' => true, + 'oidc_login_code_challenge_method' => 'S256', + ); + ''; + + authelia-nextcloud.content = builtins.readFile ( + (pkgs.formats.yaml { }).generate "nextcloud.yaml" { + identity_providers.oidc = { + authorization_policies.nextcloud = { + default_policy = "deny"; + rules = [ + { + policy = "one_factor"; + subject = "group:nextcloud"; + } + ]; + }; + + clients = [ + { + client_id = autheliaClientId; + client_name = "Nextcloud"; + client_secret = hmConfig.sops.placeholder."nextcloud/authelia/digest"; + redirect_uris = [ "https://cloud.karaolidis.com/apps/oidc_login/oidc" ]; + authorization_policy = "nextcloud"; + require_pkce = true; + pkce_challenge_method = "S256"; + claims_policy = "is_admin"; + scopes = [ + "openid" + "profile" + "email" + "groups" + "is_admin" + ]; + } + ]; + }; + } + ); + }; + }; + + virtualisation.quadlet = { + networks.nextcloud.networkConfig.internal = true; + + volumes = { + nextcloud-postgresql = { }; + nextcloud-config = { }; + nextcloud-apps = { }; + # TODO: Move to mass storage + nextcloud-data = { }; + }; + + containers = { + nextcloud = { + containerConfig = { + image = "docker-archive:${selfPkgs.docker-nextcloud}"; + networks = [ + networks.nextcloud.ref + networks.traefik.ref + ]; + volumes = [ + "${volumes.nextcloud-data.ref}:/var/lib/nextcloud" + "${volumes.nextcloud-config.ref}:/var/www/nextcloud/config" + "${volumes.nextcloud-apps.ref}:/var/www/nextcloud/apps" + "${hmConfig.sops.templates.nextcloud.path}:/var/www/nextcloud/config/override.config.php:ro" + ]; + environments = { + POSTGRES_HOST = "nextcloud-postgresql"; + POSTGRES_DB = "nextcloud"; + POSTGRES_USER = "nextcloud"; + EXTRA_INIT = '' + occ config:app:set core shareapi_allow_custom_tokens --value true --type boolean --no-interaction + occ theming:config url https://cloud.karaolidis.com + ''; + }; + environmentFiles = [ hmConfig.sops.templates.nextcloud-env.path ]; + labels = [ + "traefik.enable=true" + "traefik.http.routers.nextcloud.rule=Host(`cloud.karaolidis.com`)" + ]; + }; + + unitConfig.After = [ + "${containers.nextcloud-postgresql._serviceName}.service" + "sops-nix.service" + ]; + }; + + nextcloud-postgresql = { + containerConfig = { + image = "docker-archive:${selfPkgs.docker-postgresql}"; + networks = [ networks.nextcloud.ref ]; + volumes = [ "${volumes.nextcloud-postgresql.ref}:/var/lib/postgresql/data" ]; + environments = { + POSTGRES_DB = "nextcloud"; + POSTGRES_USER = "nextcloud"; + }; + environmentFiles = [ hmConfig.sops.templates.nextcloud-postgresql-env.path ]; + }; + + unitConfig.After = [ "sops-nix.service" ]; + }; + + authelia-init.containerConfig.volumes = [ + "${hmConfig.sops.templates.authelia-nextcloud.path}:/etc/authelia/conf.d/nextcloud.yaml:ro" + ]; + }; + }; + }; +} diff --git a/hosts/jupiter/users/storm/configs/console/podman/outline/default.nix b/hosts/jupiter/users/storm/configs/console/podman/outline/default.nix index 5f5833f..822617d 100644 --- a/hosts/jupiter/users/storm/configs/console/podman/outline/default.nix +++ b/hosts/jupiter/users/storm/configs/console/podman/outline/default.nix @@ -12,7 +12,7 @@ let selfPkgs = inputs.self.packages.${system}; hmConfig = config.home-manager.users.${user}; - inherit (hmConfig.virtualisation.quadlet) volumes networks; + inherit (hmConfig.virtualisation.quadlet) containers volumes networks; autheliaClientId = "3U5O3TkoIFb3bz3MMqscGEDx2wkT2G48iLLJalqSKA40zCweSBfgORGNMjDEidz4qiQ93qIoW2UlgTyLfzAwbklTvwHJPcarmXaq"; in { @@ -45,12 +45,12 @@ in authelia-outline.content = builtins.readFile ( (pkgs.formats.yaml { }).generate "outline.yaml" { identity_providers.oidc = { - authorization_policies.docs = { + authorization_policies.outline = { default_policy = "deny"; rules = [ { policy = "one_factor"; - subject = "group:docs"; + subject = "group:outline"; } ]; }; @@ -61,7 +61,7 @@ in client_name = "Outline"; client_secret = hmConfig.sops.placeholder."outline/authelia/digest"; redirect_uris = [ "https://docs.karaolidis.com/auth/oidc.callback" ]; - authorization_policy = "docs"; + authorization_policy = "outline"; scopes = [ "openid" "profile" @@ -83,6 +83,7 @@ in volumes = { outline-redis = { }; outline-postgresql = { }; + # TODO: Move to mass storage outline = { }; }; @@ -125,7 +126,11 @@ in ]; }; - unitConfig.After = [ "sops-nix.service" ]; + unitConfig.After = [ + "${containers.outline-postgresql._serviceName}.service" + "${containers.outline-redis._serviceName}.service" + "sops-nix.service" + ]; }; outline-postgresql = { diff --git a/hosts/jupiter/users/storm/configs/console/podman/traefik/default.nix b/hosts/jupiter/users/storm/configs/console/podman/traefik/default.nix index 24a8b7a..db4f970 100644 --- a/hosts/jupiter/users/storm/configs/console/podman/traefik/default.nix +++ b/hosts/jupiter/users/storm/configs/console/podman/traefik/default.nix @@ -102,7 +102,7 @@ in "traefik.http.routers.traefik-api.middlewares=authelia@docker" "traefik.http.middlewares.compress.compress=true" - # TODO: Middlewares: Headers + # TODO: Middlewares: Headers (Security + Performance) ]; environmentFiles = [ hmConfig.sops.templates.traefik-env.path ]; }; diff --git a/lib/fetchers/sshKnownHosts/default.nix b/lib/fetchers/sshKnownHosts/default.nix index d111d4d..440c1c0 100644 --- a/lib/fetchers/sshKnownHosts/default.nix +++ b/lib/fetchers/sshKnownHosts/default.nix @@ -15,7 +15,7 @@ pkgs.lib.fetchers.withNormalizedHash { } ( let keyTypeArgs = pkgs.lib.concatStringsSep "," keyTypes; in - pkgs.runCommand name + pkgs.runCommandLocal name { inherit outputHash outputHashAlgo; outputHashMode = "flat"; diff --git a/packages/default.nix b/packages/default.nix index a6304a7..68b6abd 100644 --- a/packages/default.nix +++ b/packages/default.nix @@ -15,10 +15,9 @@ docker-grafana = import ./docker/grafana { inherit pkgs; }; docker-grafana-image-renderer = import ./docker/grafana-image-renderer { inherit pkgs; }; docker-mariadb = import ./docker/mariadb { inherit pkgs; }; + docker-nextcloud = import ./docker/nextcloud { inherit pkgs; }; docker-ntfy = import ./docker/ntfy { inherit pkgs; }; - docker-oidcwarden = import ./docker/oidcwarden { - inherit pkgs inputs system; - }; + docker-oidcwarden = import ./docker/oidcwarden { inherit pkgs inputs system; }; docker-outline = import ./docker/outline { inherit pkgs; }; docker-postgresql = import ./docker/postgresql { inherit pkgs; }; docker-prometheus = import ./docker/prometheus { inherit pkgs; }; diff --git a/packages/docker/authelia/default.nix b/packages/docker/authelia/default.nix index 180c214..0bc98ed 100644 --- a/packages/docker/authelia/default.nix +++ b/packages/docker/authelia/default.nix @@ -10,7 +10,7 @@ pkgs.dockerTools.buildImage { }; config = { - Entrypoint = [ "/bin/authelia" ]; + Entrypoint = [ "authelia" ]; ExposedPorts = { "9091/tcp" = { }; }; diff --git a/packages/docker/base/default.nix b/packages/docker/base/default.nix index d54e522..aa5e964 100644 --- a/packages/docker/base/default.nix +++ b/packages/docker/base/default.nix @@ -11,9 +11,14 @@ pkgs.dockerTools.buildImage { bashInteractive ncurses coreutils + util-linux gnugrep + gawk findutils + which + vim iputils + iproute2 curl ]; pathsToLink = [ diff --git a/packages/docker/gitea/default.nix b/packages/docker/gitea/default.nix index 478e160..7fcbefe 100644 --- a/packages/docker/gitea/default.nix +++ b/packages/docker/gitea/default.nix @@ -17,7 +17,7 @@ pkgs.dockerTools.buildImage { ''; config = { - Entrypoint = [ "/bin/gitea" ]; + Entrypoint = [ "gitea" ]; Cmd = [ "web" "-c" diff --git a/packages/docker/grafana-image-renderer/default.nix b/packages/docker/grafana-image-renderer/default.nix index 286d81e..43ea5b0 100644 --- a/packages/docker/grafana-image-renderer/default.nix +++ b/packages/docker/grafana-image-renderer/default.nix @@ -10,7 +10,7 @@ pkgs.dockerTools.buildImage { }; config = { - Entrypoint = [ "/bin/grafana-image-renderer" ]; + Entrypoint = [ "grafana-image-renderer" ]; Cmd = [ "server" ]; ExposedPorts = { "8081/tcp" = { }; diff --git a/packages/docker/grafana/default.nix b/packages/docker/grafana/default.nix index 8d59df5..46582db 100644 --- a/packages/docker/grafana/default.nix +++ b/packages/docker/grafana/default.nix @@ -17,7 +17,7 @@ pkgs.dockerTools.buildImage { ''; config = { - Entrypoint = [ "/bin/grafana" ]; + Entrypoint = [ "grafana" ]; Cmd = [ "server" "--homepath" diff --git a/packages/docker/mariadb/default.nix b/packages/docker/mariadb/default.nix index 8210fc5..ce66c0e 100644 --- a/packages/docker/mariadb/default.nix +++ b/packages/docker/mariadb/default.nix @@ -30,7 +30,7 @@ pkgs.dockerTools.buildImage { ''; config = { - Entrypoint = [ "/bin/entrypoint" ]; + Entrypoint = [ "entrypoint" ]; WorkingDir = "/var/lib/mysql"; ExposedPorts = { "3306/tcp" = { }; diff --git a/packages/docker/nextcloud/declarative-secrets.patch b/packages/docker/nextcloud/declarative-secrets.patch new file mode 100644 index 0000000..89504d6 --- /dev/null +++ b/packages/docker/nextcloud/declarative-secrets.patch @@ -0,0 +1,34 @@ +diff --git a/lib/private/Setup.php b/lib/private/Setup.php +index 271e10d6..d21e2dd6 100644 +--- a/lib/private/Setup.php ++++ b/lib/private/Setup.php +@@ -272,21 +272,22 @@ class Setup { + $dbType = 'sqlite3'; + } + +- //generate a random salt that is used to salt the local passwords +- $salt = $this->random->generate(30); +- // generate a secret +- $secret = $this->random->generate(48); +- + //write the config file + $newConfigValues = [ +- 'passwordsalt' => $salt, +- 'secret' => $secret, + 'trusted_domains' => $trustedDomains, + 'datadirectory' => $dataDir, + 'dbtype' => $dbType, + 'version' => implode('.', \OCP\Util::getVersion()), + ]; + ++ if ($this->config->getValue('passwordsalt', null) === null) { ++ $newConfigValues['passwordsalt'] = $this->random->generate(30); ++ } ++ ++ if ($this->config->getValue('secret', null) === null) { ++ $newConfigValues['secret'] = $this->random->generate(48); ++ } ++ + if ($this->config->getValue('overwrite.cli.url', null) === null) { + $newConfigValues['overwrite.cli.url'] = $request->getServerProtocol() . '://' . $request->getInsecureServerHost() . \OC::$WEBROOT; + } diff --git a/packages/docker/nextcloud/default.nix b/packages/docker/nextcloud/default.nix new file mode 100644 index 0000000..9179fa7 --- /dev/null +++ b/packages/docker/nextcloud/default.nix @@ -0,0 +1,181 @@ +{ pkgs, ... }: +let + apacheHttpd = pkgs.apacheHttpd.overrideAttrs (oldAttrs: { + env.NIX_CFLAGS_COMPILE = "-DBIG_SECURITY_HOLE"; + }); + + # https://docs.nextcloud.com/server/latest/admin_manual/installation/php_configuration.html + php = + (pkgs.php83.override { + inherit apacheHttpd; + apxs2Support = true; + }).buildEnv + { + extensions = + { all, ... }: + with all; + [ + ctype + curl + dom + fileinfo + filter + gd + mbstring + openssl + posix + session + simplexml + xmlreader + xmlwriter + zip + zlib + pdo_pgsql + intl + sodium + apcu + imagick + exif + pcntl + opcache + gmp + sysvsem + ]; + + extraConfig = '' + expose_php = Off + memory_limit = 2048M + apc.shm_size = 128M + opcache.jit = 1255 + opcache.jit_buffer_size = 8M + opcache.interned_strings_buffer = 16 + upload_max_filesize = 100G + post_max_size = 100G + max_input_time = 3600 + max_execution_time = 3600 + output_buffering = 0 + ''; + }; + + apacheHttpdConfig = pkgs.writeTextDir "/etc/httpd/httpd.conf" '' + ServerRoot ${apacheHttpd} + + ServerName localhost + Listen 80 + + LoadModule mpm_event_module modules/mod_mpm_event.so + LoadModule authz_core_module modules/mod_authz_core.so + LoadModule unixd_module modules/mod_unixd.so + LoadModule headers_module modules/mod_headers.so + LoadModule env_module modules/mod_env.so + LoadModule dir_module modules/mod_dir.so + LoadModule mime_module modules/mod_mime.so + LoadModule rewrite_module modules/mod_rewrite.so + LoadModule php_module ${php}/modules/libphp.so + + User root + Group root + + PidFile /run/httpd/httpd.pid + + LogLevel warn + ErrorLog /dev/stderr + + TypesConfig conf/mime.types + AddType application/x-httpd-php .php .phtml + + DocumentRoot "/var/www/nextcloud" + DirectoryIndex index.php index.html + + LimitRequestBody 0 + TimeOut 3600 + + + Require all granted + AllowOverride All + Options FollowSymLinks MultiViews + + + + Require all denied + + ''; + + occ = pkgs.writeShellApplication { + name = "occ"; + text = '' + exec ${pkgs.lib.meta.getExe php} /var/www/nextcloud/occ "$@" + ''; + }; + + nextcloud31 = + let + nextcloud31 = pkgs.nextcloud31.overrideAttrs (oldAttrs: { + patches = oldAttrs.patches or [ ] ++ [ ./declarative-secrets.patch ]; + }); + in + pkgs.runCommandLocal "nextcloud" { } '' + mkdir -p $out/var/www + cp -r ${nextcloud31} $out/var/www/nextcloud + ''; + + crontab = pkgs.writeTextDir "/var/cron/tabs/root" '' + */5 * * * * ${pkgs.lib.meta.getExe php} -f /var/www/nextcloud/cron.php + ''; + + entrypoint = pkgs.writeTextFile { + name = "entrypoint"; + executable = true; + destination = "/bin/entrypoint"; + text = builtins.readFile ./entrypoint.sh; + }; +in +pkgs.dockerTools.buildImage { + name = "nextcloud"; + fromImage = import ../base { inherit pkgs; }; + + diskSize = 2048; + + copyToRoot = pkgs.buildEnv { + name = "root"; + paths = [ + apacheHttpd + apacheHttpdConfig + php + nextcloud31 + occ + entrypoint + crontab + pkgs.cron + pkgs.ffmpeg + ]; + pathsToLink = [ + "/bin" + "/etc" + "/var" + ]; + }; + + runAsRoot = '' + ${pkgs.dockerTools.shadowSetup} + mkdir -p /run/httpd + ''; + + config = { + Entrypoint = [ "entrypoint" ]; + Cmd = [ + "-DFOREGROUND" + "-f" + "/etc/httpd/httpd.conf" + ]; + Volumes = { + "/var/www/nextcloud/config" = { }; + "/var/www/nextcloud/apps" = { }; + "/var/lib/nextcloud" = { }; + }; + WorkingDir = "/var/www/nextcloud"; + ExposedPorts = { + "80/tcp" = { }; + }; + }; +} diff --git a/packages/docker/nextcloud/entrypoint.sh b/packages/docker/nextcloud/entrypoint.sh new file mode 100644 index 0000000..ce10c4a --- /dev/null +++ b/packages/docker/nextcloud/entrypoint.sh @@ -0,0 +1,72 @@ +#!/bin/sh + +set -o errexit +set -o nounset + +if [ ! -f "/var/www/nextcloud/config/config.php" ]; then + POSTGRES_HOST="${POSTGRES_HOST:-nextcloud-postgresql}" + POSTGRES_PORT="${POSTGRES_PORT:-5432}" + POSTGRES_USER="${POSTGRES_USER:-nextcloud}" + POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-nextcloud}" + POSTGRES_DB="${POSTGRES_DB:-$POSTGRES_USER}" + + ADMIN_USER="admin" + ADMIN_PASS="$(head -c 128 /dev/urandom | tr -dc 'A-Za-z0-9' | head -c 64)" + + echo "Installing Nextcloud..." + + occ maintenance:install \ + --database "pgsql" \ + --database-host "$POSTGRES_HOST" \ + --database-port "$POSTGRES_PORT" \ + --database-user "$POSTGRES_USER" \ + --database-pass "$POSTGRES_PASSWORD" \ + --database-name "$POSTGRES_DB" \ + --admin-user "$ADMIN_USER" \ + --admin-pass "$ADMIN_PASS" \ + --data-dir "/var/lib/nextcloud" + + occ user:delete admin + + occ app:disable \ + app_api \ + contactsinteraction \ + dashboard \ + federation \ + firstrunwizard \ + photos \ + recommendations \ + sharebymail \ + support \ + survey_client \ + user_status \ + weather_status + + occ app:install \ + oidc_login +fi + +occ upgrade +occ app:update --all + +occ db:add-missing-columns +occ db:add-missing-indices +occ db:add-missing-primary-keys + +occ maintenance:repair --include-expensive + +occ background:cron +occ maintenance:update:htaccess + +[ -n "${EXTRA_INIT:-}" ] && eval "$EXTRA_INIT" + +cron + +PHPRC="$(dirname "$(readlink -f "$(which php)")")/../lib/php.ini" +export PHPRC + +setsid --wait httpd "$@" & +pid=$! +trap 'kill -INT $pid' INT +wait $pid +exit $? diff --git a/packages/docker/ntfy/default.nix b/packages/docker/ntfy/default.nix index baf4c3f..72f5458 100644 --- a/packages/docker/ntfy/default.nix +++ b/packages/docker/ntfy/default.nix @@ -10,7 +10,7 @@ pkgs.dockerTools.buildImage { }; config = { - Entrypoint = [ "/bin/ntfy" ]; + Entrypoint = [ "ntfy" ]; Cmd = [ "serve" ]; ExposedPorts = { "80/tcp" = { }; diff --git a/packages/docker/oidcwarden/default.nix b/packages/docker/oidcwarden/default.nix index 866ceb3..ff00cf7 100644 --- a/packages/docker/oidcwarden/default.nix +++ b/packages/docker/oidcwarden/default.nix @@ -24,7 +24,7 @@ pkgs.dockerTools.buildImage { }; config = { - Entrypoint = [ "/bin/oidcwarden" ]; + Entrypoint = [ "oidcwarden" ]; Env = [ "WEB_VAULT_FOLDER=${selfPkgs.oidcwarden.webvault}/share/vaultwarden/vault" "DATA_FOLDER=/var/lib/vaultwarden" diff --git a/packages/docker/outline/default.nix b/packages/docker/outline/default.nix index 5275d7a..cce9655 100644 --- a/packages/docker/outline/default.nix +++ b/packages/docker/outline/default.nix @@ -13,7 +13,7 @@ pkgs.dockerTools.buildImage { }; config = { - Entrypoint = [ "/bin/outline-server" ]; + Entrypoint = [ "outline-server" ]; ExposedPorts = { "3000/tcp" = { }; }; diff --git a/packages/docker/postgresql/default.nix b/packages/docker/postgresql/default.nix index 3f32ece..828be5b 100644 --- a/packages/docker/postgresql/default.nix +++ b/packages/docker/postgresql/default.nix @@ -36,7 +36,7 @@ pkgs.dockerTools.buildImage { ''; config = { - Entrypoint = [ "/bin/entrypoint" ]; + Entrypoint = [ "entrypoint" ]; WorkingDir = "/var/lib/postgresql"; ExposedPorts = { "5432/tcp" = { }; diff --git a/packages/docker/prometheus-fail2ban-exporter/default.nix b/packages/docker/prometheus-fail2ban-exporter/default.nix index 40789f0..e443001 100644 --- a/packages/docker/prometheus-fail2ban-exporter/default.nix +++ b/packages/docker/prometheus-fail2ban-exporter/default.nix @@ -28,7 +28,7 @@ pkgs.dockerTools.buildImage { }; config = { - Entrypoint = [ "/bin/entrypoint" ]; + Entrypoint = [ "entrypoint" ]; ExposedPorts = { "9191/tcp" = { }; }; diff --git a/packages/docker/prometheus-fail2ban-exporter/entrypoint.sh b/packages/docker/prometheus-fail2ban-exporter/entrypoint.sh index db76bf8..fab4a07 100644 --- a/packages/docker/prometheus-fail2ban-exporter/entrypoint.sh +++ b/packages/docker/prometheus-fail2ban-exporter/entrypoint.sh @@ -20,4 +20,4 @@ LOG_PID=$! trap 'kill $LOG_PID' EXIT -exec /bin/prometheus-fail2ban-exporter "$@" > "$LOG_PIPE" 2>&1 +exec prometheus-fail2ban-exporter "$@" > "$LOG_PIPE" 2>&1 diff --git a/packages/docker/prometheus-node-exporter/default.nix b/packages/docker/prometheus-node-exporter/default.nix index 3722c6e..ab9d3f2 100644 --- a/packages/docker/prometheus-node-exporter/default.nix +++ b/packages/docker/prometheus-node-exporter/default.nix @@ -10,7 +10,7 @@ pkgs.dockerTools.buildImage { }; config = { - Entrypoint = [ "/bin/node_exporter" ]; + Entrypoint = [ "node_exporter" ]; Cmd = [ "--log.level=warn" ]; ExposedPorts = { "9100/tcp" = { }; diff --git a/packages/docker/prometheus-podman-exporter/default.nix b/packages/docker/prometheus-podman-exporter/default.nix index aff0551..5017011 100644 --- a/packages/docker/prometheus-podman-exporter/default.nix +++ b/packages/docker/prometheus-podman-exporter/default.nix @@ -32,7 +32,7 @@ pkgs.dockerTools.buildImage { ''; config = { - Entrypoint = [ "/bin/entrypoint" ]; + Entrypoint = [ "entrypoint" ]; ExposedPorts = { "9882/tcp" = { }; }; diff --git a/packages/docker/prometheus-podman-exporter/entrypoint.sh b/packages/docker/prometheus-podman-exporter/entrypoint.sh index e0bf6f5..681b8e2 100644 --- a/packages/docker/prometheus-podman-exporter/entrypoint.sh +++ b/packages/docker/prometheus-podman-exporter/entrypoint.sh @@ -20,4 +20,4 @@ LOG_PID=$! trap 'kill $LOG_PID' EXIT -exec /bin/prometheus-podman-exporter "$@" > "$LOG_PIPE" 2>&1 +exec prometheus-podman-exporter "$@" > "$LOG_PIPE" 2>&1 diff --git a/packages/docker/prometheus-smartctl-exporter/default.nix b/packages/docker/prometheus-smartctl-exporter/default.nix index 87d5d5f..92246a0 100644 --- a/packages/docker/prometheus-smartctl-exporter/default.nix +++ b/packages/docker/prometheus-smartctl-exporter/default.nix @@ -10,7 +10,7 @@ pkgs.dockerTools.buildImage { }; config = { - Entrypoint = [ "/bin/smartctl_exporter" ]; + Entrypoint = [ "smartctl_exporter" ]; Cmd = [ "--log.level=warn" ]; ExposedPorts = { "9633/tcp" = { }; diff --git a/packages/docker/prometheus/default.nix b/packages/docker/prometheus/default.nix index 3e7f595..4d01824 100644 --- a/packages/docker/prometheus/default.nix +++ b/packages/docker/prometheus/default.nix @@ -10,7 +10,7 @@ pkgs.dockerTools.buildImage { }; config = { - Entrypoint = [ "/bin/prometheus" ]; + Entrypoint = [ "prometheus" ]; ExposedPorts = { "9090/tcp" = { }; }; diff --git a/packages/docker/redis/default.nix b/packages/docker/redis/default.nix index f881d57..aea4aae 100644 --- a/packages/docker/redis/default.nix +++ b/packages/docker/redis/default.nix @@ -16,7 +16,7 @@ pkgs.dockerTools.buildImage { }; config = { - Entrypoint = [ "/bin/redis-server" ]; + Entrypoint = [ "redis-server" ]; WorkingDir = "/var/lib/redis"; ExposedPorts = { "6379/tcp" = { }; diff --git a/packages/docker/sish/default.nix b/packages/docker/sish/default.nix index a05275b..acc2fa5 100644 --- a/packages/docker/sish/default.nix +++ b/packages/docker/sish/default.nix @@ -10,7 +10,7 @@ pkgs.dockerTools.buildImage { }; config = { - Entrypoint = [ "/bin/sish" ]; + Entrypoint = [ "sish" ]; Cmd = [ "--ssh-address=0.0.0.0:2222" "--http-address=0.0.0.0:80" diff --git a/packages/docker/traefik/default.nix b/packages/docker/traefik/default.nix index e298423..68e62d1 100644 --- a/packages/docker/traefik/default.nix +++ b/packages/docker/traefik/default.nix @@ -10,7 +10,7 @@ pkgs.dockerTools.buildImage { }; config = { - Entrypoint = [ "/bin/traefik" ]; + Entrypoint = [ "traefik" ]; ExposedPorts = { "80/tcp" = { }; }; diff --git a/packages/docker/whoami/default.nix b/packages/docker/whoami/default.nix index 994903a..f26c778 100644 --- a/packages/docker/whoami/default.nix +++ b/packages/docker/whoami/default.nix @@ -15,7 +15,7 @@ pkgs.dockerTools.buildImage { }; config = { - Entrypoint = [ "/bin/whoami" ]; + Entrypoint = [ "whoami" ]; ExposedPorts = { "80/tcp" = { }; }; diff --git a/packages/docker/yq/default.nix b/packages/docker/yq/default.nix index 1bfaac0..c63f656 100644 --- a/packages/docker/yq/default.nix +++ b/packages/docker/yq/default.nix @@ -10,6 +10,6 @@ pkgs.dockerTools.buildImage { }; config = { - Entrypoint = [ "/bin/yq" ]; + Entrypoint = [ "yq" ]; }; }