From 898f438b755e3f73e91c91f9abd515f50a7b992f Mon Sep 17 00:00:00 2001 From: matt1432 Date: Fri, 23 Feb 2024 00:34:43 -0500 Subject: [PATCH] feat(arion): migrate nextcloud --- devices/nas/modules/arion/default.nix | 1 + .../nas/modules/arion/nextcloud/compose.nix | 106 +++++++++++ .../arion/nextcloud/images/nextcloud.nix | 8 + .../modules/arion/nextcloud/images/nginx.nix | 8 + .../arion/nextcloud/images/onlyoffice.nix | 8 + .../arion/nextcloud/images/postgres.nix | 8 + .../modules/arion/nextcloud/images/redis.nix | 8 + .../nas/modules/arion/nextcloud/nginx.conf | 180 ++++++++++++++++++ flake.lock | 8 +- 9 files changed, 331 insertions(+), 4 deletions(-) create mode 100644 devices/nas/modules/arion/nextcloud/compose.nix create mode 100644 devices/nas/modules/arion/nextcloud/images/nextcloud.nix create mode 100644 devices/nas/modules/arion/nextcloud/images/nginx.nix create mode 100644 devices/nas/modules/arion/nextcloud/images/onlyoffice.nix create mode 100644 devices/nas/modules/arion/nextcloud/images/postgres.nix create mode 100644 devices/nas/modules/arion/nextcloud/images/redis.nix create mode 100644 devices/nas/modules/arion/nextcloud/nginx.conf diff --git a/devices/nas/modules/arion/default.nix b/devices/nas/modules/arion/default.nix index 4ba749d3..a4f1de67 100644 --- a/devices/nas/modules/arion/default.nix +++ b/devices/nas/modules/arion/default.nix @@ -8,6 +8,7 @@ in { ./homepage/compose.nix ./immich/compose.nix ./music/jbots/compose.nix + ./nextcloud/compose.nix ]; arion = { diff --git a/devices/nas/modules/arion/nextcloud/compose.nix b/devices/nas/modules/arion/nextcloud/compose.nix new file mode 100644 index 00000000..34b80cf9 --- /dev/null +++ b/devices/nas/modules/arion/nextcloud/compose.nix @@ -0,0 +1,106 @@ +{ + config, + lib, + ... +}: let + inherit (config.sops) secrets; + inherit (config.arion) rwDataDir; + inherit (lib) concatStrings; + + rwPath = rwDataDir + "/nextcloud"; +in { + arion.projects."nextcloud" = { + "app-server" = { + image = ./images/nextcloud.nix; + restart = "always"; + + expose = [ + "80" + "9000" + ]; + + volumes = [ + "${rwPath}/data:/var/www/html" + "/data/docs:/var/www/drive" + ]; + + env_file = [secrets.nextcloud.path]; + + environment = { + POSTGRES_DB = "nextcloud"; + POSTGRES_HOST = "nextcloud-db"; + REDIS_HOST = "nextcloud-cache"; + REDIS_HOST_PASSWORD = "password"; + TRUSTED_PROXIES = "cloud.nelim.org"; + NEXTCLOUD_INIT_HTACCESS = "true"; + }; + }; + + "onlyoffice-document-server" = { + image = ./images/onlyoffice.nix; + restart = "always"; + + environment.JWT_ENABLED = "false"; + + ports = ["8055:80"]; + expose = [ + "80" + "443" + ]; + + volumes = ["${rwPath}/data-onlyoffice:/var/log/onlyoffice"]; + tmpfs = [ + "/var/www/onlyoffice/Data" + "/var/lib/postgresql" + "/usr/share/fonts/truetype/custom" + "/var/lib/rabbitmq" + "/var/lib/redis" + "/var/lib/onlyoffice" + ]; + + # Fix mobile editing + entrypoint = ''bash -c "${let + filePath = "/var/www/onlyoffice/documentserver/web-apps/apps/*/mobile/dist/js/app.js"; + func = "isSupportEditFeature=function()"; + in + concatStrings [ + "sed -i 's/${func}{return!1}/${func}{return 1}/g' ${filePath};" + "/app/ds/run-document-server.sh;" + "apt update;" + "apt install imagemagick -y;" + ]}"''; + }; + + "nginx-server" = { + image = ./images/nginx.nix; + restart = "always"; + ports = ["8042:80"]; + volumes = [ + "${./nginx.conf}:/etc/nginx/nginx.conf" + "${rwPath}/data:/var/www/html" + ]; + }; + + "nextcloud-db" = { + image = ./images/postgres.nix; + restart = "always"; + env_file = [secrets.nextcloud.path]; + volumes = [ + "${rwPath}/database:/var/lib/postgresql/data" + "/etc/localtime:/etc/localtime:ro" + ]; + }; + + "nextcloud-cache" = { + image = ./images/redis.nix; + restart = "always"; + #mem_limit = "2048m"; + #mem_reservation = "512m"; + env_file = [secrets.nextcloud.path]; + command = ''/bin/sh -c "redis-server --requirepass $$REDIS_HOST_PASSWORD"''; + tmpfs = [ + "/data" + ]; + }; + }; +} diff --git a/devices/nas/modules/arion/nextcloud/images/nextcloud.nix b/devices/nas/modules/arion/nextcloud/images/nextcloud.nix new file mode 100644 index 00000000..12571f48 --- /dev/null +++ b/devices/nas/modules/arion/nextcloud/images/nextcloud.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "nextcloud"; + imageDigest = "sha256:24e3d19ce514f98ccde8e4e69e0ed1703dd2a3c398acbcfd49725b18498fd212"; + sha256 = "00cl88klkqgj4xdiydabaxhrc4m0ll75s9sayp4h0rlzphf5qpjw"; + finalImageName = "nextcloud"; + finalImageTag = "fpm"; +} diff --git a/devices/nas/modules/arion/nextcloud/images/nginx.nix b/devices/nas/modules/arion/nextcloud/images/nginx.nix new file mode 100644 index 00000000..e0d6913f --- /dev/null +++ b/devices/nas/modules/arion/nextcloud/images/nginx.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "nginx"; + imageDigest = "sha256:c26ae7472d624ba1fafd296e73cecc4f93f853088e6a9c13c0d52f6ca5865107"; + sha256 = "0xqwbwjmcd3zgwv7hl27jxczxv9rfc2d3a49a0230dzw1xg9fnc3"; + finalImageName = "nginx"; + finalImageTag = "latest"; +} diff --git a/devices/nas/modules/arion/nextcloud/images/onlyoffice.nix b/devices/nas/modules/arion/nextcloud/images/onlyoffice.nix new file mode 100644 index 00000000..e3d5b52f --- /dev/null +++ b/devices/nas/modules/arion/nextcloud/images/onlyoffice.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "onlyoffice/documentserver"; + imageDigest = "sha256:ba008a8ff0d29199fa46cd7b7397d7cc734a9bb3a1fa7842a49b529469540399"; + sha256 = "1ifdbas5lcig6j5q9wnw5ms7nir4199ap7a2fgr44lvr1q4pysrb"; + finalImageName = "onlyoffice/documentserver"; + finalImageTag = "latest"; +} diff --git a/devices/nas/modules/arion/nextcloud/images/postgres.nix b/devices/nas/modules/arion/nextcloud/images/postgres.nix new file mode 100644 index 00000000..9a0c2200 --- /dev/null +++ b/devices/nas/modules/arion/nextcloud/images/postgres.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "postgres"; + imageDigest = "sha256:20e49432a20e1a63bb985977c32ec8f110bc609b93de35ad4f19c5486abcefaa"; + sha256 = "0jxkjj726jb1hal4j1vyhnrmbpyrkvawq5nf3dpiad8h3zamvk66"; + finalImageName = "postgres"; + finalImageTag = "14.2-alpine"; +} diff --git a/devices/nas/modules/arion/nextcloud/images/redis.nix b/devices/nas/modules/arion/nextcloud/images/redis.nix new file mode 100644 index 00000000..67963f66 --- /dev/null +++ b/devices/nas/modules/arion/nextcloud/images/redis.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "redis"; + imageDigest = "sha256:558d0845026fe0bf091a00c0ad647ffacf9df385d780d433ca70661f7276f834"; + sha256 = "0bbbzjl2fc2wvwj45j4z8kff2fj82qjk5nsgi79bqzm72x428mjb"; + finalImageName = "redis"; + finalImageTag = "7.0.0-alpine"; +} diff --git a/devices/nas/modules/arion/nextcloud/nginx.conf b/devices/nas/modules/arion/nextcloud/nginx.conf new file mode 100644 index 00000000..55b8068c --- /dev/null +++ b/devices/nas/modules/arion/nextcloud/nginx.conf @@ -0,0 +1,180 @@ +user www-data; +worker_processes 1; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + + upstream backend { + server app-server:9000; + #server unix:/var/run/php/php7.4-fpm.sock; + } + + # Set the `immutable` cache control options only for assets with a cache busting `v` argument + map $arg_v $asset_immutable { + "" ""; + default "immutable"; + } + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + map $http_host $this_host { + "" $host; + default $http_host; + } + + map $http_x_forwarded_proto $the_scheme { + default $http_x_forwarded_proto; + "" $scheme; + } + + map $http_x_forwarded_host $the_host { + default $http_x_forwarded_host; + "" $this_host; + } + + server { + listen 80; + # The below allows for being behind a reverse proxy and allowing the Nextcloud app to connect + server_tokens off; + + # Add headers to serve security related headers + add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;"; + # HTTP response headers borrowed from Nextcloud `.htaccess` + add_header Referrer-Policy "no-referrer" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-Download-Options "noopen" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Permitted-Cross-Domain-Policies "none" always; + add_header X-Robots-Tag "none" always; + add_header X-XSS-Protection "1; mode=block" always; + + # Remove X-Powered-By, which is an information leak + fastcgi_hide_header X-Powered-By; + + root /var/www/html; + client_max_body_size 10G; # 0=unlimited - set max upload size + fastcgi_buffers 64 4K; + client_body_buffer_size 512k; + + gzip off; + + index index.php index.html /index.php$request_uri; + + # Rule borrowed from `.htaccess` to handle Microsoft DAV clients + location = / { + if ( $http_user_agent ~ ^DavClnt ) { + return 302 /remote.php/webdav/$is_args$args; + } + } + + location ^~ /.well-known { + + location = /.well-known/carddav { return 301 /remote.php/dav/; } + location = /.well-known/caldav { return 301 /remote.php/dav/; } + #location = /.well-known/webfinger { return 301 /index.php/.well-known/webfinger/; } + #location = /.well-known/nodeinfo { return 301 /index.php/.well-known/nodeinfo/; }} + + location /.well-known/acme-challenge { try_files $uri $uri/ =404; } + location /.well-known/pki-validation { try_files $uri $uri/ =404; } + + # Let Nextcloud's API for `/.well-known` URIs handle all other + # requests by passing them to the front-end controller. + return 301 /index.php$request_uri; + } + + location = /robots.txt { + allow all; + log_not_found off; + access_log off; + } + + # Rules borrowed from `.htaccess` to hide certain paths from clients + location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; } + location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; } + + location ~* ^/ds-vpath/ { + rewrite /ds-vpath/(.*) /$1 break; + proxy_pass http://onlyoffice-document-server; + proxy_redirect off; + + client_max_body_size 10G; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + proxy_set_header Host $http_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 $the_host/ds-vpath; + proxy_set_header X-Forwarded-Proto $the_scheme; + } + + location ~ \.php(?:$|/) { + # Required for legacy support + rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri; + + fastcgi_split_path_info ^(.+?\.php)(/.*)$; + set $path_info $fastcgi_path_info; + + try_files $fastcgi_script_name =404; + + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_param HTTPS off; + + fastcgi_param modHeadersAvailable true; #Avoid sending the security headers twice + fastcgi_param front_controller_active true; + fastcgi_pass backend; + + fastcgi_intercept_errors on; + fastcgi_request_buffering off; + + fastcgi_max_temp_file_size 0; + } + + location ~ \.(?:css|js|svg|gif|png|jpg|ico|wasm|tflite|map)$ { + try_files $uri /index.php$request_uri; + add_header Cache-Control "public, max-age=15778463, $asset_immutable"; + access_log off; # Optional: Don't log access to assets + + location ~ \.wasm$ { + default_type application/wasm; + } + } + + location ~ \.woff2?$ { + try_files $uri /index.php$request_uri; + expires 7d; # Cache-Control policy borrowed from `.htaccess` + access_log off; # Optional: Don't log access to assets + } + + # Rule borrowed from `.htaccess` + location /remote { + return 301 /remote.php$request_uri; + } + + location / { + try_files $uri $uri/ /index.php$request_uri; + } + } +} diff --git a/flake.lock b/flake.lock index e8e727fe..2c870f42 100644 --- a/flake.lock +++ b/flake.lock @@ -1342,11 +1342,11 @@ "sops-nix": "sops-nix" }, "locked": { - "lastModified": 1708281692, - "narHash": "sha256-MwEtc7/Q9zOAXkN90mJB19spwDJg1wKq9QE27EQ47Kk=", + "lastModified": 1708664449, + "narHash": "sha256-rotTXLKXndrSrIQ11cZjHXuj+dqJkANAxCRzvsFpXBs=", "ref": "refs/heads/main", - "rev": "82e860c8bd9a3c634e73478fd0dd537f09c48c97", - "revCount": 41, + "rev": "adc3aa2adff3a259b96f070e2abfdb33f2364bf9", + "revCount": 42, "type": "git", "url": "ssh://git@git.nelim.org/matt1432/nixos-secrets" },