- Python 49.2%
- JavaScript 22.6%
- Jinja 16.5%
- Sass 6.2%
- Go 2.7%
- Other 2.7%
|
All checks were successful
Pipelines as Code CI / glitches-chat-deploy Success
|
||
|---|---|---|
| .tekton | ||
| roles/server_config | ||
| .gitignore | ||
| ansible.cfg | ||
| inventory.ini | ||
| justfile | ||
| README.md | ||
| site.yml | ||
| vault_pass.sh | ||
glitches.chat — Ansible
Manages the full server stack for glitches.chat: a self-hosted Matrix homeserver and accompanying services, all configured and deployed with a single playbook.
Stack
| Service | What it does |
|---|---|
| tuwunel (conduwuit fork) | Matrix homeserver |
| Caddy | Reverse proxy / TLS termination |
| LiveKit | WebRTC SFU for Element Call |
| lk-jwt-service | LiveKit JWT token service for Matrix clients |
| coturn | TURN/STUN server for VoIP / WebRTC fallback |
| matrix‑hookshot | Webhook bridge for external services (GitHub, GitLab, etc.) |
| valkey | Encrypted key‑value store service |
| Element Web | Matrix web client |
Prerequisites
- Ansible installed on the server
become: trueaccess (sudo)- Podman installed with systemd quadlet support
- Existing Caddy config at
/etc/caddythat includes/etc/caddy/sites-enabled/ - coturn installed
Running
# Dry-run (check mode)
ansible-playbook -i inventory.ini site.yml -K --ask-vault-pass --check
# Apply everything
ansible-playbook -i inventory.ini site.yml -K --ask-vault-pass
# Apply a specific component only
ansible-playbook -i inventory.ini site.yml -K --ask-vault-pass --tags <tag>
-Kprompts for your sudo password (become: trueis required to write system files).
CI deploy
Pipelines-as-Code deploys on pushes to main using .tekton/deploy.yaml.
Create or refresh the deploy secret in the same namespace as the PipelineRun:
set -a
. ./.env
set +a
kubectl -n glitches-chat-pipelines create secret generic glitches-chat-deploy \
--from-file=ssh-privatekey="$HOME/.ssh/shephard" \
--from-file=BECOME_PASS=<(printf '%s' "$BECOME_PASS") \
--from-file=vault-password=<(./vault_pass.sh) \
--dry-run=client -o yaml | kubectl apply -f -
The pipeline mounts ssh-privatekey as the Ansible SSH key, uses BECOME_PASS
as the become password file, and uses vault-password for Ansible Vault. The
racknerd-2 host and user are defined in inventory.ini.
Container notes
The stack is managed with system-level Podman quadlets in
/etc/containers/systemd/. Config files, quadlet files, and host data
directories are prepared before services are started. Container images are
pulled before startup, tuwunel is checked at /_matrix/client/versions, and
Caddy is checked for a local HTTPS listener before the play continues.
Existing data stays in place. tuwunel keeps using tuwunel_db_path
(/var/lib/tuwunel by default). Caddy keeps using the existing /etc/caddy
configuration, certificate store, runtime config, logs, Element static files,
and Stickerpicker files through bind mounts.
The tuwunel quadlet follows the upstream Podman/systemd guidance by setting
TUWUNEL_CONFIG explicitly. This playbook keeps using a system-level quadlet in
/etc/containers/systemd/ because the rest of the stack is already managed as
rootful system services; the upstream rootless example would instead live under
~/.config/containers/systemd/ and require user lingering.
Available tags
| Tag | What it runs |
|---|---|
tuwunel |
Deploy the tuwunel quadlet container |
tuwunel-config |
Deploy tuwunel config |
caddy |
Deploy all Caddy site configs and the Caddy quadlet container |
firewall |
Install and enable UFW with SSH, web, LiveKit, and coturn ports |
livekit |
Deploy LiveKit config and quadlet containers |
coturn |
Deploy coturn config |
matrix-hookshot |
Deploy hookshot config and container |
valkey |
Deploy valkey quadlet container |
element |
Download Element Web and deploy its config |
Variables
Non-secret variables live in roles/server_config/defaults/main.yml and can be overridden per-host.
Secrets live in roles/server_config/vars/vault.yml, encrypted with Ansible Vault. Always encrypt before committing:
ansible-vault encrypt roles/server_config/vars/vault.yml
Edit an encrypted vault:
ansible-vault edit roles/server_config/vars/vault.yml
Default variables
| Variable | Description |
|---|---|
server_domain |
Primary Matrix server domain |
livekit_domain |
Domain for LiveKit / lk-jwt-service |
stun_domain |
STUN domain (typically same host as coturn) |
turn_domain_udp |
TURN domain for UDP transport |
tuwunel_version |
tuwunel container tag base ("latest" or a version string) |
tuwunel_image |
Container image for tuwunel |
tuwunel_container_service_name |
Quadlet-generated tuwunel service name |
tuwunel_address |
Listen address for the homeserver |
tuwunel_port |
Listen port for the homeserver |
tuwunel_db_path |
RocksDB data directory |
tuwunel_new_user_displayname_suffix |
Suffix appended to new user display names |
tuwunel_rocksdb_repair |
Set true to attempt a DB repair on next start |
caddy_image |
Container image for Caddy |
caddy_container_service_name |
Quadlet-generated Caddy service name |
caddy_config_dir |
Existing Caddy config directory mounted into the container |
caddy_data_dir |
Existing Caddy certificate/data directory mounted into the container |
caddy_config_data_dir |
Existing Caddy runtime config data directory mounted into the container |
caddy_log_dir |
Existing Caddy log directory mounted into the container |
firewall_ssh_port |
SSH port allowed through UFW |
firewall_allowed_rules |
UFW allow rules for public service ports |
livekit_bind_address |
LiveKit bind address |
livekit_port |
LiveKit HTTP/WebSocket port |
livekit_rtc_tcp_port |
LiveKit RTC TCP port |
livekit_rtc_port_range_start |
Start of LiveKit UDP port range |
livekit_rtc_port_range_end |
End of LiveKit UDP port range |
livekit_image |
Podman image for the LiveKit container |
lk_jwt_port |
Port for lk-jwt-service |
lk_jwt_image |
Podman image for lk-jwt-service |
lk_jwt_full_access_homeservers |
Homeservers allowed full LiveKit access |
element_domain |
Domain serving Element Web |
element_version |
Element Web release to deploy ("latest" or a version string) |
coturn_listening_ip |
coturn bind IP |
coturn_listening_port |
coturn UDP/TCP listening port |
coturn_tls_port |
coturn TLS listening port |
coturn_min_port |
Start of coturn relay port range |
coturn_max_port |
End of coturn relay port range |
coturn_cert_dir |
Directory containing TLS cert/key for coturn |
matrix_hookshot_version |
Container image tag for matrix-hookshot |
matrix_hookshot_image |
Fully qualified container image name |
matrix_hookshot_encryption_path |
Path to store encryption files (enables encryption) |
valkey_port |
Port valkey listens on |
valkey_bind_address |
Address valkey binds to |
valkey_version |
Container image tag for valkey |
Vault variables
| Variable | Used in |
|---|---|
vault_turn_secret |
tuwunel config, LiveKit config, coturn config |
vault_livekit_api_key |
LiveKit config, lk-jwt-service container |
vault_livekit_api_secret |
LiveKit config, lk-jwt-service container |
conduwuit_registration_token |
tuwunel config (open registration token) |
Files managed
| Destination | Template |
|---|---|
/etc/tuwunel/tuwunel.toml |
tuwunel.toml.j2 |
/etc/containers/systemd/tuwunel-container.container |
tuwunel-container.container.j2 |
/etc/caddy/sites-available/conduwuit_caddyfile |
tuwunel_caddyfile.j2 |
/etc/caddy/sites-available/livekit_caddyfile |
livekit_caddyfile.j2 |
/etc/caddy/sites-available/element_caddyfile |
element_caddyfile.j2 |
/etc/containers/systemd/caddy-container.container |
caddy-container.container.j2 |
/etc/livekit/livekit.yaml |
livekit.yaml.j2 |
/etc/containers/systemd/livekit.container |
livekit.container.j2 |
/etc/containers/systemd/lk-jwt-service.container |
lk-jwt-service.container.j2 |
/etc/containers/systemd/matrix-hookshot.container |
matrix-hookshot.container.j2 |
/etc/matrix-hookshot/matrix_hookshot.yml |
matrix_hookshot.yml.j2 |
/etc/matrix-hookshot/passkey.pem |
auto‑generated RSA key (if missing) |
/etc/containers/systemd/valkey.container |
valkey.container.j2 |
/var/www/element/config.json |
element-config.json.j2 |
/etc/turnserver/turnserver.conf |
turnserver.conf.j2 |