(define-module (tw services nextcloud) #:use-module (gnu) #: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) " ; 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=128 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 * * * *" (lambda () (chdir "/var/www/nextcloud") ;; `setgid' first while we're still root (setgid (group:gid (getgr "httpd"))) (setuid (passwd:uid (getpw "httpd"))) (execl #$(file-append php "/bin/php") "php" "-c" #$%nextcloud-php.ini "cron.php")) (string-append #$(file-append php "/bin/php") " -c " #$%nextcloud-php.ini " /var/www/nextcloud/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)))))))