feat: element/matrix added, a lot of small improvements

krasovs.ky b08350ff 39e09b70

verified
+15 -9
README.md
···
- VM can be fully removed and re-provisioned within 3 minutes, including container autostart.
- Provisioning of everything is done using Terraform/OpenTofu.
- Secrets are provided using Bitwarden Secrets Manager.
-
- Source IP is preserved using [systemd socket activation](https://github.com/eriksjolund/podman-networking-docs?tab=readme-ov-file#socket-activation-systemd-user-service) mechanism.
- Native network performance due to the reason above.
- Stores Podman and application data on dedicated iSCSI disk.
- Stores media and downloads on NFS share.
···
I also have some observability:
-
- Storage: VictoriaMetrics and VictoriaLogs.
-
- Scrapping and writing: Grafana Alloy.
-
- Visualization: Grafana.
-
- Traces are not supported for now.
## Current services
···
|-----------------------------------------|--------------------------------------------|-----|
| Actual Budget | Budgeting App | |
| Bluesky PDS | ATProto Personal Data Server | |
| Glance | Homelab Dashboard | |
| Grafana | Data-visualization Platform | |
| Grafana Alloy | OpenTelemetry Collector | |
| Davmail | Exchange to IMAP/SMTP Gateway | |
| Karakeep | Bookmark App | ☑️ |
| Immich | Image & Video Management | ☑️ |
| Miniflux | RSS Reader | ☑️ |
| OAuth2 Proxy | Identity-Aware Proxy | |
| OpenCloud | File Management and Collaboration platform | ☑️ |
···
| Tangled Knot | Git Platform based on ATProto | |
| Telegraf | Only for MQTT to OpenTelemetry conversion | |
| Traefik | Application Proxy | |
-
| Tuwunel | Matrix Homeserver | |
| Gatus | Uptime Monitoring[^1] | |
| VictoriaMetrics / VictoriaLogs / vmauth | Metrics and Logs Storage | ☑️ |
···
## Future plans
-
- [x] Move Traefik, Grafana Alloy and other configs to the repository.
- [ ] Consider switching to Flatcar Linux. Personally I like it more, but in the current version they didn't ship
-
`i915` driver, which is a dealbreaker for me. However, it's [already merged](https://github.com/flatcar/scripts/pull/2349)
-
and will soon be available in the Alpha channel.
- [x] Monitor uptime and setup alerts with Uptime Kuma.
- [ ] Harden network setup; for now it's pretty permissive.
- [ ] Integrate `hashicorp/assert` support.
···
- VM can be fully removed and re-provisioned within 3 minutes, including container autostart.
- Provisioning of everything is done using Terraform/OpenTofu.
- Secrets are provided using Bitwarden Secrets Manager.
+
- Source IP is preserved
+
using [systemd socket activation](https://github.com/eriksjolund/podman-networking-docs?tab=readme-ov-file#socket-activation-systemd-user-service)
+
mechanism.
- Native network performance due to the reason above.
- Stores Podman and application data on dedicated iSCSI disk.
- Stores media and downloads on NFS share.
···
I also have some observability:
+
- Storage: VictoriaMetrics and VictoriaLogs.
+
- Scrapping and writing: Grafana Alloy.
+
- Visualization: Grafana.
+
- Traces are not supported for now.
## Current services
···
|-----------------------------------------|--------------------------------------------|-----|
| Actual Budget | Budgeting App | |
| Bluesky PDS | ATProto Personal Data Server | |
+
| Element Web | Element Web Client | |
+
| Element Call | Element Call Client | |
| Glance | Homelab Dashboard | |
| Grafana | Data-visualization Platform | |
| Grafana Alloy | OpenTelemetry Collector | |
| Davmail | Exchange to IMAP/SMTP Gateway | |
| Karakeep | Bookmark App | ☑️ |
| Immich | Image & Video Management | ☑️ |
+
| Matrix | Matrix Homeserver | ☑️ |
+
| MatrixRTC | Matrix Realtime Stack | ☑️ |
| Miniflux | RSS Reader | ☑️ |
| OAuth2 Proxy | Identity-Aware Proxy | |
| OpenCloud | File Management and Collaboration platform | ☑️ |
···
| Tangled Knot | Git Platform based on ATProto | |
| Telegraf | Only for MQTT to OpenTelemetry conversion | |
| Traefik | Application Proxy | |
| Gatus | Uptime Monitoring[^1] | |
| VictoriaMetrics / VictoriaLogs / vmauth | Metrics and Logs Storage | ☑️ |
···
## Future plans
+
- [x] Move Traefik, Grafana Alloy and other configs to the repository.
- [ ] Consider switching to Flatcar Linux. Personally I like it more, but in the current version they didn't ship
+
`i915` driver, which is a dealbreaker for me. However,
+
it's [already merged](https://github.com/flatcar/scripts/pull/2349)
+
and will soon be available in the Alpha channel.
- [x] Monitor uptime and setup alerts with Uptime Kuma.
- [ ] Harden network setup; for now it's pretty permissive.
- [ ] Integrate `hashicorp/assert` support.
+5
butane/fcos.yml.tftpl
···
tcp dport 8465 accept
tcp dport 8636 accept
# allow plex
tcp dport 32400 accept
udp dport 1900 accept
···
tcp dport 8465 accept
tcp dport 8636 accept
+
# allow livekit
+
udp dport 59900-60000 accept
+
udp dport 3478 accept
+
tcp dport 7881 accept
+
# allow plex
tcp dport 32400 accept
udp dport 1900 accept
+54 -5
configs/alloy/config.alloy
···
format = "json"
}
discovery.docker "fcos" {
host = "unix:///var/run/docker.sock"
}
···
loki.process "copy_msg" {
forward_to = [loki.write.victoria_logs.receiver]
-
// Bluesky logs plain json, so we need to manually remap msg to _msg.
stage.match {
selector = "{_msg=\"\"}"
-
stage.json {
-
expressions = { "msg" = "" }
}
-
stage.labels {
-
values = { "_msg" = "msg" }
}
}
}
···
targets = [
{ __address__ = "host.containers.internal:9558" },
{ __address__ = "prometheus-podman-exporter:9882" },
{ __address__ = "rmqtt:6060", __metrics_path__ = "/api/v1/metrics/prometheus" },
]
forward_to = [prometheus.remote_write.victoria_metrics.receiver]
···
format = "json"
}
+
livedebugging {
+
enabled = true
+
}
+
discovery.docker "fcos" {
host = "unix:///var/run/docker.sock"
}
···
loki.process "copy_msg" {
forward_to = [loki.write.victoria_logs.receiver]
+
// Some services require to manually remap message field to _msg.
stage.match {
selector = "{_msg=\"\"}"
+
stage.match {
+
selector = "{container_name=\"/synapse\"}"
+
+
stage.json {
+
expressions = { "log" = "" }
+
}
+
+
stage.labels {
+
values = { "_msg" = "log" }
+
}
+
}
+
+
stage.match {
+
selector = "{container_name=\"/grafana\"}"
+
+
stage.json {
+
expressions = { "msg" = "" }
+
}
+
+
stage.labels {
+
values = { "_msg" = "msg" }
+
}
+
}
+
+
stage.match {
+
selector = "{container_name=\"/grafana-alloy\"}"
+
+
stage.json {
+
expressions = { "msg" = "" }
+
}
+
+
stage.labels {
+
values = { "_msg" = "msg" }
+
}
}
+
stage.match {
+
selector = "{container_name=\"/bluesky-pds\"}"
+
+
stage.json {
+
expressions = { "msg" = "" }
+
}
+
+
stage.labels {
+
values = { "_msg" = "msg" }
+
}
}
}
}
···
targets = [
{ __address__ = "host.containers.internal:9558" },
{ __address__ = "prometheus-podman-exporter:9882" },
+
{ __address__ = "immich:8081" },
+
{ __address__ = "immich:8082" },
+
{ __address__ = "opencloud:9205" },
+
{ __address__ = "opencloud:9304" },
+
{ __address__ = "synapse:9000" },
{ __address__ = "rmqtt:6060", __metrics_path__ = "/api/v1/metrics/prometheus" },
]
forward_to = [prometheus.remote_write.victoria_metrics.receiver]
+28
configs/containers/systemd/element-call.container.tftpl
···
···
+
[Unit]
+
Description=Element Call Quadlet
+
+
[Container]
+
Image=ghcr.io/element-hq/element-call:v0.16.0
+
AutoUpdate=registry
+
ContainerName=element-call
+
+
User=1000:1000
+
UserNS=keep-id:uid=1000,gid=1000
+
+
Label="glance.parent=element-web"
+
Label="glance.name=Element Call"
+
Label="glance.hide=false"
+
+
Label="traefik.enable=true"
+
Label="traefik.http.routers.element-call.rule=Host(`call.element.${base_domain}`)"
+
+
Volume=%E/element/call.json:/app/config.json:Z
+
+
Network=reverse-proxy.network
+
+
[Service]
+
TimeoutStartSec=900
+
Restart=always
+
+
[Install]
+
WantedBy=multi-user.target default.target
+31
configs/containers/systemd/element-web.container.tftpl
···
···
+
[Unit]
+
Description=Element Web Quadlet
+
+
[Container]
+
Image=docker.io/vectorim/element-web:latest
+
AutoUpdate=registry
+
ContainerName=element-web
+
+
User=1000:1000
+
UserNS=keep-id:uid=1000,gid=1000
+
+
Label="glance.id=element-web"
+
Label="glance.name=Element"
+
Label="glance.icon=di:element"
+
Label="glance.url=https://element.${base_domain}"
+
Label="glance.description=Matrix web client"
+
Label="glance.hide=false"
+
+
Label="traefik.enable=true"
+
Label="traefik.http.routers.element-web.rule=Host(`element.${base_domain}`)"
+
+
Volume=%E/element/web.json:/app/config.json:Z
+
+
Network=reverse-proxy.network
+
+
[Service]
+
TimeoutStartSec=900
+
Restart=always
+
+
[Install]
+
WantedBy=multi-user.target default.target
+9 -2
configs/containers/systemd/grafana-alloy.container.tftpl
···
Label="glance.description=OpenTelemetry Collector"
Label="glance.hide=false"
-
Exec=run --storage.path=/var/lib/alloy/data --disable-reporting /etc/alloy/config.alloy
Volume=%E/alloy/config.alloy:/etc/alloy/config.alloy:Z
Volume=%t/podman/podman.sock:/var/run/docker.sock
···
Restart=always
[Install]
-
WantedBy=multi-user.target default.target
···
Label="glance.description=OpenTelemetry Collector"
Label="glance.hide=false"
+
Exec=run --server.http.listen-addr=0.0.0.0:12345 --storage.path=/var/lib/alloy/data --disable-reporting /etc/alloy/config.alloy
+
+
Label="traefik.enable=true"
+
Label="traefik.http.routers.grafana-alloy.rule=Host(`alloy.${base_domain}`)"
+
Label="traefik.http.routers.grafana-alloy.middlewares=oauth2-proxy@file"
+
Label="traefik.http.services.grafana-alloy.loadbalancer.server.port=12345"
+
Label="traefik.http.routers.grafana-alloy-auth.rule=Host(`alloy.${base_domain}`) && PathPrefix(`/oauth2/`)"
+
Label="traefik.http.routers.grafana-alloy-auth.service=oauth2-proxy"
Volume=%E/alloy/config.alloy:/etc/alloy/config.alloy:Z
Volume=%t/podman/podman.sock:/var/run/docker.sock
···
Restart=always
[Install]
+
WantedBy=multi-user.target default.target
+1
configs/containers/systemd/immich/immich-server.container.tftpl
···
User=1000:1000
GroupAdd=keep-groups
Environment=IMMICH_MEDIA_LOCATION=/usr/src/app/upload
Environment=TZ=Europe/Belgrade
Environment=DB_HOSTNAME=immich-postgres
···
User=1000:1000
GroupAdd=keep-groups
+
Environment=IMMICH_TELEMETRY_INCLUDE=all
Environment=IMMICH_MEDIA_LOCATION=/usr/src/app/upload
Environment=TZ=Europe/Belgrade
Environment=DB_HOSTNAME=immich-postgres
+35
configs/containers/systemd/matrix-rtc/matrix-rtc-jwt.container.tftpl
···
···
+
[Unit]
+
Description=MatrixRTC Authorization Service Quadlet
+
+
[Container]
+
Image=ghcr.io/element-hq/lk-jwt-service:0.3.0
+
AutoUpdate=registry
+
ContainerName=matrix-rtc-jwt
+
+
User=1000:1000
+
+
Environment=LIVEKIT_URL=wss://matrix-rtc.${base_domain}/livekit/sfu
+
Environment=LIVEKIT_JWT_PORT=9090
+
Environment=LIVEKIT_FULL_ACCESS_HOMESERVERS=${base_domain}
+
Secret=matrix-rtc-livekit-key,type=env,target=LIVEKIT_KEY
+
Secret=matrix-rtc-livekit-secret,type=env,target=LIVEKIT_SECRET
+
+
Label="glance.parent=matrix-rtc"
+
Label="glance.name=MatrixRTC Authorization Service"
+
Label="glance.hide=false"
+
+
Label="traefik.enable=true"
+
Label="traefik.http.routers.matrix-rtc-jwt.rule=Host(`matrix-rtc.${base_domain}`) && PathPrefix(`/livekit/jwt`)"
+
Label="traefik.http.routers.matrix-rtc-jwt.middlewares=strip-jwt-prefix"
+
Label="traefik.http.middlewares.strip-jwt-prefix.stripprefix.prefixes=/livekit/jwt"
+
Label="traefik.http.services.matrix-rtc-jwt.loadbalancer.server.port=9090"
+
+
Pod=matrix-rtc.pod
+
+
[Service]
+
TimeoutStartSec=900
+
Restart=always
+
+
[Install]
+
WantedBy=multi-user.target default.target
+
+43
configs/containers/systemd/matrix-rtc/matrix-rtc-sfu.container.tftpl
···
···
+
[Unit]
+
Description=MatrixRTC Livekit Quadlet
+
Wants=matrix-rtc-valkey.service
+
After=matrix-rtc-valkey.service
+
+
[Container]
+
Image=docker.io/livekit/livekit-server:v1.9
+
AutoUpdate=registry
+
ContainerName=matrix-rtc-sfu
+
+
User=1000:1000
+
+
Label="glance.id=matrix-rtc"
+
Label="glance.icon=di:matrix-light"
+
Label="glance.description=Matrix Realtime Stack"
+
Label="glance.name=MatrixRTC"
+
Label="glance.hide=false"
+
+
Label="traefik.enable=true"
+
Label="traefik.http.routers.matrix-rtc-sfu.rule=Host(`matrix-rtc.${base_domain}`) && PathPrefix(`/livekit/sfu`)"
+
Label="traefik.http.routers.matrix-rtc-sfu.middlewares=strip-sfu-prefix"
+
Label="traefik.http.middlewares.strip-sfu-prefix.stripprefix.prefixes=/livekit/sfu"
+
Label="traefik.http.services.matrix-rtc-sfu.loadbalancer.server.port=7880"
+
+
Label="traefik.tcp.routers.matrix-rtc-turn.rule=HostSNI(`turn.${base_domain}`)"
+
Label="traefik.tcp.routers.matrix-rtc-turn.tls=true"
+
Label="traefik.tcp.routers.matrix-rtc-turn.tls.certresolver=leresolver"
+
Label="traefik.tcp.routers.matrix-rtc-turn.service=matrix-rtc-turn"
+
Label="traefik.tcp.services.matrix-rtc-turn.loadbalancer.server.port=5349"
+
+
Exec=--config /etc/livekit.yaml
+
+
Volume=%E/matrix-rtc/livekit.yaml:/etc/livekit.yaml:Z
+
+
Pod=matrix-rtc.pod
+
+
[Service]
+
TimeoutStartSec=900
+
Restart=always
+
+
[Install]
+
WantedBy=multi-user.target default.target
+
+27
configs/containers/systemd/matrix-rtc/matrix-rtc-valkey.container.tftpl
···
···
+
[Unit]
+
Description=MatrixRTC Valkey Quadlet
+
+
[Container]
+
Image=docker.io/valkey/valkey:8-alpine
+
AutoUpdate=registry
+
ContainerName=matrix-rtc-valkey
+
+
User=1000:1000
+
+
Label="glance.parent=matrix-rtc"
+
Label="glance.name=Valkey"
+
Label="glance.hide=false"
+
+
HealthCmd=valkey-cli ping || exit 1
+
+
Volume=/var/mnt/docker/app_data/matrix-rtc/valkey:/data:Z
+
+
Pod=matrix-rtc.pod
+
Notify=healthy
+
+
[Service]
+
TimeoutStartSec=900
+
Restart=always
+
+
[Install]
+
WantedBy=multi-user.target default.target
+34
configs/containers/systemd/matrix/matrix-authentication-service.container.tftpl
···
···
+
[Unit]
+
Description=Matrix Authencation Service Quadlet
+
Wants=matrix-postgres.service
+
After=matrix-postgres.service
+
+
[Container]
+
Image=ghcr.io/element-hq/matrix-authentication-service:1.4
+
AutoUpdate=registry
+
ContainerName=matrix-authentication-service
+
+
User=1000:1000
+
+
Label="glance.parent=matrix"
+
Label="glance.name=Matrix Authentication Service"
+
Label="glance.hide=false"
+
+
Label="traefik.enable=true"
+
Label="traefik.http.routers.matrix-authentication-service.rule=Host(`matrix-account.${base_domain}`) || (Host(`matrix.${base_domain}`) && PathRegexp(`^/_matrix/client/(.*)/(login|logout|refresh)`))"
+
Label="traefik.http.services.matrix-authentication-service.loadbalancer.server.port=8080"
+
+
Exec=--config /data/config.yaml
+
+
Volume=%E/matrix/mas.yaml:/data/config.yaml:Z
+
Volume=/var/mnt/docker/app_data/matrix/mas:/data:Z
+
+
Pod=matrix.pod
+
+
[Service]
+
TimeoutStartSec=900
+
Restart=always
+
+
[Install]
+
WantedBy=multi-user.target default.target
+
+33
configs/containers/systemd/matrix/matrix-postgres.container.tftpl
···
···
+
[Unit]
+
Description=Matrix Postgres Quadlet
+
+
[Container]
+
Image=docker.io/postgres:18-bookworm
+
AutoUpdate=registry
+
ContainerName=matrix-postgres
+
+
User=1000:1000
+
+
Environment=POSTGRES_USER=synapse
+
Environment=POSTGRES_DB=synapse
+
Environment=POSTGRES_INITDB_ARGS="--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
+
Secret=synapse-postgres-password,type=env,target=POSTGRES_PASSWORD
+
+
Label="glance.parent=matrix"
+
Label="glance.name=Postgres"
+
Label="glance.hide=false"
+
+
HealthCmd=pg_isready --dbname="$$${POSTGRES_DB}" --username="$$${POSTGRES_USER}" || exit 1;
+
HealthStartupInterval=5s
+
+
Volume=/var/mnt/docker/app_data/matrix/postgres:/var/lib/postgresql/data:Z
+
+
Pod=matrix.pod
+
Notify=healthy
+
+
[Service]
+
TimeoutStartSec=900
+
Restart=always
+
+
[Install]
+
WantedBy=multi-user.target default.target
+35
configs/containers/systemd/matrix/matrix-synapse.container.tftpl
···
···
+
[Unit]
+
Description=Matrix Synapse Quadlet
+
Wants=matrix-valkey.service matrix-postgres.service
+
After=matrix-valkey.service matrix-postgres.service
+
+
[Container]
+
Image=docker.io/matrixdotorg/synapse:v1.140.0
+
AutoUpdate=registry
+
ContainerName=matrix-synapse
+
+
User=1000:1000
+
+
Label="glance.id=matrix"
+
Label="glance.name=Matrix"
+
Label="glance.icon=di:matrix-light"
+
Label="glance.description=Matrix Homeserver"
+
Label="glance.hide=false"
+
+
Label="traefik.enable=true"
+
Label="traefik.http.routers.matrix-synapse.rule=Host(`matrix.${base_domain}`)"
+
Label="traefik.http.services.matrix-synapse.loadbalancer.server.port=8008"
+
+
Volume=%E/matrix/homeserver.yaml:/data/homeserver.yaml:Z
+
Volume=%E/matrix/log.config:/data/${base_domain}.log.config:Z
+
Volume=/var/mnt/docker/app_data/matrix/synapse:/data:Z
+
+
Pod=matrix.pod
+
+
[Service]
+
TimeoutStartSec=900
+
Restart=always
+
+
[Install]
+
WantedBy=multi-user.target default.target
+
+27
configs/containers/systemd/matrix/matrix-valkey.container.tftpl
···
···
+
[Unit]
+
Description=Matrix Valkey Quadlet
+
+
[Container]
+
Image=docker.io/valkey/valkey:8-alpine
+
AutoUpdate=registry
+
ContainerName=matrix-valkey
+
+
User=1000:1000
+
+
Label="glance.parent=matrix"
+
Label="glance.name=Valkey"
+
Label="glance.hide=false"
+
+
HealthCmd=valkey-cli ping || exit 1
+
+
Volume=/var/mnt/docker/app_data/matrix/valkey:/data:Z
+
+
Pod=matrix.pod
+
Notify=healthy
+
+
[Service]
+
TimeoutStartSec=900
+
Restart=always
+
+
[Install]
+
WantedBy=multi-user.target default.target
+1
configs/containers/systemd/networks/matrix-rtc.network
···
···
+
[Network]
+1
configs/containers/systemd/networks/matrix.network
···
···
+
[Network]
+1
configs/containers/systemd/opencloud/opencloud-collaboration.container.tftpl
···
Environment=OC_URL="https://cloud.${base_domain}"
Environment=COLLABORATION_GRPC_ADDR=0.0.0.0:9301
Environment=COLLABORATION_HTTP_ADDR=0.0.0.0:9300
Environment=COLLABORATION_WOPI_SRC=https://wopiserver.${base_domain}
Environment=COLLABORATION_APP_NAME=CollaboraOnline
Environment=COLLABORATION_APP_PRODUCT=Collabora
···
Environment=OC_URL="https://cloud.${base_domain}"
Environment=COLLABORATION_GRPC_ADDR=0.0.0.0:9301
Environment=COLLABORATION_HTTP_ADDR=0.0.0.0:9300
+
Environment=COLLABORATION_DEBUG_ADDR=0.0.0.0:9304
Environment=COLLABORATION_WOPI_SRC=https://wopiserver.${base_domain}
Environment=COLLABORATION_APP_NAME=CollaboraOnline
Environment=COLLABORATION_APP_PRODUCT=Collabora
+4 -1
configs/containers/systemd/pocket-id.container.tftpl
···
UserNS=keep-id:uid=1000,gid=1000
Environment=APP_URL=https://id.${base_domain}
Secret=pocket-id-maxmind-license-key,type=env,target=MAXMIND_LICENSE_KEY
Label="glance.name=Pocket ID"
···
Label="traefik.enable=true"
Label="traefik.http.routers.pocket-id.rule=Host(`id.${base_domain}`)"
-
Label="traefik.http.routers.pocket-id.service=pocket-id"
Volume=/var/mnt/docker/app_data/pocket-id:/app/data:Z
···
UserNS=keep-id:uid=1000,gid=1000
Environment=APP_URL=https://id.${base_domain}
+
Environment=METRICS_ENABLED=true
+
Environment=OTEL_LOGS_EXPORTER=otlp
+
Environment=OTEL_EXPORTER_OTLP_ENDPOINT=http://grafana-alloy:4317
+
Environment=OTEL_EXPORTER_OTLP_PROTOCOL=grpc
Secret=pocket-id-maxmind-license-key,type=env,target=MAXMIND_LICENSE_KEY
Label="glance.name=Pocket ID"
···
Label="traefik.enable=true"
Label="traefik.http.routers.pocket-id.rule=Host(`id.${base_domain}`)"
Volume=/var/mnt/docker/app_data/pocket-id:/app/data:Z
+1
configs/containers/systemd/pods/immich.pod
···
PodName=immich
UserNS=keep-id:uid=1000,gid=1000
Network=immich.network
···
PodName=immich
UserNS=keep-id:uid=1000,gid=1000
Network=immich.network
+
Network=reverse-proxy.network
+7
configs/containers/systemd/pods/matrix-rtc.pod
···
···
+
[Unit]
+
Description=MatrixRTC Pod
+
+
[Pod]
+
PodName=matrix-rtc
+
UserNS=keep-id:uid=1000,gid=1000
+
Network=host
+8
configs/containers/systemd/pods/matrix.pod
···
···
+
[Unit]
+
Description=Matrix Pod
+
+
[Pod]
+
PodName=matrix
+
UserNS=keep-id:uid=1000,gid=1000
+
Network=matrix.network
+
Network=reverse-proxy.network
+1
configs/containers/systemd/pods/opencloud.pod
···
PodName=opencloud
UserNS=keep-id:uid=1000,gid=1000
Network=opencloud.network
···
PodName=opencloud
UserNS=keep-id:uid=1000,gid=1000
Network=opencloud.network
+
Network=reverse-proxy.network
+1 -1
configs/containers/systemd/tangled.container.tftpl
···
Description=Tangled Knot Quadlet
[Container]
-
Image=ghcr.io/savely-krasovsky/knot-docker:v1.9.0-alpha
AutoUpdate=registry
ContainerName=tangled
···
Description=Tangled Knot Quadlet
[Container]
+
Image=ghcr.io/savely-krasovsky/knot-docker:1.9.1-alpha
AutoUpdate=registry
ContainerName=tangled
-46
configs/containers/systemd/tuwunel.container.tftpl
···
-
[Unit]
-
Description=Tuwunel Quadlet
-
Requires=podman.socket
-
After=podman.socket
-
-
[Container]
-
Image=ghcr.io/matrix-construct/tuwunel:latest
-
AutoUpdate=registry
-
ContainerName=tuwunel
-
-
User=1000:1000
-
UserNS=keep-id:uid=1000,gid=1000
-
-
Environment=TUWUNEL_CONFIG=
-
Environment=TUWUNEL_SERVER_NAME=${base_domain}
-
Environment=TUWUNEL_DATABASE_PATH=/var/lib/tuwunel/
-
Environment=TUWUNEL_ADDRESS=0.0.0.0
-
Environment=TUWUNEL_PORT=6167
-
Environment=TUWUNEL_ALLOW_FEDERATION=true
-
Environment=TUWUNEL_ALLOW_REGISTRATION=true
-
Environment=TUWUNEL_LOG=info
-
Environment=TUWUNEL_TURN_URIS="[\"turn:turn.${base_domain}?transport=udp\", \"turn:turn.${base_domain}?transport=tcp\"]"
-
Environment=TUWUNEL_ALLOW_LEGACY_MEDIA=true
-
Secret=tuwunel-registration-token,type=env,target=TUWUNEL_REGISTRATION_TOKEN
-
Secret=tuwunel-turn-secret,type=env,target=TUWUNEL_TURN_SECRET
-
-
Label="glance.name=Tuwunel"
-
Label="glance.icon=di:matrix-light"
-
Label="glance.description=Matrix Homeserver"
-
Label="glance.hide=false"
-
-
Label="traefik.enable=true"
-
Label="traefik.http.routers.tuwunel.rule=Host(`matrix.${base_domain}`)"
-
Label="traefik.http.services.tuwunel.loadbalancer.server.port=6167"
-
-
Volume=/var/mnt/docker/app_data/tuwunel:/var/lib/tuwunel/:Z
-
-
Network=reverse-proxy.network
-
-
[Service]
-
TimeoutStartSec=900
-
Restart=always
-
-
[Install]
-
WantedBy=multi-user.target default.target
-
···
+22
configs/element/call.json.tftpl
···
···
+
{
+
"default_server_config": {
+
"m.homeserver": {
+
"base_url": "https://matrix.${base_domain}",
+
"server_name": "${base_domain}"
+
}
+
},
+
"livekit": {
+
"livekit_service_url": "https://matrix-rtc.${base_domain}/livekit/jwt"
+
},
+
"features": {
+
"feature_use_device_session_member_events": true
+
},
+
"ssla": "https://static.element.io/legal/element-software-and-services-license-agreement-uk-1.pdf",
+
"matrix_rtc_session": {
+
"wait_for_key_rotation_ms": 3000,
+
"membership_event_expiry_ms": 180000000,
+
"delayed_leave_event_delay_ms": 18000,
+
"delayed_leave_event_restart_ms": 4000,
+
"network_error_retry_ms": 100
+
}
+
}
+67
configs/element/web.json.tftpl
···
···
+
{
+
"default_server_name": "${base_domain}",
+
"default_server_config": {
+
"m.homeserver": {
+
"base_url": "https://matrix.${base_domain}"
+
},
+
"m.identity_server": {
+
"base_url": "https://vector.im"
+
},
+
"org.matrix.msc2965.authentication": {
+
"issuer": "https://matrix-account.${base_domain}/",
+
"account": "https://matrix-account.${base_domain}/account/"
+
},
+
"org.matrix.msc4143.rtc_foci": [
+
{
+
"type": "livekit",
+
"livekit_service_url": "https://matrix-rtc.${base_domain}/livekit/jwt"
+
}
+
]
+
},
+
"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"
+
],
+
"bug_report_endpoint_url": "https://element.io/bugreports/submit",
+
"uisi_autorageshake_app": "element-auto-uisi",
+
"show_labs_settings": false,
+
"room_directory": {
+
"servers": ["matrix.org", "gitter.im"]
+
},
+
"enable_presence_by_hs_url": {
+
"https://matrix.org": false,
+
"https://matrix-client.matrix.org": false
+
},
+
"terms_and_conditions_links": [
+
{
+
"url": "https://element.io/privacy",
+
"text": "Privacy Policy"
+
},
+
{
+
"url": "https://element.io/cookie-policy",
+
"text": "Cookie Policy"
+
}
+
],
+
"posthog": {
+
"project_api_key": "phc_Jzsm6DTm6V2705zeU5dcNvQDlonOR68XvX2sh1sEOHO",
+
"api_host": "https://posthog.element.io"
+
},
+
"privacy_policy_url": "https://element.io/cookie-policy",
+
"map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx",
+
"setting_defaults": {
+
"RustCrypto.staged_rollout_percent": 60
+
},
+
"features": {
+
"feature_video_rooms": true,
+
"feature_group_calls": true,
+
"feature_element_call_video_rooms": true
+
},
+
"element_call": {
+
"url": "https://call.element.krasovs.ky"
+
}
+
}
+23
configs/matrix-rtc/livekit.yaml.tftpl
···
···
+
port: 7880
+
log_level: info
+
+
rtc:
+
tcp_port: 7881
+
port_range_start: 59900
+
port_range_end: 60000
+
use_external_ip: true
+
+
redis:
+
address: localhost:6379
+
+
turn:
+
enabled: true
+
domain: turn.${base_domain}
+
udp_port: 3478
+
tls_port: 5349
+
relay_range_start: 59000
+
relay_range_end: 59100
+
external_tls: true
+
+
keys:
+
${secrets.matrix_rtc_livekit_key}: ${secrets.matrix_rtc_livekit_secret}
+78
configs/matrix/homeserver.yaml.tftpl
···
···
+
server_name: "${base_domain}"
+
pid_file: /data/homeserver.pid
+
web_client_location: "https://element.${base_domain}"
+
public_baseurl: "https://matrix.${base_domain}"
+
listeners:
+
- port: 8008
+
tls: false
+
type: http
+
x_forwarded: true
+
resources:
+
- names: [client, federation]
+
compress: false
+
- port: 9000
+
type: metrics
+
+
database:
+
name: psycopg2
+
args:
+
user: synapse
+
password: ${secrets.synapse_postgres_password}
+
dbname: synapse
+
host: matrix-postgres
+
cp_min: 5
+
cp_max: 10
+
+
redis:
+
enabled: true
+
host: matrix-valkey
+
port: 6379
+
+
log_config: "/data/${base_domain}.log.config"
+
media_store_path: /data/media_store
+
registration_shared_secret: "${secrets.synapse_registration_shared_secret}"
+
report_stats: false
+
macaroon_secret_key: "${secrets.synapse_macaroon_secret_key}"
+
form_secret: "${secrets.synapse_form_secret}"
+
signing_key_path: "/data/${base_domain}.signing.key"
+
trusted_key_servers:
+
- server_name: "matrix.org"
+
+
turn_uris: [ "turn:turn.${base_domain}?transport=udp", "turn:turn.${base_domain}?transport=tcp" ]
+
turn_shared_secret: "${secrets.coturn_turn_shared_secret}"
+
turn_user_lifetime: 86400000
+
turn_allow_guests: false
+
+
password_config:
+
enabled: false
+
+
matrix_authentication_service:
+
enabled: true
+
endpoint: http://matrix-authentication-service:8080/
+
secret: ${secrets.matrix_authentication_service_secret}
+
+
enable_metrics: true
+
+
# Support Element Call
+
experimental_features:
+
# MSC3266: Room summary API. Used for knocking over federation
+
msc3266_enabled: true
+
# MSC4222 needed for syncv2 state_after. This allow clients to
+
# correctly track the state of the room.
+
msc4222_enabled: true
+
+
# The maximum allowed duration by which sent events can be delayed, as
+
# per MSC4140.
+
max_event_delay_duration: 24h
+
+
rc_message:
+
# This needs to match at least e2ee key sharing frequency plus a bit of headroom
+
# Note key sharing events are bursty
+
per_second: 0.5
+
burst_count: 30
+
+
rc_delayed_event_mgmt:
+
# This needs to match at least the heart-beat frequency plus a bit of headroom
+
# Currently the heart-beat is every 5 seconds which translates into a rate of 0.2s
+
per_second: 1
+
burst_count: 20
+24
configs/matrix/log.config
···
···
+
version: 1
+
+
formatters:
+
structured:
+
class: synapse.logging.TerseJsonFormatter
+
+
handlers:
+
console:
+
class: logging.StreamHandler
+
formatter: structured
+
+
loggers:
+
# This is just here so we can leave `loggers` in the config regardless of whether
+
# we configure other loggers below (avoid empty yaml dict error).
+
_placeholder:
+
level: "INFO"
+
synapse.storage.SQL:
+
level: INFO
+
+
root:
+
level: INFO
+
handlers: [console]
+
+
disable_existing_loggers: false
+88
configs/matrix/mas.yaml.tftpl
···
···
+
http:
+
public_base: https://matrix-account.${base_domain}/
+
listeners:
+
- name: web
+
resources:
+
- name: discovery
+
- name: human
+
- name: oauth
+
- name: compat
+
- name: graphql
+
- name: assets
+
binds:
+
- address: '[::]:8080'
+
proxy_protocol: false
+
- name: internal
+
resources:
+
- name: health
+
binds:
+
- host: localhost
+
port: 8081
+
proxy_protocol: false
+
trusted_proxies:
+
- 192.168.0.0/16
+
- 172.16.0.0/12
+
- 10.0.0.0/10
+
- 127.0.0.1/8
+
- fd00::/8
+
- ::1/128
+
+
database:
+
uri: "postgresql://synapse:${secrets.synapse_postgres_password}@matrix-postgres/mas"
+
max_connections: 10
+
min_connections: 0
+
connect_timeout: 30
+
idle_timeout: 600
+
max_lifetime: 1800
+
+
email:
+
from: '"Matrix Authentication Service" <noreply+matrix@krasovs.ky>'
+
reply_to: '"Matrix Authentication Service" <noreply+matrix@krasovs.ky>'
+
transport: smtp
+
mode: tls
+
hostname: smtps-proxy.fastmail.com
+
port: 443
+
username: savely@${base_domain}
+
password: ${secrets.matrix_authentication_service_smtp_password}
+
+
secrets:
+
encryption: ${secrets.matrix_authentication_service_secrets_encryption}
+
keys:
+
- key: |
+
${indent(6, secrets.matrix_authentication_service_secrets_rsa_key)}
+
- key: |
+
${indent(6, secrets.matrix_authentication_service_secrets_p256_key)}
+
- key: |
+
${indent(6, secrets.matrix_authentication_service_secrets_p384_key)}
+
- key: |
+
${indent(6, secrets.matrix_authentication_service_secrets_secp256k1_key)}
+
+
passwords:
+
enabled: false
+
+
matrix:
+
kind: synapse
+
homeserver: ${base_domain}
+
secret: ${secrets.matrix_authentication_service_secret}
+
endpoint: https://matrix.${base_domain}/
+
+
upstream_oauth2:
+
providers:
+
- id: 01K7WMWMAB8M7J0HR3S5FM5DR2
+
synapse_idp_id: oidc-pocket-id
+
issuer: "https://id.${base_domain}"
+
human_name: "Pocket ID"
+
client_id: "c6e8a96b-647f-47fe-8e75-2b05a6c79242"
+
client_secret: "${secrets.synapse_oidc_client_secret}"
+
token_endpoint_auth_method: client_secret_basic
+
scope: "email openid profile"
+
claims_imports:
+
localpart:
+
action: require
+
template: '{{ user.preferred_username }}'
+
displayname:
+
action: force
+
template: '{{ user.name }}'
+
email:
+
action: force
+
template: "{{ user.email }}"
+71 -8
fcos.tf
···
id = var.containers_secret_config.immich_map_key
}
locals {
// Add secrets into quadlets config
containers_config = merge(var.containers_config, {
proxmox_ip : var.proxmox_config.host,
truenas_ip : var.fcos_config.truenas_ip,
secrets : {
vmauth_traefik_bearer_token : data.bitwarden_secret.vmauth_traefik_bearer_token.value
vmauth_proxmox_bearer_token : data.bitwarden_secret.vmauth_proxmox_bearer_token.value
immich_map_key : data.bitwarden_secret.immich_map_key.value
}
})
···
butane_config = merge(var.fcos_config, {
config_files : local.config_files
-
config_dirs : local.config_dirs,
})
config_rendered_files = {
···
data "ct_config" "fcos_ignition" {
content = templatefile("${path.module}/butane/fcos.yml.tftpl", local.butane_config)
-
strict = true
}
resource "proxmox_virtual_environment_vm" "fcos" {
-
node_name = "pve"
-
name = "fcos"
description = "Managed by OpenTofu"
lifecycle {
···
}
provisioner "remote-exec" {
-
inline = ["sh /tmp/init.sh"]
on_failure = fail
}
}
···
}
connection {
-
type = "ssh"
-
user = "core"
private_key = file(pathexpand(var.fcos_config.ssh_private_key_path))
-
host = var.fcos_config.ip
}
// Create directories if not exist
···
id = var.containers_secret_config.immich_map_key
}
+
// Matrix secrets
+
data "bitwarden_secret" "coturn_turn_shared_secret" {
+
id = var.containers_secret_config.coturn_turn_shared_secret
+
}
+
data "bitwarden_secret" "synapse_postgres_password" {
+
id = var.containers_secret_config.synapse_postgres_password
+
}
+
data "bitwarden_secret" "synapse_registration_shared_secret" {
+
id = var.containers_secret_config.synapse_registration_shared_secret
+
}
+
data "bitwarden_secret" "synapse_macaroon_secret_key" {
+
id = var.containers_secret_config.synapse_macaroon_secret_key
+
}
+
data "bitwarden_secret" "synapse_form_secret" {
+
id = var.containers_secret_config.synapse_form_secret
+
}
+
data "bitwarden_secret" "synapse_oidc_client_secret" {
+
id = var.containers_secret_config.synapse_oidc_client_secret
+
}
+
data "bitwarden_secret" "matrix_authentication_service_secret" {
+
id = var.containers_secret_config.matrix_authentication_service_secret
+
}
+
data "bitwarden_secret" "matrix_authentication_service_secrets_encryption" {
+
id = var.containers_secret_config.matrix_authentication_service_secrets_encryption
+
}
+
data "bitwarden_secret" "matrix_authentication_service_secrets_rsa_key" {
+
id = var.containers_secret_config.matrix_authentication_service_secrets_rsa_key
+
}
+
data "bitwarden_secret" "matrix_authentication_service_secrets_p256_key" {
+
id = var.containers_secret_config.matrix_authentication_service_secrets_p256_key
+
}
+
data "bitwarden_secret" "matrix_authentication_service_secrets_p384_key" {
+
id = var.containers_secret_config.matrix_authentication_service_secrets_p384_key
+
}
+
data "bitwarden_secret" "matrix_authentication_service_secrets_secp256k1_key" {
+
id = var.containers_secret_config.matrix_authentication_service_secrets_secp256k1_key
+
}
+
data "bitwarden_secret" "matrix_authentication_service_smtp_password" {
+
id = var.containers_secret_config.matrix_authentication_service_smtp_password
+
}
+
data "bitwarden_secret" "matrix_rtc_livekit_key" {
+
id = var.containers_secret_config.matrix_rtc_livekit_key
+
}
+
data "bitwarden_secret" "matrix_rtc_livekit_secret" {
+
id = var.containers_secret_config.matrix_rtc_livekit_secret
+
}
+
locals {
// Add secrets into quadlets config
containers_config = merge(var.containers_config, {
proxmox_ip : var.proxmox_config.host,
truenas_ip : var.fcos_config.truenas_ip,
+
fcos_ip : var.fcos_config.ip,
secrets : {
vmauth_traefik_bearer_token : data.bitwarden_secret.vmauth_traefik_bearer_token.value
vmauth_proxmox_bearer_token : data.bitwarden_secret.vmauth_proxmox_bearer_token.value
immich_map_key : data.bitwarden_secret.immich_map_key.value
+
coturn_turn_shared_secret : data.bitwarden_secret.coturn_turn_shared_secret.value
+
synapse_postgres_password : data.bitwarden_secret.synapse_postgres_password.value
+
synapse_registration_shared_secret : data.bitwarden_secret.synapse_registration_shared_secret.value
+
synapse_macaroon_secret_key : data.bitwarden_secret.synapse_macaroon_secret_key.value
+
synapse_form_secret : data.bitwarden_secret.synapse_form_secret.value
+
synapse_oidc_client_secret : data.bitwarden_secret.synapse_oidc_client_secret.value
+
matrix_authentication_service_secret : data.bitwarden_secret.matrix_authentication_service_secret.value
+
matrix_authentication_service_secrets_encryption : data.bitwarden_secret.matrix_authentication_service_secrets_encryption.value
+
matrix_authentication_service_secrets_rsa_key : data.bitwarden_secret.matrix_authentication_service_secrets_rsa_key.value
+
matrix_authentication_service_secrets_p256_key : data.bitwarden_secret.matrix_authentication_service_secrets_p256_key.value
+
matrix_authentication_service_secrets_p384_key : data.bitwarden_secret.matrix_authentication_service_secrets_p384_key.value
+
matrix_authentication_service_secrets_secp256k1_key : data.bitwarden_secret.matrix_authentication_service_secrets_secp256k1_key.value
+
matrix_authentication_service_smtp_password : data.bitwarden_secret.matrix_authentication_service_smtp_password.value
+
matrix_rtc_livekit_key : data.bitwarden_secret.matrix_rtc_livekit_key.value
+
matrix_rtc_livekit_secret : data.bitwarden_secret.matrix_rtc_livekit_secret.value
}
})
···
butane_config = merge(var.fcos_config, {
config_files : local.config_files
+
config_dirs : local.config_dirs,
})
config_rendered_files = {
···
data "ct_config" "fcos_ignition" {
content = templatefile("${path.module}/butane/fcos.yml.tftpl", local.butane_config)
+
strict = true
}
resource "proxmox_virtual_environment_vm" "fcos" {
+
node_name = "pve"
+
name = "fcos"
description = "Managed by OpenTofu"
lifecycle {
···
}
provisioner "remote-exec" {
+
inline = ["sh /tmp/init.sh"]
on_failure = fail
}
}
···
}
connection {
+
type = "ssh"
+
user = "core"
private_key = file(pathexpand(var.fcos_config.ssh_private_key_path))
+
host = var.fcos_config.ip
}
// Create directories if not exist
+73 -59
variables.tf
···
variable "bws_access_token" {
description = "Bitwarden Secrets CLI access token"
-
type = string
-
sensitive = true
}
variable "proxmox_config" {
description = "Proxmox credentials"
type = object({
-
host = string
password_secret_id = string
})
}
···
variable "containers_config" {
description = "Shared configuration"
type = object({
-
email = string
base_domain = string
-
ews_domain = string
})
}
variable "containers_secret_config" {
description = "Quadlet Ssecret"
-
type = map(string)
default = {
-
traefik_cf_dns_api_token = "e9e0f0f0-abc8-4bde-b05f-b292018179bb"
-
vmauth_traefik_bearer_token = "fba802cf-948f-4ff7-8965-b29f00e2da48"
-
vmauth_proxmox_bearer_token = "bb281df0-e5e8-4348-a92e-b2a300a30117"
-
oauth2_proxy_cookie_secret = "289c0832-27c2-463b-97b7-b29200a8cebd"
-
oauth2_proxy_client_secret = "afdb8ef2-a3d4-4a17-b839-b29200ab6f87"
-
pocket_id_maxmind_license_key = "08c549a4-bf48-4998-8cb0-b29200ac845d"
-
actual_budget_openid_client_secret = "5754702b-d9d5-4127-b5ab-b29200abdd6a"
-
open_webui_secret_key = "aeeb7cdd-d10e-41d4-abb4-b33300dabc1a"
-
open_webui_oauth_client_secret = "b595040b-a23a-44af-8bff-b29200ad6258"
-
open_webui_google_drive_api_key = "d24bf77b-622d-4ef0-88ae-b2b200d67ee1"
-
open_webui_anthropic_api_key = "104a349b-a4be-4d3a-9c0b-b2c700e64c9a"
-
open_webui_google_api_key = "3016f3ef-c14c-4f4c-8439-b2c700e62f21"
-
open_webui_openai_api_key = "24fd45e2-0fd3-42cd-8fd5-b2c700e66731"
-
karakeep_oauth_client_secret = "784d379b-bcaf-424f-bc77-b29500ff1be6"
-
karakeep_openai_api_key = "98f5ccdf-d4b1-4883-b4e3-b295010ba589"
-
meili_master_key = "a67874c5-95c2-4f7a-b335-b295010010e0"
-
nextauth_secret = "94b4b746-f005-46e0-b60a-b29501010c06"
-
immich_postgres_password = "386f1adc-878f-4755-a06b-b29700b15cd0"
-
immich_map_key = "b5735614-bc05-441d-a2e2-b29800d3b25c"
-
miniflux_postgres_password = "1c6a587e-9dda-47de-953a-b29a01697231"
-
miniflux_database_url = "456f8488-cdeb-4246-959d-b29a016be9ac"
-
miniflux_oauth2_client_secret = "3bb3cedd-1ee4-4624-b865-b29a016c2318"
-
pds_jwt_secret = "b9dfaefd-3083-4e2f-a23f-b29a017db774"
-
pds_admin_password = "00e810b5-6d8b-4342-8189-b29a017dca5e"
-
pds_plc_rotation_key_k256_private_key_hex = "e0825e62-8d49-4b4a-99cd-b29a017def90"
-
pds_email_smtp_url = "5a940d99-28cb-4792-9825-b29a017e11ad"
-
outline_secret_key = "501e040c-5574-4058-a0c0-b29d01010c09"
-
outline_utils_secret = "b032948f-bce3-46bb-bd26-b29d01012dde"
-
outline_database_url = "5887f243-6332-4041-8457-b29d0104be2e"
-
outline_postgres_password = "4212e3a7-acd3-4804-ac0e-b29d01015850"
-
outline_oidc_client_secret = "9c8cae9a-db6d-45d0-8cc0-b29d0101844c"
-
outline_smtp_password = "5fdbfb32-257e-4cc3-8b07-b29d01063ba6"
-
grafana_oauth2_client_secret = "697cf367-a80c-41f6-b975-b2a200a986d8"
-
glance_github_token = "de3353d8-09d9-4063-b513-b2a3008cc2c9"
-
tangled_knot_server_secret = "a58caac0-1c07-4152-89e6-b2a900c8fe8f"
-
forward_info_bot_telegram_token = "f8eda775-f945-4eb8-b48a-b2b80092cf54"
-
restic_aws_access_key_id = "2743cf63-05ae-45b4-997f-b2c700dfabef"
-
restic_aws_secret_access_key = "134279a9-b3ee-4309-ae9e-b2c700dfe86c"
-
restic_b2_account_id = "3e058bd3-e13d-4b6a-9d48-b2c700e00d62"
-
restic_b2_account_key = "ddc2f07b-47ca-49b2-ae41-b2c700e02f01"
-
restic_password = "52ce5eb2-98ae-4243-ba08-b2c700e04b7e"
-
opencloud_collabora_password = "bced1168-9741-4b8e-abf4-b2d4000e2c9e"
-
opencloud_smtp_password = "5e0889ac-3b11-4fc4-81ca-b2d400170e85"
-
simplex_smp_pass = "ebc8a3cb-4b85-44d6-b61c-b33800e45456"
-
simplex_xftp_pass = "c6feec9d-2622-4322-acbf-b338013f79e9"
-
tuwunel-turn-secret = "5b69585c-03e8-454f-94e0-b357000002d4"
-
tuwunel-registration-token = "92e470e2-c88e-43d3-ae0c-b3570039c4c9"
}
}
···
type = object({
hostname = string
ssh_keys = list(string)
-
root_ca = string
mac_address = string
-
ip = string
-
gateway = string
-
mask = string
-
nameserver = string
-
truenas_ip = string
truenas_iqn = string
# To sync configs afterwards
···
variable "bws_access_token" {
description = "Bitwarden Secrets CLI access token"
+
type = string
+
sensitive = true
}
variable "proxmox_config" {
description = "Proxmox credentials"
type = object({
+
host = string
password_secret_id = string
})
}
···
variable "containers_config" {
description = "Shared configuration"
type = object({
+
email = string
base_domain = string
+
ews_domain = string
})
}
variable "containers_secret_config" {
description = "Quadlet Ssecret"
+
type = map(string)
default = {
+
traefik_cf_dns_api_token = "e9e0f0f0-abc8-4bde-b05f-b292018179bb"
+
vmauth_traefik_bearer_token = "fba802cf-948f-4ff7-8965-b29f00e2da48"
+
vmauth_proxmox_bearer_token = "bb281df0-e5e8-4348-a92e-b2a300a30117"
+
oauth2_proxy_cookie_secret = "289c0832-27c2-463b-97b7-b29200a8cebd"
+
oauth2_proxy_client_secret = "afdb8ef2-a3d4-4a17-b839-b29200ab6f87"
+
pocket_id_maxmind_license_key = "08c549a4-bf48-4998-8cb0-b29200ac845d"
+
actual_budget_openid_client_secret = "5754702b-d9d5-4127-b5ab-b29200abdd6a"
+
open_webui_secret_key = "aeeb7cdd-d10e-41d4-abb4-b33300dabc1a"
+
open_webui_oauth_client_secret = "b595040b-a23a-44af-8bff-b29200ad6258"
+
open_webui_google_drive_api_key = "d24bf77b-622d-4ef0-88ae-b2b200d67ee1"
+
open_webui_anthropic_api_key = "104a349b-a4be-4d3a-9c0b-b2c700e64c9a"
+
open_webui_google_api_key = "3016f3ef-c14c-4f4c-8439-b2c700e62f21"
+
open_webui_openai_api_key = "24fd45e2-0fd3-42cd-8fd5-b2c700e66731"
+
karakeep_oauth_client_secret = "784d379b-bcaf-424f-bc77-b29500ff1be6"
+
karakeep_openai_api_key = "98f5ccdf-d4b1-4883-b4e3-b295010ba589"
+
meili_master_key = "a67874c5-95c2-4f7a-b335-b295010010e0"
+
nextauth_secret = "94b4b746-f005-46e0-b60a-b29501010c06"
+
immich_postgres_password = "386f1adc-878f-4755-a06b-b29700b15cd0"
+
immich_map_key = "b5735614-bc05-441d-a2e2-b29800d3b25c"
+
miniflux_postgres_password = "1c6a587e-9dda-47de-953a-b29a01697231"
+
miniflux_database_url = "456f8488-cdeb-4246-959d-b29a016be9ac"
+
miniflux_oauth2_client_secret = "3bb3cedd-1ee4-4624-b865-b29a016c2318"
+
pds_jwt_secret = "b9dfaefd-3083-4e2f-a23f-b29a017db774"
+
pds_admin_password = "00e810b5-6d8b-4342-8189-b29a017dca5e"
+
pds_plc_rotation_key_k256_private_key_hex = "e0825e62-8d49-4b4a-99cd-b29a017def90"
+
pds_email_smtp_url = "5a940d99-28cb-4792-9825-b29a017e11ad"
+
outline_secret_key = "501e040c-5574-4058-a0c0-b29d01010c09"
+
outline_utils_secret = "b032948f-bce3-46bb-bd26-b29d01012dde"
+
outline_database_url = "5887f243-6332-4041-8457-b29d0104be2e"
+
outline_postgres_password = "4212e3a7-acd3-4804-ac0e-b29d01015850"
+
outline_oidc_client_secret = "9c8cae9a-db6d-45d0-8cc0-b29d0101844c"
+
outline_smtp_password = "5fdbfb32-257e-4cc3-8b07-b29d01063ba6"
+
grafana_oauth2_client_secret = "697cf367-a80c-41f6-b975-b2a200a986d8"
+
glance_github_token = "de3353d8-09d9-4063-b513-b2a3008cc2c9"
+
tangled_knot_server_secret = "a58caac0-1c07-4152-89e6-b2a900c8fe8f"
+
forward_info_bot_telegram_token = "f8eda775-f945-4eb8-b48a-b2b80092cf54"
+
restic_aws_access_key_id = "2743cf63-05ae-45b4-997f-b2c700dfabef"
+
restic_aws_secret_access_key = "134279a9-b3ee-4309-ae9e-b2c700dfe86c"
+
restic_b2_account_id = "3e058bd3-e13d-4b6a-9d48-b2c700e00d62"
+
restic_b2_account_key = "ddc2f07b-47ca-49b2-ae41-b2c700e02f01"
+
restic_password = "52ce5eb2-98ae-4243-ba08-b2c700e04b7e"
+
opencloud_collabora_password = "bced1168-9741-4b8e-abf4-b2d4000e2c9e"
+
opencloud_smtp_password = "5e0889ac-3b11-4fc4-81ca-b2d400170e85"
+
simplex_smp_pass = "ebc8a3cb-4b85-44d6-b61c-b33800e45456"
+
simplex_xftp_pass = "c6feec9d-2622-4322-acbf-b338013f79e9"
+
tuwunel_registration_token = "92e470e2-c88e-43d3-ae0c-b3570039c4c9"
+
coturn_turn_shared_secret = "5b69585c-03e8-454f-94e0-b357000002d4"
+
synapse_postgres_password = "2209bd8d-f6a7-43e0-afa8-b37a00bbfd2c"
+
synapse_registration_shared_secret = "9dab9863-5dac-4748-a1fc-b37a0145f7f1"
+
synapse_macaroon_secret_key = "cfa20ae3-8103-46be-a129-b37a014627aa"
+
synapse_form_secret = "c11840ef-11f0-40c7-a08e-b37a0146564f"
+
synapse_oidc_client_secret = "6e0f179f-631c-480c-b9ec-b37a0146e95c"
+
matrix_rtc_livekit_key = "5c336187-6139-413b-bbf1-b37a01588b03"
+
matrix_rtc_livekit_secret = "a24e0995-d297-4c23-849f-b37a0158a5d4"
+
matrix_authentication_service_secret = "bcaa7f79-c9fc-4448-9c79-b37a016954f5"
+
matrix_authentication_service_secrets_encryption = "012d8da3-3f7c-471a-b9cb-b37b0001dc1b"
+
matrix_authentication_service_secrets_rsa_key = "c2c1d0d3-1c80-4c36-961e-b37b000049ca"
+
matrix_authentication_service_secrets_p256_key = "8a19b557-c518-43f7-90a8-b37b0000b7c6"
+
matrix_authentication_service_secrets_p384_key = "557701bc-7430-4dc8-98ae-b37b0000e3c1"
+
matrix_authentication_service_secrets_secp256k1_key = "a6624b6b-1f2c-4883-94dd-b37b00010dc9"
+
matrix_authentication_service_smtp_password = "e25452b1-480c-4581-b407-b37b00042943"
}
}
···
type = object({
hostname = string
ssh_keys = list(string)
+
root_ca = string
mac_address = string
+
ip = string
+
gateway = string
+
mask = string
+
nameserver = string
+
truenas_ip = string
truenas_iqn = string
# To sync configs afterwards