aboutsummaryrefslogtreecommitdiff
path: root/tw/services/nextcloud.scm
blob: 6ede7005d649e01a1da913f070f9580c8dfa9410 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
(define-module (tw services nextcloud)
  #:use-module (gnu)
  #:use-module (gnu packages certs)
  #:use-module (gnu packages php)
  #:use-module (gnu services certbot)
  #:use-module (gnu services mcron)
  #:use-module (gnu services web)
  #:use-module (guix gexp)
  #:use-module (tw services))

(define-public %nextcloud-php.ini
  (computed-file "nextcloud-php.ini"
    #~(begin
        (use-modules (ice-9 popen) (ice-9 rdelim))
        (let* ((php-config #$(file-append php "/bin/php-config"))
               (pipe (open-pipe* OPEN_READ php-config "--extension-dir"))
               (php-extdir (read-line pipe)))
          (unless (zero? (status:exit-val (close-pipe pipe)))
            (error "Failed to get PHP extension dir"))
          (with-output-to-file #$output
            ;; Guix's PHP comes with the following extensions built-in,
            ;; so no extension= line necessary:
            ;; pdo_mysql, bcmath, bz2, exif, gd, iconv, intl
            (lambda () (display (string-append "\
memory_limit=512M
extension_dir=/run/current-system/profile/lib/php/extensions/" (basename php-extdir) "
extension=imagick
; Caching extensions for Nextcloud
extension=apcu
apc.enable_cli=1
zend_extension=opcache
; https://www.php.net/manual/en/opcache.configuration.php
opcache.enable=1
opcache.interned_strings_buffer=32
opcache.max_accelerated_files=10000
opcache.memory_consumption=256
opcache.save_comments=1
; It will take up to revalidate_freq seconds for changes to config.php to be applied.
opcache.revalidate_freq=120
"))))))))

(define-public %nextcloud-services
  (list (simple-service 'nextcloud-https-server httpd-service-type
          ;; The certbot service redirects everything on port 80 to
          ;; port 443 by default, modulo its own /.well-known paths.
          (list (httpd-virtualhost "*:443" (list "\
# For Nextcloud.
ServerName cloud.wilkenfamily.de
DocumentRoot /var/www/nextcloud
SSLEngine on
SSLCertificateFile \"/etc/letsencrypt/live/cloud.wilkenfamily.de/fullchain.pem\"
SSLCertificateKeyFile \"/etc/letsencrypt/live/cloud.wilkenfamily.de/privkey.pem\"
Header always set Strict-Transport-Security \"max-age=15552000\"

# Don't check for .htaccess files above DocumentRoot.
<Directory \"/\">
    AllowOverride None
</Directory>

<Directory /var/www/nextcloud>
    Options +FollowSymlinks
    AllowOverride All
    <IfModule mod_dav.c>
        Dav off
    </IfModule>
    SetEnv HOME /var/www/nextcloud
    SetEnv HTTP_HOME /var/www/nextcloud
</Directory>

# Redirect to local php-fpm if mod_php is not available
<IfModule !mod_php7.c>
    <IfModule proxy_fcgi_module>
        # Enable http authorization headers
        <IfModule setenvif_module>
            SetEnvIfNoCase ^Authorization$ \"(.+)\" HTTP_AUTHORIZATION=$1
        </IfModule>
        <FilesMatch \".+\\.ph(ar|p|tml)$\">
            <If \"-f %{REQUEST_FILENAME}\">
                SetHandler \"proxy:unix:/var/run/php-fpm.sock|fcgi://localhost/\"
            </If>
        </FilesMatch>
        # Deny access to raw PHP sources and files without filename (e.g. '.php')
        <FilesMatch \"^\\.ph(ar|p|ps|tml)$|.*\\.phps$\">
            Require all denied
        </FilesMatch>
    </IfModule>
</IfModule>
"))))

        (service (@ (tw services php-fpm) php-fpm-service-type)
          (php-fpm-configuration
           (user "httpd")
           (group "httpd")
           (socket "/var/run/php-fpm.sock")
           (socket-user "httpd")
           (socket-group "httpd")
           (php-ini-file %nextcloud-php.ini)))

        (simple-service 'nextcloud-certificates certbot-service-type
          (list (certificate-configuration
                 (domains '("cloud.wilkenfamily.de"))
                 (deploy-hook %httpd-cert-deploy-hook))))

        ;; Nextcloud cron
        (simple-service 'nextcloud-cron mcron-service-type
          (list #~(job "*/5 * * * *"
                       #$(program-file "nextcloud-cron-command"
                           #~(begin
                               ;; `setgid' first while we're still root
                               (setgid (group:gid (getgr "httpd")))
                               (setuid (passwd:uid (getpw "httpd")))
                               (chdir "/var/www/nextcloud")
                               ;; Nextcloud News needs this to fetch HTTPS feeds.
                               (setenv "SSL_CERT_DIR" #$(file-append nss-certs "/etc/ssl/certs"))
                               (execl #$(file-append php "/bin/php") "php"
                                      "-c" #$%nextcloud-php.ini "cron.php"))))

                ;; Nextcloud backups
                ;; Requires: sudo, php, btrfs, mysqldump, rsync
                (let ((backup-script (local-file "files/nextcloud-backup" #:recursive? #t)))
                  #~(job "0 6 * * *"
                         (lambda ()
                           ;; Pass through the php.ini file that allows us to
                           ;; use Nextcloud's occ script.
                           (execl #$backup-script "nextcloud-backup" #$%nextcloud-php.ini))
                         (string-append #$backup-script " " #$%nextcloud-php.ini)))))))