--- - name: matrix hosts: all tasks: - name: Create /home/docker/matrix.{{inventory_hostname}} dir ansible.builtin.file: path: /home/docker/matrix.{{inventory_hostname}} owner: root group: docker state: directory mode: '0550' - name: Create /home/docker/matrix.{{inventory_hostname}}/data dir ansible.builtin.file: path: /home/docker/matrix.{{inventory_hostname}}/data owner: 3000 group: 3000 state: directory mode: '0750' - name: Gen initial passwords if not exists ansible.builtin.shell: docker run --rm -v ./data:/data -e SYNAPSE_SERVER_NAME=matrix.{{inventory_hostname}} -e SYNAPSE_HTTP_PORT=8008 -e SYNAPSE_REPORT_STATS=no -e UID=3000 -e GUID=3000 matrixdotorg/synapse:latest generate args: chdir: /home/docker/matrix.{{inventory_hostname}} creates: /home/docker/matrix.{{inventory_hostname}}/data/homeserver.yaml - name: get turn secret shell: bash -c 'source /home/docker/turn.{{inventory_hostname}}/env ; echo $TURN_SECRET' register: turnsecret changed_when: false - name: Edit Matrix/Synapse config blockinfile: path: /home/docker/matrix.{{inventory_hostname}}/data/homeserver.yaml create: yes mode: 0444 owner: root group: docker marker: "# {mark} ANSIBLE MANAGED BLOCK" block: | public_baseurl: https://matrix-synapse.{{inventory_hostname}}/ enable_registration: false max_upload_size: 2048M retention: enabled: true federation_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' - '169.254.0.0/16' - '::1/128' - 'fe80::/64' - 'fc00::/7' #server_notices: ## system_mxid_localpart: mx-admin # system_mxid_display_name: "Server Notices" # system_mxid_avatar_url: "mxc://server.com/xumMIlgDBLYFaPVkEsdrNVLW" # room_name: "Server Notices" web_client_location: https://matrix-web.{{inventory_hostname}}/ trusted_key_servers: - server_name: "matrix.org" redis: enabled: true host: matrix.{{inventory_hostname}}--redis port: 6379 media_retention: local_media_lifetime: 28d remote_media_lifetime: 14d turn_uris: - "turns:turn.{{inventory_hostname}}:5349?transport=udp" - "turns:turn.{{inventory_hostname}}:5349?transport=tcp" turn_shared_secret: "{{turnsecret.stdout}}" turn_user_lifetime: 86400000 turn_allow_guests: True backup: yes notify: Restart matrix - name: /home/docker/matrix.{{inventory_hostname}}/genpw.sh (generate Random PW for Matrix and DB) blockinfile: path: /home/docker/matrix.{{inventory_hostname}}/genpw.sh create: yes mode: 0550 owner: root group: docker marker: "# {mark} ANSIBLE MANAGED BLOCK" block: | cd /home/docker/matrix.{{inventory_hostname}} postgresqluser=$(pwgen -s 32 1) postgresqlpassword=$(pwgen -s 32 1) matrixadminpassword=$(pwgen -s 32 1) [ -f env ] || echo "POSTGRES_USER=!POSTGRESUSER! POSTGRES_PASSWORD=!POSTGRESPASSWORD! MATRIX_ADMIN_PASSWORD=!MATRIX_ADMIN_PASSWORD! " >env [ -f env.db ] || echo "POSTGRES_USER=!POSTGRESUSER! POSTGRES_PASSWORD=!POSTGRESPASSWORD! " >env.db chmod 440 env env.db chown root:docker env env.db sed -i "s/\!MATRIX_ADMIN_PASSWORD\!/$matrixadminpassword/g" env sed -i "s/\!POSTGRESUSER\!/$postgresqluser/g" env env.db sed -i "s/\!POSTGRESPASSWORD\!/$postgresqlpassword/g" env env.db if ! grep -q "name: psycopg2" data/homeserver.yaml then # Remove sqlite config sed -i '/database:/,/database: \/data\/homeserver.d/d' data/homeserver.yaml # add postgres config echo " database: name: psycopg2 args: user: $postgresqluser password: $postgresqlpassword database: synapse host: matrix.{{inventory_hostname}}--db cp_min: 5 cp_max: 10 " >>data/homeserver.yaml fi backup: yes validate: /bin/bash -n %s notify: run genpw.sh - name: /home/docker/matrix.{{inventory_hostname}}/genpw.sh shebang lineinfile: path: /home/docker/matrix.{{inventory_hostname}}/genpw.sh insertbefore: BOF line: "#!/bin/bash -e" - name: Gen initial passwords if not exists ansible.builtin.shell: ./genpw.sh args: chdir: /home/docker/matrix.{{inventory_hostname}} creates: /home/docker/matrix.{{inventory_hostname}}/env - name: /home/docker/matrix.{{inventory_hostname}}/nginx-matrix.conf blockinfile: path: /home/docker/matrix.{{inventory_hostname}}/nginx-matrix.conf mode: "0444" owner: root group: root create: yes marker: "# {mark} ANSIBLE MANAGED BLOCK" block: | # Needed for federation while not using Port 8448 server { listen 80 default_server; server_name matrix.{{inventory_hostname}}; location / { proxy_pass http://matrix.{{inventory_hostname}}--synapse:8008; proxy_set_header X-Forwarded-For $remote_addr; client_max_body_size 2048m; } location /.well-known/matrix/ { root /var/www/; default_type application/json; add_header Access-Control-Allow-Origin *; } } backup: yes notify: Restart matrix - name: Create /home/docker/matrix.{{inventory_hostname}}/well-known dir ansible.builtin.file: path: /home/docker/matrix.{{inventory_hostname}}/well-known owner: root group: root state: directory mode: '0555' - name: /home/docker/matrix.{{inventory_hostname}}/well-known/client copy: dest: /home/docker/matrix.{{inventory_hostname}}/well-known/client mode: "0444" owner: root group: root content: | { "m.homeserver": { "base_url": "https://matrix.{{inventory_hostname}}" } } backup: yes - name: /home/docker/matrix.{{inventory_hostname}}/well-known/server copy: dest: /home/docker/matrix.{{inventory_hostname}}/well-known/server mode: "0444" owner: root group: root content: | { "m.server": "matrix-synapse.{{inventory_hostname}}:443" } backup: yes - name: Element Web configuration copy: dest: /home/docker/matrix.{{inventory_hostname}}/element-web-config.json owner: root group: root mode: 0444 content: | { "default_server_config": { "m.homeserver": { "base_url": "https://matrix.{{inventory_hostname}}", "server_name": "matrix.{{inventory_hostname}}" }, "m.identity_server": { "base_url": "https://vector.im" } }, "disable_custom_urls": true, "disable_guests": true, "disable_login_language_selector": true, "disable_3pid_login": true, "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.riot.im/scalar/api" ], "default_country_code": "DE", "show_labs_settings": false, "features": {}, "default_federate": true, "default_theme": "dark", "default_device_display_name" : "Matrix", "room_directory": { "servers": ["matrix.{{inventory_hostname}}", "matrix.org"] }, "enable_presence_by_hs_url": { "https://matrix.org": false, "https://matrix-client.matrix.org": false }, "setting_defaults": { "breadcrumbs": false }, "jitsi": { "preferred_domain": "meet.element.io" }, "element_call": { "url": "https://call.element.io", "participant_limit": 8, "brand": "Element Call" }, "map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx" } backup: yes - name: /home/docker/matrix.{{inventory_hostname}}/docker-compose.yml Container Configuration blockinfile: path: /home/docker/matrix.{{inventory_hostname}}/docker-compose.yml create: yes mode: 0440 owner: root group: docker marker: "# {mark} ANSIBLE MANAGED BLOCK" block: | version: '3.6' services: matrix.{{inventory_hostname}}: image: "nginx:latest" restart: unless-stopped volumes: - ./nginx-matrix.conf:/etc/nginx/conf.d/matrix.conf:ro - ./well-known:/var/www/.well-known/matrix depends_on: - matrix.{{inventory_hostname}}--synapse networks: - matrix.{{inventory_hostname}}--network - traefik labels: - traefik.enable=true # HTTPS - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}.rule=Host(`matrix.{{ ansible_facts['nodename'] }}`) - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}.entrypoints=https - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}.tls=true # Proxy to service-port - traefik.http.services.matrix-{{ ansible_facts['hostname'] }}.loadbalancer.server.port=80 - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}.service=matrix-{{ ansible_facts['hostname'] }} # cert via letsencrypt - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}.tls.certresolver=letsencrypt # Traefik network - traefik.docker.network=traefik # activate secHeaders@file and .well.known - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}.middlewares=secHeaders@file matrix.{{inventory_hostname}}--synapse: image: docker.io/matrixdotorg/synapse:latest restart: unless-stopped user: 3000:3000 volumes: - ./data:/data - /etc/localtime:/etc/localtime:ro depends_on: - matrix.{{inventory_hostname}}--db networks: - matrix.{{inventory_hostname}}--network - traefik environment: SYNAPSE_HTTP_PORT: 8008 SYNAPSE_SERVER_NAME: "matrix.{{inventory_hostname}}" SYNAPSE_REPORT_STATS: "no" labels: - traefik.enable=true # HTTPS - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}-synapse.rule=Host(`matrix-synapse.{{ ansible_facts['nodename'] }}`) - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}-synapse.entrypoints=https - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}-synapse.tls=true # Proxy to service-port - traefik.http.services.matrix-{{ ansible_facts['hostname'] }}-synapse.loadbalancer.server.port=8008 - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}-synapse.service=matrix-{{ ansible_facts['hostname'] }}-synapse # cert via letsencrypt - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}-synapse.tls.certresolver=letsencrypt # Traefik network - traefik.docker.network=traefik # activate secHeaders@file and .well.known - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}-synapse.middlewares=secHeaders@file matrix.{{inventory_hostname}}--db: image: docker.io/postgres:latest restart: unless-stopped command: postgres -c wal_level=minimal -c max_wal_size=100MB -c max_wal_senders=0 volumes: - ./matrixdb-data:/var/lib/postgresql/data - /etc/localtime:/etc/localtime:ro env_file: env.db environment: - POSTGRES_INITDB_ARGS=--encoding='UTF8' --lc-collate='C' --lc-ctype='C' - POSTGRES_DB=synapse networks: - matrix.{{inventory_hostname}}--network matrix.{{inventory_hostname}}--redis: image: redis:latest restart: unless-stopped volumes: - /etc/localtime:/etc/localtime:ro networks: - matrix.{{inventory_hostname}}--network matrix.{{inventory_hostname}}--admin: image: awesometechnologies/synapse-admin:latest restart: unless-stopped networks: - matrix.{{inventory_hostname}}--network - traefik environment: - REACT_APP_SERVER=https://{{inventory_hostname}} labels: - traefik.enable=true # HTTPS - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}-admin.rule=Host(`matrix-admin.{{ ansible_facts['nodename'] }}`) - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}-admin.entrypoints=https - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}-admin.tls=true # Proxy to service-port - traefik.http.services.matrix-{{ ansible_facts['hostname'] }}-admin.loadbalancer.server.port=80 - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}-admin.service=matrix-{{ ansible_facts['hostname'] }}-admin # cert via letsencrypt - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}-admin.tls.certresolver=letsencrypt # Traefik network - traefik.docker.network=traefik # activate secHeaders@file and .well.known - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}-admin.middlewares=secHeaders@file matrix.{{inventory_hostname}}--web: image: vectorim/element-web:latest restart: unless-stopped volumes: - /etc/localtime:/etc/localtime:ro - ./element-web-config.json:/app/config.json:ro networks: - matrix.{{inventory_hostname}}--network - traefik labels: - traefik.enable=true # HTTPS - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}-web.rule=Host(`matrix-web.{{ ansible_facts['nodename'] }}`) - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}-web.entrypoints=https - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}-web.tls=true # Proxy to service-port - traefik.http.services.matrix-{{ ansible_facts['hostname'] }}-web.loadbalancer.server.port=80 - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}-web.service=matrix-{{ ansible_facts['hostname'] }}-web # cert via letsencrypt - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}-web.tls.certresolver=letsencrypt # Traefik network - traefik.docker.network=traefik # activate secHeaders@file and .well.known - traefik.http.routers.matrix-{{ ansible_facts['hostname'] }}-web.middlewares=secHeaders@file networks: matrix.{{inventory_hostname}}--network: driver: bridge driver_opts: com.docker.network.bridge.name: br-matrix traefik: external: true backup: yes notify: Restart matrix - name: Start matrix ansible.builtin.shell: docker-compose up -d args: chdir: /home/docker/matrix.{{inventory_hostname}} creates: /home/docker/matrix.{{inventory_hostname}}/matrixdb-data/postmaster.pid - name: Wait until matrix install is finished wait_for: path: /home/docker/matrix.{{inventory_hostname}}/matrixdb-data/base - name: /home/docker/matrix.{{inventory_hostname}}/matrix.init.sh blockinfile: path: /home/docker/matrix.{{inventory_hostname}}/matrix.init.sh mode: "0500" owner: root group: root create: yes marker: "# {mark} ANSIBLE MANAGED BLOCK" block: | # matrix sleep 120 cd /home/docker/matrix.{{inventory_hostname}} || exit 1 . ./env docker compose exec matrix.{{inventory_hostname}}--synapse register_new_matrix_user -c /data/homeserver.yaml -a -u mx-admin -p $MATRIX_ADMIN_PASSWORD http://localhost:8008 >matrix.init.log 2>&1 backup: yes validate: /bin/bash -n %s # notify: run matrix.init - name: Run matrix.init after install ansible.builtin.shell: bash /home/docker/matrix.{{inventory_hostname}}/matrix.init.sh args: chdir: /home/docker/matrix.{{inventory_hostname}} creates: /home/docker/matrix.{{inventory_hostname}}/matrix.init.log # - name: /usr/local/sbin/autoupdate.d/matrix.update # blockinfile: # path: /usr/local/sbin/autoupdate.d/matrix.update # mode: "0400" # owner: root # group: root # create: yes # marker: "# {mark} ANSIBLE MANAGED BLOCK" # block: | # backup: yes # validate: /bin/bash -n %s # notify: run matrix.update handlers: - name: run genpw.sh ansible.builtin.shell: ./genpw.sh args: chdir: /home/docker/matrix.{{inventory_hostname}} notify: Restart matrix # - name: run matrix.update # ansible.builtin.shell: bash /usr/local/sbin/autoupdate.d/matrix.update # # - name: run matrix.init # ansible.builtin.shell: bash /home/docker/matrix.{{inventory_hostname}}/matrix.init.sh - name: Restart matrix ansible.builtin.shell: docker-compose up -d args: chdir: /home/docker/matrix.{{inventory_hostname}}