blob: b643ac99a6735ecc5e2882bb9656d8da3a0c7e17 (
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
127
|
(define-module (tw services paperless)
#:use-module (gnu)
#:use-module ((gnu packages admin) #:select (shadow))
#:use-module (gnu services)
#:use-module (gnu services configuration)
#:use-module (gnu services databases)
#:use-module (gnu services web)
#:use-module (guix records)
#:use-module (tw services docker)
#:use-module (tw services restic)
#:use-module (tw services web)
#:export (paperless-service-type
paperless-configuration))
(define %paperless-user "paperless")
(define %paperless-uid 481) ; randomly chosen to avoid collisions
(define-configuration/no-serialization paperless-configuration
(container (string "ghcr.io/paperless-ngx/paperless-ngx:2.5") "Container image to run.")
(domain (string "localhost") "The external domain which will resolve to this
Grafana instance.")
(bind-address (string "127.0.0.1") "The host IP to bind to.")
(data-path (string "/var/lib/paperless") "The path to store data in, on the host.")
(secret-key-file string "A file name containing a @code{PAPERLESS_SECRET_KEY=...}
assignment. This is used to create session tokens, and must be changed from
the default. Make sure this file is readable only by the root user."))
(define (paperless-accounts config)
(list (user-account
(name %paperless-user)
(uid %paperless-uid)
(group %paperless-user)
(comment "Paperless server user")
(system? #t)
(home-directory (paperless-configuration-data-path config))
(shell (file-append shadow "/sbin/nologin")))
(user-group
(name %paperless-user)
(id %paperless-uid)
(system? #t))))
(define (paperless-environment config)
(match-record config <paperless-configuration> (domain bind-address)
(plain-file "paperless.env" (string-append "\
PAPERLESS_BIND_ADDR=" bind-address "
PAPERLESS_URL=https://" domain "
PAPERLESS_OCR_LANGUAGES=eng deu fra por
PAPERLESS_TIME_ZONE=Europe/Berlin
PAPERLESS_UID=" (number->string %paperless-uid) "
PAPERLESS_GID=" (number->string %paperless-uid) "
"))))
(define (paperless-docker-service config)
(match-record config <paperless-configuration> (container data-path secret-key-file)
(list (docker-container-configuration
(name "paperless")
(image container)
(read-only-root? #f) ; wrapper script runs "apt" in container
(volumes
;; We need to mount each subdir separately because the container
;; image specifies volumes to be mounted there otherwise.
(map (lambda (subdir)
(list (string-append data-path "/" subdir)
(string-append "/usr/src/paperless/" subdir)
#t))
'("consume" "data" "export" "media")))
(environment-files
(list (paperless-environment config) secret-key-file))
(network-type "host")
;; Paperless connects to redis://localhost:6379 (default port) by default.
(extra-requirements '(redis))))))
(define (paperless-reverse-proxy config)
(match-record config <paperless-configuration> (domain bind-address)
(if (string=? domain "localhost") (list)
(list (https-reverse-proxy-configuration
(domains (list domain))
;; The container runs on port 8000 and has a health check with
;; that port hardcoded, so just use that.
(destination-port 8000)
(destination-ip
(if (string=? bind-address "0.0.0.0")
"127.0.0.1"
bind-address))
(extra-locations
(list (nginx-location-configuration
(uri "/ws/") ; e.g. /ws/status/ endpoint
;; https://nginx.org/en/docs/http/websocket.html
(body `(("proxy_pass http://" ,destination-ip ":"
,(number->string destination-port) ";")
"proxy_http_version 1.1;"
"proxy_set_header Upgrade $http_upgrade;"
"proxy_set_header Connection \"upgrade\";"))))))))))
(define %paperless-backup-repo
(restic-local-repository (path "/var/backups/paperless")))
(define %paperless-backup-password
(restic-password-source
(type 'file)
(name "/etc/restic/lud-paperless")))
(define (paperless-backups config)
(match-record config <paperless-configuration> (data-path)
(list (restic-scheduled-backup
(schedule #~"0 5 * * *")
(paths (list data-path))
(repo %paperless-backup-repo)
(password %paperless-backup-password)))))
(define (paperless-backup-cleanup config)
(list (restic-scheduled-cleanup
(schedule #~"0 12 * * *")
(repo %paperless-backup-repo)
(password %paperless-backup-password)
(keep-daily 30)
(keep-monthly -1))))
(define paperless-service-type
(service-type
(name 'paperless)
(extensions
(list (service-extension docker-container-service-type paperless-docker-service)
(service-extension account-service-type paperless-accounts)
(service-extension https-reverse-proxy-service-type paperless-reverse-proxy)
(service-extension restic-backup-service-type paperless-backups)
(service-extension restic-cleanup-service-type paperless-backup-cleanup)))
(description "Paperless server, running under Docker.")))
|