aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Wilken2023-12-14 20:54:57 +0100
committerTimo Wilken2023-12-14 20:54:57 +0100
commitbf94f7872a1df293bd904bbd2c1ef7229f4f98a8 (patch)
tree42a6fae2c786b9d5a6564ddf9c55e7c501d33971
parent37e8d03ba4e57e3694b4966b575986be6356726c (diff)
Run Matrix services in OCI containers
-rw-r--r--tw/services/matrix.scm131
-rw-r--r--tw/system/lud.scm37
2 files changed, 145 insertions, 23 deletions
diff --git a/tw/services/matrix.scm b/tw/services/matrix.scm
index 6b184f49..0e7cff61 100644
--- a/tw/services/matrix.scm
+++ b/tw/services/matrix.scm
@@ -1,27 +1,114 @@
(define-module (tw services matrix)
+ #:use-module (gnu)
+ #:use-module ((gnu packages admin) #:select (shadow))
#:use-module (gnu services)
- #:use-module (tw services web))
+ #: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-public %matrix-services
- (list (simple-service 'synapse-reverse-proxy https-reverse-proxy-service-type
+(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.
- (list (https-reverse-proxy-configuration
- (domains '("matrix.twilken.net"))
- (destination-port 48448))))
-
- ;; TODO: Postgres for Synapse
- ;; (service postgresql-service-type
- ;; (postgresql-configuration
- ;; (postgresql postgresql-15)
- ;; (data-directory "/var/lib/postgresql/data")))
-
- ;; (service postgresql-role-service-type
- ;; (postgresql-role-configuration
- ;; (roles (list (postgresql-role
- ;; (name "synapse") ; TODO
- ;; (create-database? #t))))))
-
- ;; TODO: Matrix/Synapse
- ;; TODO: Matrix bridges
- ))
+ (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.")))
diff --git a/tw/system/lud.scm b/tw/system/lud.scm
index a7fe67db..b4fa7729 100644
--- a/tw/system/lud.scm
+++ b/tw/system/lud.scm
@@ -1,6 +1,12 @@
(define-module (tw system lud)
#:use-module (gnu)
#:use-module (gnu bootloader grub)
+ #:use-module ((gnu services dbus)
+ #:select (dbus-root-service-type))
+ #:use-module ((gnu services desktop)
+ #:select (elogind-service-type))
+ #:use-module ((gnu services docker)
+ #:select (docker-service-type))
#:use-module (gnu system locale)
#:use-module (gnu system nss)
#:use-module (guix gexp)
@@ -28,6 +34,11 @@
(define data-partition ; /dev/sdc1
(uuid "4715ae0e-5cef-48f2-a59e-025321153888" 'btrfs))
+(define matrix-config
+ (matrix-configuration
+ (server-name "twilken.net")
+ (domain "matrix.twilken.net")))
+
(define-public %lud-system
(operating-system
(host-name "lud.twilken.net")
@@ -232,6 +243,31 @@ innodb_buffer_pool_size = 1G
innodb_io_capacity = 4000
")))
+ (service docker-service-type)
+ (service dbus-root-service-type) ; required by `docker-service-type'
+ (service elogind-service-type) ; required by `docker-service-type'
+
+ (service matrix-service-type matrix-config)
+
+ (simple-service 'homepage/matrix-well-known nginx-service-type
+ (list (nginx-server-configuration
+ (listen '("443 ssl http2"))
+ (server-name '("twilken.net"))
+ (ssl-certificate "/etc/letsencrypt/live/twilken.net/fullchain.pem")
+ (ssl-certificate-key "/etc/letsencrypt/live/twilken.net/privkey.pem")
+ (server-tokens? #f)
+ (locations
+ ;; Handle /.well-known URLs, so that I can use @*:twilken.net usernames.
+ (cons* (nginx-location-configuration
+ (uri "/")
+ (body '("return 301 https://www.twilken.net$request_uri;")))
+ (matrix-well-known-nginx-locations matrix-config))))))
+
+ (simple-service 'homepage-certificate certbot-service-type
+ (list (certificate-configuration
+ (domains '("twilken.net"))
+ (deploy-hook %nginx-cert-deploy-hook))))
+
;; TODO: JSON exporter (Nextcloud)
;; TODO: Syncthing exporter
;; TODO: Transmission exporter
@@ -257,7 +293,6 @@ innodb_io_capacity = 4000
" --fstab --verbose")))))
%nextcloud-services
- %matrix-services
(server-base-services host-name)))
;; The list of user accounts ('root' is implicit).