From 98cf95a922e613fe4d0be933a8f613222bc2b85c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 12 Apr 2021 01:42:46 +0100
Subject: [PATCH] Add nextcloud service

---
 configuration/default.nix                     |   7 +-
 .../services/configs/nginx-nextcloud.conf     | 173 ++++++++++++++++++
 configuration/services/nextcloud.nix          |  52 ++++++
 3 files changed, 230 insertions(+), 2 deletions(-)
 create mode 100644 configuration/services/configs/nginx-nextcloud.conf
 create mode 100644 configuration/services/nextcloud.nix

diff --git a/configuration/default.nix b/configuration/default.nix
index de10004..3c9b0df 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -1,7 +1,7 @@
 { config, pkgs, ... }:
 
 {
-  imports = [ ./services/gitea.nix ];
+  imports = [ ./services/gitea.nix ./services/nextcloud.nix ];
 
   nix = {
     package = pkgs.nixFlakes;
@@ -52,7 +52,10 @@
           enableACME = true;
           locations."/" = { proxyPass = "http://localhost:${toString port}"; };
         } // extra;
-    in { "gitea.tlater.net" = host 3000 { }; };
+    in {
+      "gitea.tlater.net" = host 3000 { };
+      "nextcloud.tlater.net" = host 3001 { };
+    };
   };
 
   security.acme = {
diff --git a/configuration/services/configs/nginx-nextcloud.conf b/configuration/services/configs/nginx-nextcloud.conf
new file mode 100644
index 0000000..3eb1193
--- /dev/null
+++ b/configuration/services/configs/nginx-nextcloud.conf
@@ -0,0 +1,173 @@
+worker_processes auto;
+
+error_log  /var/log/nginx/error.log warn;
+pid        /var/run/nginx.pid;
+
+
+events {
+    worker_connections  1024;
+}
+
+
+http {
+    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;
+
+    set_real_ip_from  10.0.0.0/8;
+    set_real_ip_from  172.16.0.0/12;
+    set_real_ip_from  192.168.0.0/16;
+    real_ip_header    X-Real-IP;
+
+    #gzip  on;
+
+    upstream php-handler {
+        server nextcloud-nextcloud:9000;
+    }
+
+    server {
+        listen 80;
+
+        # Add headers to serve security related headers
+        # Before enabling Strict-Transport-Security headers please read into this
+        # topic first.
+        #add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
+        #
+        # WARNING: Only add the preload option once you read about
+        # the consequences in https://hstspreload.org/. This option
+        # will add the domain to a hardcoded list that is shipped
+        # in all major browsers and getting removed from this list
+        # could take several months.
+        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;
+
+        # Path to the root of your installation
+        root /var/www/html;
+
+        location = /robots.txt {
+            allow all;
+            log_not_found off;
+            access_log off;
+        }
+
+        # The following 2 rules are only needed for the user_webfinger app.
+        # Uncomment it if you're planning to use this app.
+        #rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
+        #rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
+
+        # The following rule is only needed for the Social app.
+        # Uncomment it if you're planning to use this app.
+        #rewrite ^/.well-known/webfinger /public.php?service=webfinger last;
+
+        location = /.well-known/carddav {
+            return 301 $scheme://$host:$server_port/remote.php/dav;
+        }
+
+        location = /.well-known/caldav {
+            return 301 $scheme://$host:$server_port/remote.php/dav;
+        }
+
+        # set max upload size
+        client_max_body_size 10G;
+        fastcgi_buffers 64 4K;
+
+        # Enable gzip but do not remove ETag headers
+        gzip on;
+        gzip_vary on;
+        gzip_comp_level 4;
+        gzip_min_length 256;
+        gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
+        gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
+
+        # Uncomment if your server is build with the ngx_pagespeed module
+        # This module is currently not supported.
+        #pagespeed off;
+
+        location / {
+            rewrite ^ /index.php;
+        }
+
+        location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ {
+            deny all;
+        }
+        location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) {
+            deny all;
+        }
+
+        location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+)\.php(?:$|\/) {
+            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 $path_info;
+            # fastcgi_param HTTPS on;
+
+            # Avoid sending the security headers twice
+            fastcgi_param modHeadersAvailable true;
+
+            # Enable pretty urls
+            fastcgi_param front_controller_active true;
+            fastcgi_pass php-handler;
+            fastcgi_intercept_errors on;
+            fastcgi_request_buffering off;
+        }
+
+        location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
+            try_files $uri/ =404;
+            index index.php;
+        }
+
+        # Adding the cache control header for js, css and map files
+        # Make sure it is BELOW the PHP block
+        location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
+            try_files $uri /index.php$request_uri;
+            add_header Cache-Control "public, max-age=15778463";
+            # Add headers to serve security related headers (It is intended to
+            # have those duplicated to the ones above)
+            # Before enabling Strict-Transport-Security headers please read into
+            # this topic first.
+            #add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
+            #
+            # WARNING: Only add the preload option once you read about
+            # the consequences in https://hstspreload.org/. This option
+            # will add the domain to a hardcoded list that is shipped
+            # in all major browsers and getting removed from this list
+            # could take several months.
+            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;
+
+            # Optional: Don't log access to assets
+            access_log off;
+        }
+
+        location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap|mp4|webm)$ {
+            try_files $uri /index.php$request_uri;
+            # Optional: Don't log access to other assets
+            access_log off;
+        }
+    }
+}
diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
new file mode 100644
index 0000000..aeb9fc8
--- /dev/null
+++ b/configuration/services/nextcloud.nix
@@ -0,0 +1,52 @@
+{ config, ... }:
+
+{
+  virtualisation.pods.nextcloud = {
+    hostname = "nextcloud.tlater.net";
+    publish = [ "3001:80" ];
+
+    containers = {
+      nextcloud = {
+        image = "nextcloud:fpm-alpine";
+        dependsOn = [ "postgres" ];
+        volumes = [
+          "nextcloud-apps:/var/www/html/custom_apps"
+          "nextcloud-config:/var/www/html/config"
+          "nextcloud-data:/var/www/html/data"
+        ];
+        environment = {
+          POSTGRES_DB = "nextcloud";
+          POSTGRES_USER = "nextcloud";
+          POSTGRES_HOST = "nextcloud-postgres";
+          POSTGRES_PASSWORD = "rI7t7Nek1yGA9ucrRc7Uhy0jcjwPjnXa8me4o8tJON8=";
+          OVERWRITEPROTOCOL = "https";
+        };
+      };
+
+      cron = {
+        image = "nextcloud:fpm-alpine";
+        entrypoint = "/cron.sh";
+        dependsOn = [ "postgres" "nextcloud" ];
+        extraOptions = [ "--volumes-from=nextcloud-nextcloud" ];
+      };
+
+      nginx = {
+        image = "nginx:alpine";
+        dependsOn = [ "nextcloud" ];
+        volumes =
+          [ "${./configs/nginx-nextcloud.conf}:/etc/nginx/nginx.conf:ro" ];
+        extraOptions = [ "--volumes-from=nextcloud-nextcloud" ];
+      };
+
+      postgres = {
+        image = "postgres:alpine";
+        environment = {
+          POSTGRES_DB = "nextcloud";
+          POSTGRES_USER = "nextcloud";
+          POSTGRES_PASSWORD = "rI7t7Nek1yGA9ucrRc7Uhy0jcjwPjnXa8me4o8tJON8=";
+        };
+        volumes = [ "nextcloud-db-data-new:/var/lib/postgresql/data" ];
+      };
+    };
+  };
+}