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
|
(define-module (tw services matrix)
#:use-module (gnu)
#:use-module ((gnu packages admin) #:select (shadow))
#:use-module (gnu services)
#:use-module (gnu services certbot)
#:use-module (gnu services configuration)
#:use-module (gnu services databases)
#:use-module (gnu services docker)
#:use-module (gnu services web)
#:use-module (guix records)
#:use-module (tw services web)
#:use-module (tw services docker)
#:export (matrix-service-type
matrix-configuration
matrix-well-known-nginx-locations))
(define %matrix-user "matrix")
(define %matrix-uid 1337) ; match Mautrix bridge containers
(define %conduit-port 6167)
(define-maybe/no-serialization string)
(define-configuration/no-serialization matrix-configuration
(domain (string "localhost") "The external domain on which the Matrix server
will actually be hosted. If a different display domain is desired for
usernames, use @code{matrix-well-known-nginx-locations}.")
(server-name maybe-string "The external display name of the server where the
Matrix server is hosted. Usernames will include this hostname. If not given,
@code{domain} is used.")
(data-path (string "/var/lib/matrix") "The path to store data inside."))
(define (matrix-oci-containers config)
(match-record config <matrix-configuration> (domain server-name data-path)
(list (oci-container-configuration
(provision "conduit")
(image "registry.gitlab.com/famedly/conduit/matrix-conduit:v0.6.0")
;; We can't use %matrix-user, since the container's internal user
;; has UID 1000, and that's already taken on the host system.
(container-user (number->string %matrix-uid))
(network "host") ; allow access to localhost-bound conduit port
;; https://gitlab.com/famedly/conduit/-/blob/next/docker/README.md
;; https://gitlab.com/famedly/conduit/-/blob/next/conduit-example.toml
(environment `(("CONDUIT_CONFIG" . "") ; use only env vars
("CONDUIT_SERVER_NAME" . ,(maybe-value server-name domain))
("CONDUIT_ADDRESS" . "127.0.0.1")
("CONDUIT_PORT" . ,(number->string %conduit-port))
("CONDUIT_DATABASE_BACKEND" . "rocksdb")
("CONDUIT_ALLOW_REGISTRATION" . "false")
("CONDUIT_ALLOW_FEDERATION" . "false")
("CONDUIT_ALLOW_CHECK_FOR_UPDATES" . "false")
("CONDUIT_ENABLE_LIGHTNING_BOLT" . "false")
("CONDUIT_MAX_REQUEST_SIZE" . "100_000_000")
("CONDUIT_TRUSTED_SERVERS" . "[\"matrix.org\"]")))
(volumes `((,(string-append data-path "/conduit") . "/var/lib/matrix-conduit")))))))
(define (matrix-accounts config)
(match-record config <matrix-configuration> (data-path)
(list (user-account
(name %matrix-user)
(uid %matrix-uid)
(group "nogroup")
(comment "Matrix server user")
(system? #t)
(home-directory data-path)
(shell (file-append shadow "/sbin/nologin"))))))
(define (matrix-well-known-nginx-locations config)
(match-record config <matrix-configuration> (domain)
(list (nginx-location-configuration
(uri "/.well-known/matrix/server")
(body `(("return 200 '{\"m.server\": \"" ,domain "\"}';")
"types { } default_type \"application/json; charset=utf-8\";")))
(nginx-location-configuration
(uri "/.well-known/matrix/client")
(body `("return 200 '{\"m.homeserver\": {\"base_url\": \"https://matrix.twilken.net\"}}';"
"types { } default_type \"application/json; charset=utf-8\";"
"add_header \"Access-Control-Allow-Origin\" *;"))))))
(define (matrix-reverse-proxy config)
(match-record config <matrix-configuration> (domain)
;; https://gitlab.com/famedly/conduit/-/blob/next/DEPLOY.md#nginx
(list (nginx-server-configuration
(listen '("443 ssl http2" "8448 ssl http2"))
(server-name (list domain))
(ssl-certificate (string-append "/etc/letsencrypt/live/" domain "/fullchain.pem"))
(ssl-certificate-key (string-append "/etc/letsencrypt/live/" domain "/privkey.pem"))
(server-tokens? #f)
(locations
(list (nginx-location-configuration
(uri "/_matrix")
(body `(("proxy_pass http://127.0.0.1:"
,(number->string %conduit-port) "$request_uri;")
"proxy_set_header Host $http_host;"
"proxy_buffering off;"
"proxy_read_timeout 5m;")))))))))
(define (matrix-certificates config)
(match-record config <matrix-configuration> (domain)
(list (certificate-configuration
(domains (list domain))
(deploy-hook %nginx-cert-deploy-hook)))))
(define matrix-service-type
(service-type
(name 'matrix)
(extensions
(list (service-extension oci-container-service-type matrix-oci-containers)
(service-extension account-service-type matrix-accounts)
;; Synapse can't access certbot certs, but nginx can, so proxy HTTPS
;; access through. Also, it's good to have Synapse available on :443.
(service-extension nginx-service-type matrix-reverse-proxy)
(service-extension certbot-service-type matrix-certificates)))
(default-value (matrix-configuration))
(description "Run a matrix server with various bridges.")))
|