diff --git a/AGENTS.md b/AGENTS.md index dfdfc15..d9edb42 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -73,6 +73,7 @@ uv run ansible-galaxy install --role-file requirements.yml - `playbook-transcriber.yml` — транскрибация (образ из Yandex Registry). - `playbook-wanderer.yml` — пешие маршруты. - `playbook-remembos.yml` — интервальное повторение. +- `playbook-tuwunel.yml` — Matrix-сервер (Tuwunel) с federation-делегацией на apex-домен. ### Агрегатные и служебные diff --git a/files/caddyproxy/Caddyfile.j2 b/files/caddyproxy/Caddyfile.j2 index 3c70f2d..428524b 100644 --- a/files/caddyproxy/Caddyfile.j2 +++ b/files/caddyproxy/Caddyfile.j2 @@ -19,8 +19,33 @@ vakhrushev.me { tls anwinged@ya.ru + # Matrix federation delegation: tells other servers/clients that the + # homeserver for vakhrushev.me lives at matrix.vakhrushev.me. + # https://spec.matrix.org/latest/server-server-api/#server-discovery + handle /.well-known/matrix/server { + header Content-Type application/json + header Access-Control-Allow-Origin * + respond `{"m.server": "matrix.vakhrushev.me:443"}` + } + + handle /.well-known/matrix/client { + header Content-Type application/json + header Access-Control-Allow-Origin * + respond `{"m.homeserver": {"base_url": "https://matrix.vakhrushev.me"}}` + } + + handle { + reverse_proxy { + to homepage_app:80 + } + } +} + +matrix.vakhrushev.me { + tls anwinged@ya.ru + reverse_proxy { - to homepage_app:80 + to tuwunel_app:6167 } } diff --git a/files/tuwunel/docker-compose.template.yml b/files/tuwunel/docker-compose.template.yml new file mode 100644 index 0000000..08a45ca --- /dev/null +++ b/files/tuwunel/docker-compose.template.yml @@ -0,0 +1,36 @@ +# See versions: https://github.com/matrix-construct/tuwunel/releases +# Configuration reference: https://github.com/matrix-construct/tuwunel/blob/main/tuwunel-example.toml + +services: + + tuwunel_app: + image: jevolk/tuwunel:v1.6.0 + container_name: tuwunel_app + restart: unless-stopped + user: "{{ owner_create_result.uid }}:{{ owner_create_result.group }}" + networks: + - "web_proxy_network" + volumes: + - "{{ data_dir }}:/var/lib/tuwunel" + environment: + TUWUNEL_SERVER_NAME: "{{ tuwunel_server_name }}" + TUWUNEL_DATABASE_PATH: "/var/lib/tuwunel" + TUWUNEL_ADDRESS: "0.0.0.0" + TUWUNEL_PORT: "6167" + TUWUNEL_MAX_REQUEST_SIZE: "20000000" + + TUWUNEL_ALLOW_REGISTRATION: "false" + TUWUNEL_ALLOW_FEDERATION: "true" + TUWUNEL_ALLOW_CHECK_FOR_UPDATES: "false" + TUWUNEL_TRUSTED_SERVERS: '["matrix.org"]' + + # Well-known delegation values returned to clients/servers that query tuwunel directly. + # The canonical delegation is served by Caddy on {{ tuwunel_server_name }} (see Caddyfile). + TUWUNEL_WELL_KNOWN_SERVER: "{{ tuwunel_well_known_server }}" + TUWUNEL_WELL_KNOWN_CLIENT: "{{ tuwunel_well_known_client }}" + + TUWUNEL_LOG: "info" + +networks: + web_proxy_network: + external: true diff --git a/playbook-all-applications.yml b/playbook-all-applications.yml index a589322..7ad841d 100644 --- a/playbook-all-applications.yml +++ b/playbook-all-applications.yml @@ -40,6 +40,9 @@ - name: 'Configure apprise' ansible.builtin.import_playbook: playbook-apprise.yml +- name: 'Configure tuwunel' + ansible.builtin.import_playbook: playbook-tuwunel.yml + # - name: 'Configure homepage' diff --git a/playbook-tuwunel.yml b/playbook-tuwunel.yml new file mode 100644 index 0000000..5a39a41 --- /dev/null +++ b/playbook-tuwunel.yml @@ -0,0 +1,73 @@ +--- +- name: "Configure tuwunel matrix server" + hosts: all + + vars_files: + - vars/secrets.yml + + vars: + app_name: "tuwunel" + app_user: "{{ app_name }}" + app_owner_uid: 1105 + app_owner_gid: 1105 + base_dir: "{{ (application_dir, app_name) | path_join }}" + data_dir: "{{ (base_dir, 'data') | path_join }}" + backups_dir: "{{ (base_dir, 'backups') | path_join }}" + + tuwunel_server_name: "vakhrushev.me" + tuwunel_well_known_server: "matrix.vakhrushev.me:443" + tuwunel_well_known_client: "https://matrix.vakhrushev.me" + + tasks: + - name: "Create user and environment" + ansible.builtin.import_role: + name: owner + vars: + owner_name: "{{ app_user }}" + owner_uid: "{{ app_owner_uid }}" + owner_gid: "{{ app_owner_gid }}" + owner_extra_groups: ["docker"] + + - name: "Create application internal directories" + ansible.builtin.file: + path: "{{ item }}" + state: "directory" + owner: "{{ app_user }}" + group: "{{ app_user }}" + mode: "0750" + loop: + - "{{ base_dir }}" + - "{{ data_dir }}" + - "{{ backups_dir }}" + + - name: "Disable backup script" + ansible.builtin.file: + dest: "{{ base_dir }}/backup.sh" + state: absent + + - name: "Create backup targets file" + ansible.builtin.lineinfile: + path: "{{ base_dir }}/backup-targets" + line: "{{ item }}" + create: true + owner: "{{ app_user }}" + group: "{{ app_user }}" + mode: "0750" + loop: + - "{{ data_dir }}" + + - name: "Copy docker compose file" + ansible.builtin.template: + src: "./files/{{ app_name }}/docker-compose.template.yml" + dest: "{{ base_dir }}/docker-compose.yml" + owner: "{{ app_user }}" + group: "{{ app_user }}" + mode: "0640" + + - name: "Run application with docker compose" + community.docker.docker_compose_v2: + project_src: "{{ base_dir }}" + state: "present" + remove_orphans: true + tags: + - run-app