Ansible Domo
Going for an Esperanto naming theme.
Portable Ansible provisioning for Twirre infrastructure. The current layout uses Ubuntu 24.04 package names, /srv for deployed services, /etc for config, and systemd-managed apps, so it will not work on Debian without adjustment.
What this provisions
- Base host packages, timezone, and static content roots
- SSH admin users with key-based login
- A dedicated
backupagentuser for rsync-based backups with restricted SSH settings and passwordlesssudo /usr/bin/rsync - Docker from distro packages
- Bun installed to
/opt/bunwith/usr/local/bin/bun - The
twirre.ioBun app service - The
twirre.meRust binary service from a GitHub Release asset - Gitea and Docker Mailserver as Compose stacks under
/srv - nginx virtual hosts for the retained public domains
- apt-based certbot with ACME webroot support
- WireGuard with
wg-quick@wg0enabled at boot - fail2ban with the audit-derived SSH jail settings
Layout
site.yml: top-level playbookinventory/hosts.yml: example inventorygroup_vars/all/main.yml: shared variables and service declarationsgroup_vars/all/vault.example.yml: secrets shape to move into an encrypted Vault fileroles/: reusable server roles
Secrets
Create an encrypted Vault file at group_vars/all/vault.yml based on group_vars/all/vault.example.yml. The playbook will use Vault variables when present and otherwise fall back to safe placeholders for syntax checking.
Example:
uv run ansible-vault create group_vars/all/vault.yml
Usage
Update the inventory and variables first, especially:
inventory/hosts.ymlgroup_vars/all/main.ymlgroup_vars/all/vault.yml- repository URLs, release versions, and domains for the app services
backupagent.authorized_keys
Run a syntax check:
uv run ansible-playbook --syntax-check site.yml
Run the playbook:
uv run ansible-playbook site.yml --ask-vault-pass
Result
twirre.io: Bun source checkout in/srv/twirre/twirre.io; runtime config in/etc/twirre-io/app.env; data in/var/lib/twirre-io/app.sqlite3, public files in/var/lib/twirre-io/files, and hidden files in/var/lib/twirre-io/hfiles; systemd unittwirre_io.service.twirre.me: Rust release archive downloaded from GitHub Releases into/opt/twirre-me/releases/<version>/;/opt/twirre-me/currentpoints at the selected version; runtime config in/etc/twirre-me/app.env; data directory reserved at/var/lib/twirre-me; systemd unittwirre_me.service.Gitea: Docker Compose stack in/srv/gitea/compose.yaml; persistent application data in/srv/gitea/data; systemd unitgitea-compose.service; public HTTP behind nginx atgit.twirre.io, SSH on port2222.Mailserver: Docker Compose stack in/srv/mail/compose.yamlwith environment in/srv/mail/mailserver.env; mail data, state, logs, and docker-mailserver config under/srv/mail/docker-data/dms/; Let's Encrypt certificates mounted from/etc/letsencrypt; systemd unitmailserver-compose.service.lagrange.meulenbelt.nl: static placeholder site rooted at/srv/lagrange.map.twirre.io,chat.twirre.io, andoverleaf.twirre.io: nginx reverse proxies only; no source code or data is stored on this host for these services.- Shared web infrastructure: nginx site configs in
/etc/nginx/sites-available/with enabled symlinks in/etc/nginx/sites-enabled/; ACME webroot in/var/www/letsencrypt; certificates in/etc/letsencrypt.
Notes
- nginx falls back to snakeoil certificates until a matching ACME certificate already exists on disk.
twirre.medeploys the version declared inbinary_apps; updateversionafter publishing a matching GitHub Release asset and checksum.- A run with
certbot_manage_certificates: truerequests certificates during that playbook run. If DNS and HTTP reachability are correct, issuance happens immediately. mailserverstarts only after its live Let's Encrypt certificate exists on disk, so the same run that issuesmail.twirre.iocan also bring up Docker Mailserver.- ACME issuance is disabled by default through
certbot_manage_certificates: falseso the first provisioning run can complete before DNS and public reachability are finalized.
Manual post-provisioning steps
- Set up ACME DNS records for the domains and enable
certbot_manage_certificates: truebefore the next playbook run. - Restore backups for Gitea and Mailserver data.
Future plans
- Encryption for non-boot files with LUKS (/home, /srv, /var/lib/).
Description
Languages
Jinja
100%