(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.
AllowOverride None
Options +FollowSymlinks
AllowOverride All
Dav off
SetEnv HOME /var/www/nextcloud
SetEnv HTTP_HOME /var/www/nextcloud
# Redirect to local php-fpm if mod_php is not available
# Enable http authorization headers
SetEnvIfNoCase ^Authorization$ \"(.+)\" HTTP_AUTHORIZATION=$1
SetHandler \"proxy:unix:/var/run/php-fpm.sock|fcgi://localhost/\"
# Deny access to raw PHP sources and files without filename (e.g. '.php')
Require all denied
"))))
(service 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)))))))