matrix/example/matrix.nomad.hcl

474 lines
11 KiB
HCL

job "matrix" {
datacenters = ["dc1"]
region = "global"
group "matrix" {
network {
mode = "bridge"
}
volume "data" {
source = "matrix-synapse-data"
type = "csi"
access_mode = "single-node-writer"
attachment_mode = "file-system"
}
service {
name = "matrix"
port = 8008
meta {
alloc = "${NOMAD_ALLOC_INDEX}"
datacenter = "${NOMAD_DC}"
group = "${NOMAD_GROUP_NAME}"
job = "${NOMAD_JOB_NAME}"
namespace = "${NOMAD_NAMESPACE}"
node = "${node.unique.name}"
region = "${NOMAD_REGION}"
}
check {
type = "http"
path = "/health"
expose = true
interval = "10s"
timeout = "5s"
task = "synapse"
check_restart {
limit = 12
grace = "10m"
}
}
tags = [
"traefik.http.routers.matrix-admin.rule=Host(`matrix.consul`) && (PathPrefix(`/_admin/`) || PathPrefix(`/_synapse/admin`))",
"traefik.enable=true",
"traefik.http.routers.matrix-admin.entrypoints=https",
"traefik.http.middlewares.csp-matrix-admin.headers.contentsecuritypolicy=connect-src 'self' https://scalar.vector.im https://api.maptiler.com;default-src 'self';font-src 'self' data:;frame-src 'self' blob: https://scalar.vector.im/ https://meet.element.io;img-src 'self' data: blob: https://img.youtube.com https://*.ytimg.com;script-src 'self' https://usercontent.riot.im https://scalar.vector.im;style-src 'self' 'unsafe-inline';worker-src 'self' blob:;",
"traefik.http.routers.matrix-admin.middlewares=security-headers@file,rate-limit-std@file,forward-proto@file,inflight-std@file,hsts@file,compression@file,csp-matrix-admin",
"traefik.http.routers.matrix.rule=Host(`matrix.consul`) || (Host(`matrix.consul`) && PathRegexp(`^/(_(synapse|matrix)|\\.well-known/matrix)/.*`))",
"traefik.enable=true",
"traefik.http.routers.matrix.entrypoints=https",
"traefik.http.middlewares.csp-matrix.headers.contentsecuritypolicy=connect-src 'self' https://scalar.vector.im https://api.maptiler.com;default-src 'self';font-src 'self' data:;frame-src 'self' blob: https://scalar.vector.im/ https://meet.element.io;img-src 'self' data: blob: https://img.youtube.com https://*.ytimg.com;script-src 'self' https://usercontent.riot.im https://scalar.vector.im;style-src 'self' 'unsafe-inline';worker-src 'self' blob:;",
"traefik.http.routers.matrix.middlewares=security-headers@file,rate-limit-std@file,forward-proto@file,inflight-std@file,hsts@file,compression@file,csp-matrix",
]
connect {
sidecar_service {
proxy {
upstreams {
destination_name = "postgres"
local_bind_port = 5432
# Work arround, see https://github.com/hashicorp/nomad/issues/18538
destination_type = "service"
}
}
}
sidecar_task {
config {
args = [
"-c",
"${NOMAD_SECRETS_DIR}/envoy_bootstrap.json",
"-l",
"${meta.connect.log_level}",
"--concurrency",
"${meta.connect.proxy_concurrency}",
"--disable-hot-restart"
]
}
resources {
cpu = 50
memory = 64
}
}
}
}
# wait for required services tp be ready before starting the main task
task "wait-for" {
driver = "docker"
user = 1053
config {
image = "danielberteaud/wait-for:24.3-1"
readonly_rootfs = true
pids_limit = 20
}
lifecycle {
hook = "prestart"
}
env {
SERVICE_0 = "postgres.service.consul"
}
resources {
cpu = 10
memory = 10
memory_max = 30
}
}
task "synapse" {
driver = "docker"
leader = true
config {
image = "danielberteaud/matrix-synapse:1.103.0-1"
pids_limit = 200
readonly_rootfs = true
}
vault {
policies = ["matrix-synapse"]
env = false
disable_file = true
change_mode = "noop"
}
env {
SYNAPSE_CONFIG = "/secrets/homeserver.yml"
TMPDIR = "/data/tmp"
}
# Use a template block instead of env {} so we can fetch values from vault
template {
data = <<_EOT
LANG=fr_FR.utf8
TZ=Europe/Paris
_EOT
destination = "secrets/.env"
perms = 400
env = true
}
template {
data = <<_EOT
alias_creation_rules:
- action: allow
alias: '*'
user_id: '*'
allow_guest_access: false
allowed_avatar_mimetypes:
- image/png
- image/jpeg
- image/gif
database:
args:
database: matrix-synapse
host: 127.0.0.1
password: '{{ with secret "database/creds/matrix-synapse" }}{{ .Data.password }}{{ end }}'
port: "5432"
user: '{{ with secret "database/creds/matrix-synapse" }}{{ .Data.username }}{{ end }}'
name: psycopg2
default_identity_server: https://matrix.org
delete_stale_devices_after: 180d
email:
client_base_url: https://matrix.consul
enable_notifs: true
notif_for_new_users: true
notif_from: '%(app)s <no-reply@consul>'
require_transport_security: false
smtp_host: 127.0.0.1
smtp_port: 25
forgotten_room_retention_period: 15d
form_secret: '{{- with secret "kv/service/matrix" }}{{ .Data.data.form_secret }}{{ end }}'
listeners:
- path: /alloc/tmp/synapse.sock
resources:
- compress: false
names:
- client
- federation
type: http
log_config: /secrets/logging.conf
macaroon_secret_key: '{{- with secret "kv/service/matrix" }}{{ .Data.data.macaroon_secret_key }}{{ end }}'
max_avatar_size: 4M
media_retention:
local_media_lifetime: 730d
remote_media_lifetime: 14d
media_store_path: /data/media_store
password_config:
enabled: false
public_baseurl: https://matrix.consul
push:
include_content: event_id_only
report_stats: false
request_token_inhibit_3pid_errors: true
server_name: matrix.consul
server_notices:
system_mxid_display_name: Notification bot
system_mxid_localpart: server
signing_key_path: /data/conf/matrix.consul.signing.key
sso:
client_whitelist:
- https://matrix.consul
update_profile_information: true
suppress_key_server_warning: true
trusted_key_servers:
- server_name: matrix.org
url_preview_enabled: true
url_preview_ip_range_blacklist:
- 127.0.0.0/8
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
- 100.64.0.0/10
- 192.0.0.0/24
- 169.254.0.0/16
- 192.88.99.0/24
- 198.18.0.0/15
- 192.0.2.0/24
- 198.51.100.0/24
- 203.0.113.0/24
- 224.0.0.0/4
url_preview_url_blacklist:
- username: '*'
- netloc: ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$
web_client: false
_EOT
destination = "secrets/homeserver.yml"
uid = 100000
gid = 108008
perms = 0640
}
template {
data = <<_EOT
version: 1
formatters:
precise:
format: '%(name)s - %(lineno)d - %(levelname)s - %(request)s- %(message)s'
filters:
context:
(): synapse.util.logcontext.LoggingContextFilter
request: ""
handlers:
console:
class: logging.StreamHandler
formatter: precise
filters: [context]
loggers:
synapse.storage.SQL:
# beware: increasing this to DEBUG will make synapse log sensitive
# information such as access tokens.
level: INFO
root:
level: DEBUG
handlers: [console]
_EOT
destination = "secrets/logging.conf"
}
volume_mount {
volume = "data"
destination = "/data"
}
resources {
cpu = 500
memory = 384
}
}
task "nginx" {
driver = "docker"
config {
image = "danielberteaud/matrix-element:1.11.63-1"
readonly_rootfs = true
pids_limit = 100
volumes = [
"local/nginx.conf:/etc/nginx/conf.d/default.conf:ro",
]
mount {
type = "tmpfs"
target = "/tmp"
tmpfs_options {
size = 5000000
}
}
}
template {
data = <<_EOT
upstream synapse {
server unix:/alloc/tmp/synapse.sock;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 127.0.0.1:8008 default_server;
server_tokens off;
root /opt/element;
index index.html;
include /etc/nginx/mime.types;
default_type application/octet-stream;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_socket_keepalive on;
proxy_buffering off;
proxy_request_buffering off;
client_max_body_size 100m;
set_real_ip_from 127.0.0.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
location /_matrix {
proxy_pass http://synapse;
proxy_read_timeout 600;
}
location /_synapse {
proxy_pass http://synapse;
proxy_read_timeout 600;
}
location = /health {
access_log off;
proxy_pass http://synapse;
}
location /index.html {
add_header Cache-Control "no-cache";
}
location /version {
add_header Cache-Control "no-cache";
}
location /config.json {
add_header Cache-Control "no-cache";
alias /local/element.json;
}
location /.well-known/matrix/server {
add_header Access-Control-Allow-Origin *;
default_type application/json;
expires 6h;
return 200 '{"m.server": "matrix.consul:443"}';
}
location /.well-known/matrix/client {
add_header Access-Control-Allow-Origin *;
default_type application/json;
expires 6h;
return 200 '{"m.homeserver": {"base_url": "https://matrix.consul"}}';
}
# Expose synapse admin
location /_admin/ {
alias /opt/synapse-admin/;
expires 30d;
}
# default files
location / {
expires 30d;
}
}
_EOT
destination = "local/nginx.conf"
}
template {
data = <<_EOT
{
"default_server_config": {
"m.homeserver": {
"base_url": "https://matrix.consul",
"server_name": "matrix.consul"
},
"m.identity_server": {
"base_url": "https://vector.im"
}
},
"brand": "Element",
"integrations_ui_url": "https://scalar.vector.im/",
"integrations_rest_url": "https://scalar.vector.im/api",
"integrations_widgets_urls": [
"https://scalar.vector.im/_matrix/integrations/v1",
"https://scalar.vector.im/api",
"https://scalar-staging.vector.im/_matrix/integrations/v1",
"https://scalar-staging.vector.im/api",
"https://scalar-staging.element.im/scalar/api"
],
"show_labs_settings": true,
"roomDirectory": {
"servers": [
"matrix.org"
]
},
"disable_guests": true,
"settingDefaults": {
"UIFeature.feedback": false,
"UIFeature.thirdPartyId": false
},
"map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx",
"happyJson": true
}
_EOT
destination = "local/element.json"
}
resources {
cpu = 20
memory = 16
}
}
}
}