2022-06-12 15:39:15 +00:00
{
nix-packages ,
system ,
config ,
pkgs ,
lib ,
. . .
} : let
2023-06-13 05:46:23 +00:00
inherit ( pkgs ) matrix-media-repo ;
2022-06-12 15:39:15 +00:00
config-yml = pkgs . writeText " m a t r i x - m e d i a - r e p o . y a m l " ( lib . generators . toYAML { } {
2022-04-29 16:34:08 +00:00
repo = {
bindAddress = " 1 2 7 . 0 . 0 . 1 " ;
port = 8008 ;
2022-05-27 17:58:46 +00:00
logDirectory = " - " ;
2022-04-29 16:34:08 +00:00
} ;
2022-04-29 20:11:01 +00:00
database . postgres = " p o s t g r e s q l : / / / m a t r i x _ m e d i a _ r e p o ? s s l m o d e = d i s a b l e & h o s t = / r u n / p o s t g r e s q l " ;
2022-06-12 15:39:15 +00:00
homeservers = [
{
name = " m a t r i x . c h i r . r s " ;
csApi = " h t t p s : / / m a t r i x . c h i r . r s " ;
}
2022-08-26 06:30:59 +00:00
{
name = " m a t r i x . i n t . c h i r . r s " ;
csApi = " h t t p s : / / m a t r i x . c h i r . r s " ;
}
2022-06-12 15:39:15 +00:00
] ;
2023-09-15 12:58:12 +00:00
accessTokens . maxCacheTimeSeconds = 43200 ;
2022-06-12 15:39:15 +00:00
admins = [ " @ l o t t e : c h i r . r s " ] ;
datastores = [
{
type = " s 3 " ;
2023-05-23 04:55:27 +00:00
id = " b 0 0 3 b a b b b 8 6 f e c f 5 6 b b 9 b a 6 5 7 1 f 9 a d b 0 b d 1 e 7 1 c 8 " ;
2022-06-12 15:39:15 +00:00
enabled = true ;
forKinds = [ " a l l " ] ;
opts = {
2023-09-15 12:58:12 +00:00
tempPath = " / v a r / l i b / m a t r i x - m e d i a - r e p o " ;
2022-06-12 15:39:15 +00:00
endpoint = " s 3 . u s - w e s t - 0 0 0 . b a c k b l a z e b 2 . c o m " ;
accessKeyId = " # A C C E S S _ K E Y _ I D # " ;
accessSecret = " # S E C R E T _ A C C E S S _ K E Y # " ;
ssl = true ;
bucketName = " m a t r i x - c h i r - r s " ;
region = " u s - w e s t - 0 0 0 " ;
2023-09-08 11:39:34 +00:00
useMD5 = true ;
2022-06-12 15:39:15 +00:00
} ;
}
] ;
2022-05-03 09:31:27 +00:00
metrics = {
enabled = true ;
2022-05-03 15:11:04 +00:00
bindAddress = " : : " ;
2022-05-03 09:31:27 +00:00
port = 9000 ;
} ;
2022-05-27 14:27:16 +00:00
urlPreviews = {
enabled = true ;
numWorkers = 10 ;
oEmbed = true ;
2022-08-20 13:18:18 +00:00
allowedNetworks = [
" 0 . 0 . 0 . 0 / 0 "
" : : / 0 "
] ;
2022-05-27 14:27:16 +00:00
disallowedNetworks = [
" 1 2 7 . 0 . 0 . 1 / 8 "
" 1 0 . 0 . 0 . 0 / 8 "
" 1 7 2 . 1 6 . 0 . 0 / 1 2 "
" 1 9 2 . 1 6 8 . 0 . 0 / 1 6 "
" : : 1 / 1 2 8 "
" f e 8 0 : : / 6 4 "
" f c 0 0 : : / 7 "
] ;
2022-08-17 15:06:08 +00:00
userAgent = " T e l e g r a m B o t ( l i k e T w i t t e r B o t ) " ; # to make it work with fxtwitter/vxtwitter
2022-05-27 14:27:16 +00:00
} ;
2022-05-27 17:56:39 +00:00
downloads = {
expireAfterDays = 7 ;
} ;
2022-05-28 07:38:51 +00:00
featureSupport = {
2023-09-15 12:58:12 +00:00
} ;
redis = {
2022-05-28 07:38:51 +00:00
enabled = true ;
2023-09-15 12:58:12 +00:00
shards = [
{
name = " l o c a l h o s t " ;
port = " l o c a l h o s t : ${ toString config . services . redis . servers . matrix-media-repo . port } " ;
}
] ;
2022-05-28 07:38:51 +00:00
} ;
2022-05-28 07:43:59 +00:00
sentry = {
enable = true ;
dsn = " h t t p s : / / 1 8 e 3 6 e 6 f 1 6 b 5 4 9 0 c 8 3 3 6 4 1 0 1 7 1 7 c d d b a @ o 2 5 3 9 5 2 . i n g e s t . s e n t r y . i o / 6 4 4 9 2 8 3 " ;
} ;
2022-08-25 15:44:57 +00:00
thumbnails = {
maxSourceBytes = 0 ;
maxPixels = 102000000 ;
types = [
" i m a g e / j p e g "
" i m a g e / j p g "
" i m a g e / p n g "
" i m a g e / a p n g "
" i m a g e / g i f "
" i m a g e / h e i f "
" i m a g e / w e b p "
" i m a g e / s v g + x m l "
2022-08-26 09:47:45 +00:00
" i m a g e / j x l "
2022-08-25 15:44:57 +00:00
" a u d i o / m p e g "
" a u d i o / o g g "
" a u d i o / w a v "
" a u d i o / f l a c "
" v i d e o / m p 4 "
" v i d e o / w e b m "
" v i d e o / x - m a t r o s k a "
" v i d e o / q u i c k t i m e "
] ;
} ;
2022-04-29 16:34:08 +00:00
} ) ;
2022-06-12 15:39:15 +00:00
in {
networking . firewall . interfaces . " w g 0 " . allowedTCPPorts = [ 9000 ] ;
2022-04-29 16:34:08 +00:00
systemd . services . matrix-media-repo = {
description = " M a t r i x M e d i a R e p o " ;
2022-06-12 15:39:15 +00:00
after = [ " n e t w o r k . t a r g e t " ] ;
wantedBy = [ " m u l t i - u s e r . t a r g e t " ] ;
2022-08-25 15:44:57 +00:00
path = [ matrix-media-repo pkgs . ffmpeg pkgs . imagemagick ] ;
2022-04-29 16:34:08 +00:00
preStart = ''
akid = $ ( cat $ { config . sops . secrets . " s e r v i c e s / m a t r i x - m e d i a - r e p o / a c c e s s - k e y - i d " . path } )
2022-04-30 08:15:58 +00:00
sak = $ ( cat $ { config . sops . secrets . " s e r v i c e s / m a t r i x - m e d i a - r e p o / s e c r e t - a c c e s s - k e y " . path } )
2022-04-29 16:42:18 +00:00
cat $ { config-yml } > /var/lib/matrix-media-repo/config.yml
2022-04-29 16:46:43 +00:00
sed - i " s | # A C C E S S _ K E Y _ I D # | $ a k i d | g " /var/lib/matrix-media-repo/config.yml
sed - i " s | # S E C R E T _ A C C E S S _ K E Y # | $ s a k | g " /var/lib/matrix-media-repo/config.yml
2022-04-29 16:34:08 +00:00
'' ;
serviceConfig = {
Type = " s i m p l e " ;
User = " m a t r i x - m e d i a - r e p o " ;
Group = " m a t r i x - m e d i a - r e p o " ;
Restart = " a l w a y s " ;
ExecStart = " ${ matrix-media-repo } / b i n / m e d i a _ r e p o - c o n f i g / v a r / l i b / m a t r i x - m e d i a - r e p o / c o n f i g . y m l " ;
} ;
} ;
2022-11-20 14:54:52 +00:00
systemd . services . purge-old-media = {
2022-11-21 13:27:43 +00:00
path = [ pkgs . curl ] ;
2022-11-20 14:54:52 +00:00
description = " P u r g e u n u s e d m e d i a " ;
script = ''
export MATRIX_TOKEN = $ ( cat $ { config . sops . secrets . " s e r v i c e s / m a t r i x - m e d i a - r e p o / m a t r i x - t o k e n " . path } )
for i in $ ( seq 1000 ) ; do
curl - H " A u t h o r i z a t i o n : B e a r e r $ M A T R I X _ T O K E N " - X POST https://matrix.chir.rs/_matrix/media/unstable/admin/purge/old \ ? before_ts = $ ( date - d " 3 m o n t h s a g o " + % s % 3 N ) \ & include_local = true && exit 0
done
'' ;
2022-11-23 17:07:49 +00:00
2022-11-20 14:54:52 +00:00
serviceConfig = {
Type = " o n e s h o t " ;
User = " m a t r i x - m e d i a - r e p o " ;
Group = " m a t r i x - m e d i a - r e p o " ;
} ;
} ;
systemd . timers . purge-old-media = {
description = " P u r g e u n u s e d m e d i a " ;
after = [ " n e t w o r k . t a r g e t " " m a t r i x - m e d i a - r e p o . s e r v i c e " ] ;
requires = [ " p u r g e - o l d - m e d i a . s e r v i c e " ] ;
wantedBy = [ " m u l t i - u s e r . t a r g e t " ] ;
timerConfig = {
OnUnitInactiveSec = 300 ;
RandomizedDelaySec = 300 ;
} ;
} ;
2022-04-29 16:34:08 +00:00
sops . secrets . " s e r v i c e s / m a t r i x - m e d i a - r e p o / a c c e s s - k e y - i d " . owner = " m a t r i x - m e d i a - r e p o " ;
sops . secrets . " s e r v i c e s / m a t r i x - m e d i a - r e p o / s e c r e t - a c c e s s - k e y " . owner = " m a t r i x - m e d i a - r e p o " ;
2022-11-20 14:54:52 +00:00
sops . secrets . " s e r v i c e s / m a t r i x - m e d i a - r e p o / m a t r i x - t o k e n " . owner = " m a t r i x - m e d i a - r e p o " ;
2022-04-29 16:34:08 +00:00
users . users . matrix-media-repo = {
description = " M a t r i x M e d i a R e p o s i t o r y " ;
home = " / v a r / l i b / m a t r i x - m e d i a - r e p o " ;
useDefaultShell = true ;
group = " m a t r i x - m e d i a - r e p o " ;
isSystemUser = true ;
} ;
2022-06-12 15:39:15 +00:00
users . groups . matrix-media-repo = { } ;
2022-04-29 16:34:08 +00:00
systemd . tmpfiles . rules = [
" d ' / v a r / l i b / m a t r i x - m e d i a - r e p o ' 0 7 5 0 m a t r i x - m e d i a - r e p o m a t r i x - m e d i a - r e p o - - "
] ;
2022-04-29 20:00:21 +00:00
services . postgresql . ensureDatabases = [
2022-04-29 20:02:32 +00:00
" m a t r i x _ m e d i a _ r e p o "
2022-04-29 20:00:21 +00:00
] ;
2022-06-12 15:39:15 +00:00
services . postgresql . ensureUsers = [
{
name = " m a t r i x - m e d i a - r e p o " ;
ensurePermissions = {
" D A T A B A S E m a t r i x _ m e d i a _ r e p o " = " A L L P R I V I L E G E S " ;
} ;
}
] ;
2022-08-26 15:28:14 +00:00
services . caddy . virtualHosts . " m a t r i x . c h i r . r s " = {
useACMEHost = " c h i r . r s " ;
2022-12-30 13:03:57 +00:00
logFormat = pkgs . lib . mkForce " " ;
2022-08-26 15:28:14 +00:00
extraConfig = ''
import baseConfig
2023-06-11 19:18:38 +00:00
route {
handle /_matrix/media /* / d o w n l o a d / m a t r i x . c h i r . r s / d i s c o r d _ * {
header Access-Control-Allow-Origin *
# Remove path prefix
uri path_regexp ^ /_matrix/media/.+/download/matrix \ . chir \ .rs/discord_ /
# The mxc patterns use | instead of /, so replace it first turning it into attachments/1234/5678/filename.png
uri replace " % 7 C " /
reverse_proxy {
# reverse_proxy automatically includes the uri, so no {uri} at the end
to https://cdn.discordapp.com
# Caddy doesn't set the Host header automatically when reverse proxying
# (because usually reverse proxies are local and don't care about Host headers)
header_up Host cdn . discordapp . com
}
2023-06-11 17:49:46 +00:00
}
2023-06-11 19:18:38 +00:00
# Do the same for thumbnails, but redirect to media.discordapp.net (which is Discord's thumbnailing server, and happens to use similar width/height params as Matrix)
# Alternatively, you can point this at cdn.discordapp.com too. Clients shouldn't mind even if they get a bigger image than they asked for.
handle /_matrix/media /* / t h u m b n a i l / m a t r i x . c h i r . r s / d i s c o r d _ * {
header Access-Control-Allow-Origin *
uri path_regexp ^ /_matrix/media/.+/thumbnail/matrix \ . chir \ .rs/discord_ /
uri replace " % 7 C " /
reverse_proxy {
to https://media.discordapp.net
header_up Host media . discordapp . net
}
2023-06-11 17:49:46 +00:00
}
2023-06-11 19:18:38 +00:00
handle /_matrix/media /* {
uri * replace /unstable/fi.mau.msc2246 / /v1 /
reverse_proxy http://localhost:8008 {
header_down Access-Control-Allow-Origin *
header_down Access-Control-Allow-Headers *
}
2022-08-26 15:28:14 +00:00
}
2023-06-11 19:18:38 +00:00
handle /_matrix/client/v3/logout /* {
reverse_proxy http://localhost:8008
}
2022-08-26 15:28:14 +00:00
2023-06-11 19:18:38 +00:00
handle /_matrix /* {
reverse_proxy {
to https://matrix.int.chir.rs
header_up Host { upstream_hostport }
2022-08-26 15:28:14 +00:00
2023-06-11 19:18:38 +00:00
transport http {
versions 1 .1 2 3
}
2022-08-26 15:28:14 +00:00
}
}
2023-06-11 19:18:38 +00:00
handle /.well-known/matrix/server {
header Access-Control-Allow-Origin *
header Content-Type application/json
respond " { \" m . s e r v e r \" : \" m a t r i x . c h i r . r s : 4 4 3 \" } " 200
}
2022-08-26 15:28:14 +00:00
2023-06-11 19:18:38 +00:00
handle /.well-known/matrix/client {
header Access-Control-Allow-Origin *
header Content-Type application/json
2023-08-12 11:09:10 +00:00
respond " { \" m . h o m e s e r v e r \" : { \" b a s e _ u r l \" : \" h t t p s : / / m a t r i x . c h i r . r s \" } , \" o r g . m a t r i x . m s c 3 5 7 5 . p r o x y \" : { \" u r l \" : \" h t t p s : / / s l i d i n g - s y n c . c h i r . r s \" } } " 200
2023-06-11 19:18:38 +00:00
}
2022-08-26 15:28:14 +00:00
}
'' ;
2022-04-29 20:35:33 +00:00
} ;
2023-09-15 12:58:12 +00:00
services . redis . servers . matrix-media-repo = {
enable = true ;
bind = " 1 2 7 . 0 . 0 . 1 " ;
databases = 1 ;
port = 36659 ;
} ;
2022-04-29 16:34:08 +00:00
}