kulupu-mi/kulupu/services/gotosocial.scm

172 lines
6.5 KiB
Scheme

(define-module (kulupu services gotosocial)
#:use-module (guix gexp)
#:use-module ((guix licenses) #:prefix license:)
#:use-module (guix records)
#:use-module (guix packages)
#:use-module (gnu services)
#:use-module (gnu services certbot)
#:use-module (gnu services configuration)
#:use-module (gnu services databases)
#:use-module (gnu services base)
#:use-module (gnu services shepherd)
#:use-module (gnu services web)
#:use-module (gnu system shadow)
#:use-module (gnu packages admin)
#:use-module (gnu packages bash)
#:use-module (gnu packages base)
#:use-module (kulupu packages gotosocial)
#:use-module (ice-9 match)
#:export (gotosocial-service-type
gotosocial-configuration))
(define-maybe string)
(define-configuration gotosocial-configuration
(host
(string "localhost")
"Name to use as gotosocial host")
(gotosocial
(package gotosocial)
"The gotosocial package to use")
(frontend
(package gotosocial-frontend)
"The gotosocial web asset package to use")
(config-file
(maybe-string)
"Path to configuration file, defaults to no configuration file")
(port
(integer 8080)
"Port to listen on, default 8080")
(work-dir
(string "/var/lib/gotosocial")
"GTS work directory")
(run-dir
(string "/var/run/gotosocial")
"GTS runtime directory")
(postgres?
(boolean #t)
"Set up postgres DB, use sqlite if false")
(nginx?
(boolean #t)
"Set up reverse proxy via nginx")
(https?
(boolean #t)
"Set up HTTPS via certbot")
(database-address
(string "/var/run/gotosocial/gts.db")
"Address of the database, default /var/run/gotosocial/gts.db")
(no-serialization))
(define (gotosocial-shepherd-service config)
(match-record config <gotosocial-configuration>
(gotosocial frontend config-file port work-dir run-dir host postgres? database-address)
(let* ((gts (file-append gotosocial "/bin/gotosocial")))
(list (shepherd-service
(documentation "Run GoToSocial")
(requirement `(networking ,@(if postgres? '(postgres) '())))
(provision '(gotosocial))
(start #~(make-forkexec-constructor
(list
(#$(file-append gotosocial "/bin/gotosocial")
"server" "start" "--syslog-enabled"
"--port=" (number->string #$port)
$#(when (not postgres?) "--db-type=sqlite")
"--db-address=" #$database-address
"--letsencrypt-cert-dir=" #$work-dir "/storage/certs"
"--storage-local-base-path=" #$work-dir "/storage"
"--web-asset-base-dir=" #$(file-append frontend "/gotosocial/web/assets")
"--web-template-base-dir=" #$(file-append frontend "/gotosocial/web/template")
"--host=" host))
#:user "gotosocial"
#:group "gotosocial"
#:directory #$work-dir))
(stop #~(make-kill-destructor)))))))
(define (gotosocial-postgresql-roles config)
(match-record config <gotosocial-configuration>
(postgres?)
(if postgres? (list (postgresql-role
(name "gotosocial")
(create-database? #t)))
'())))
(define (gotosocial-certbot config)
(match-record config <gotosocial-configuration>
(https? host nginx?)
(if (not https?) '()
(list (certificate-configuration
(domains (list host))
(deploy-hook (if nginx? %nginx-cert-deploy-hook %gotosocial-cert-deploy-hook)))))))
(define %nginx-cert-deploy-hook
(program-file
"nginx-cert-deploy-hook"
#~(let ((pid (call-with-input-file "/var/run/nginx/pid" read)))
(kill pid SIGHUP))))
(define %gotosocial-cert-deploy-hook
(program-file
"gotosocial-cert-deploy-hook"
(with-imported-modules '((guix build utils))
#~(begin (use-module (guix build utils))
(invoke "herd" "restart" "gotosocial")))))
(define (gotosocial-nginx config)
(match-record config <gotosocial-configuration>
(nginx? https? host run-dir)
(if (not nginx?) '()
(list (nginx-server-configuration
(listen (if https? '("443 ssl") '("80")))
(server-name (list host))
(ssl-certificate (if https? (string-append "/etc/letsencrypt/live/" host "/fullchain.pem") #f))
(ssl-certificate-key (if https? (string-append "/etc/letsencrypt/live/" host "/privkey.pem") #f))
(locations (list
(nginx-location-configuration
(uri "/")
(body `(,(string-append "proxy_pass http://unix:" run-dir "/gotosocial.socket;")
"proxy_set_header Host $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-Proto $scheme;"))))))))))
(define (gotosocial-activation config)
(match-record config <gotosocial-configuration>
(work-dir run-dir)
#~(begin
(use-modules (guix build utils)
(ice-9 string-fun))
(let* ((user (getpw "gotosocial"))
(user-id (passwd:uid user))
(group-id (passwd:gid user)))
(mkdir-p #$work-dir)
(mkdir-p #$run-dir)
(chown #$work-dir user-id group-id)
(chown #$run-dir user-id group-id)))))
(define (gotosocial-accounts config)
(match-record config <gotosocial-configuration>
(work-dir)
(list (user-group
(name "gotosocial")
(system? #t))
(user-account
(name "gotosocial")
(system? #t)
(group "gotosocial")
(comment "GoToSocial server user")
(home-directory work-dir)
(shell (file-append bash-minimal "/bin/bash"))))))
(define-public gotosocial-service-type
(service-type
(name 'gotosocial)
(extensions
(list (service-extension shepherd-root-service-type gotosocial-shepherd-service)
(service-extension account-service-type gotosocial-accounts)
(service-extension activation-service-type gotosocial-activation)
(service-extension nginx-service-type gotosocial-nginx)
(service-extension certbot-service-type gotosocial-certbot)
(service-extension postgresql-role-service-type gotosocial-postgresql-roles)))
(description "Runs GoToSocial")
(default-value (gotosocial-configuration))))