Преглед изворни кода

Add Synology DSM support (#5315)

Adds optional support for running the playbook on Synology DSM 7+, detected
automatically via /etc/synoinfo.conf so that non-Synology hosts are unaffected.

Includes DSM-native user/group management (synouser/synogroup), a requests
version constraint for Docker SDK compatibility, and a boot-fix service that
re-shares the volume mount and starts matrix services skipped by DSM's boot
ordering. The shared-mount volume path is configurable via
matrix_base_synology_volume_path, and the make-shared step only runs when the
volume is not already shared.

Co-authored-by: CKSit <sitchiuki@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
master
cksit пре 4 часа
committed by GitHub
родитељ
комит
ee1cd217a8
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
13 измењених фајлова са 490 додато и 23 уклоњено
  1. +2
    -0
      docs/README.md
  2. +179
    -0
      docs/configuring-playbook-synology.md
  3. +20
    -0
      roles/custom/matrix-base/defaults/main.yml
  4. +16
    -0
      roles/custom/matrix-base/tasks/detect_platform.yml
  5. +13
    -0
      roles/custom/matrix-base/tasks/main.yml
  6. +24
    -0
      roles/custom/matrix-base/tasks/setup_matrix_base.yml
  7. +5
    -23
      roles/custom/matrix-base/tasks/setup_matrix_user.yml
  8. +31
    -0
      roles/custom/matrix-base/tasks/setup_matrix_user_linux.yml
  9. +69
    -0
      roles/custom/matrix-base/tasks/setup_matrix_user_synology.yml
  10. +27
    -0
      roles/custom/matrix-base/tasks/setup_synology_boot_fix.yml
  11. +34
    -0
      roles/custom/matrix-base/tasks/setup_synology_prerequisites.yml
  12. +54
    -0
      roles/custom/matrix-base/templates/bin/matrix-synology-boot-fix.j2
  13. +16
    -0
      roles/custom/matrix-base/templates/systemd/matrix-synology-boot-fix.service.j2

+ 2
- 0
docs/README.md Прегледај датотеку

@@ -76,6 +76,8 @@ If your server and services experience issues, feel free to come to [our support

- [Alternative architectures](alternative-architectures.md)

- [Configuring Synology DSM](configuring-playbook-synology.md)

- [Container images used by the playbook](container-images.md)

- [Obtaining an Access Token](obtaining-access-tokens.md)


+ 179
- 0
docs/configuring-playbook-synology.md Прегледај датотеку

@@ -0,0 +1,179 @@
<!--
SPDX-FileCopyrightText: 2026 Chiu Ki Sit

SPDX-License-Identifier: AGPL-3.0-or-later
-->

# Configuring Synology DSM

This document is a guide for preparing Synology DSM for the installation of the [Matrix Docker Ansible Deploy](https://github.com/spantaleev/matrix-docker-ansible-deploy) project.

> **Note:** Synology DSM is a community-supported platform. It is not officially tested or maintained by the project maintainers. Use at your own discretion.

**Intended audience:** Users already familiar with DSM, SSH, and this Ansible project.

## Assumptions

- DSM version 7 or higher
- `Volume1` is used as the default Docker storage location
- You are using DSM's built-in reverse proxy for handling HTTPS

## How Synology Support Works

The playbook automatically detects Synology DSM by checking for `/etc/synoinfo.conf`. When detected, it:

- Uses `synouser` and `synogroup` (DSM-native tools) instead of standard Linux user management
- Constrains the Python `requests` package to a version compatible with the Docker SDK
- Ensures `/volume1` has shared mount propagation so container bind mounts work correctly
- Deploys a `matrix-synology-boot-fix` service that runs on every boot after Docker is ready

You can override auto-detection by setting `matrix_base_host_is_synology: true` or `false` in your `vars.yml`.

### Matrix Service Account

The playbook creates a `matrix` system account using Synology's `synouser` tool. The account is secured as follows:

- **Expired** (`expired=1`) — the account cannot be used to log in to DSM or any application

You must set a password for this account via `matrix_synology_user_password` in your `vars.yml` (see [vars.yml Configuration](#varsyml-configuration)). The password cannot be used to log in because the account is expired, but a non-empty password is required as an additional security layer.

> If you pre-create the `matrix` user manually before running the playbook, the playbook will not modify the existing account's settings — you are responsible for securing it.

### Boot-fix Service

Synology DSM has two boot-time quirks that the boot-fix service addresses automatically:

1. **`/volume1` shared mount propagation**

Docker requires `/volume1` to be mounted as shared (`mount --make-shared /volume1`) for container bind mounts with `bind-propagation=slave` to work correctly (used by matrix-synapse for its media store). On Synology, this cannot be inserted into the systemd chain before Container Manager starts — doing so causes Container Manager to detect a broken dependency and prompt for repair on every boot. The playbook applies this during setup, and the boot-fix service re-applies it on every subsequent reboot, safely outside Container Manager's dependency chain.

2. **Skipped services at boot**

Synology's systemd drops services with multi-level dependency chains from the boot activation queue (e.g. `matrix-traefik → matrix-container-socket-proxy → docker`). These services show as `inactive` or `failed` after reboot even though they are enabled. The boot-fix service scans for any enabled `matrix-*.service` in either state and starts them automatically.

> **If you previously configured a Task Scheduler entry** (`Control Panel > Task Scheduler`) to run `mount --make-shared /volume1` at boot-up, you can remove it — the boot-fix service now handles this.

## Synology GUI Preparation

1. **Enable SSH**
- `Control Panel` > `Terminal & SNMP` > `Enable SSH service`

2. **Enable SFTP**
- `Control Panel` > `File Service` > `FTP` > `Enable SFTP service` with default port

3. **Enable User Home Directory**
- `Control Panel` > `User & Group` > `Advanced` > `Enable user home service`

4. **Install Container Manager**
- Install from `Package Center`

5. **Configure Reverse Proxy**
- `Control Panel` > `Login Portal` > `Advanced` > `Reverse Proxy`
- Create entries for each service you enable (e.g. Matrix, Element, admin page)
- Example entry:
- Source: `HTTPS` / `matrix.example.com` / port `443`
- Destination: `HTTP` / `localhost` / port `81`

## SSH Preparation

### (Optional but Recommended) Enable SSH Key Authentication

Configure key-based SSH login to avoid password prompts during Ansible runs.

### Set Up the Ansible Environment

Create a project folder and Python virtual environment on the DSM host:

```shell
mkdir ~/path/to/your/project/folder
cd ~/path/to/your/project/folder

python3 -m venv ./myenv
# (optional) activate python virtual environment
# source ./myenv/bin/activate
```

## Inventory Configuration

In your `inventory/hosts` file, set the Python interpreter to your virtual environment:

```ini
# SSH key authentication with empty passphrase example
matrix.example.com ansible_host=<your-dsm-ip> ansible_ssh_user=<dsm-ssh-user> become=true become_user=root ansible_python_interpreter=/volume1/homes/path/to/your/project/folder/myenv/bin/python ansible_sudo_pass='your-password'
```

## vars.yml Configuration

Add the following Synology-specific variables to your `vars.yml`:

```yaml
# Synology-specific settings

# Controls Synology DSM-specific handling. `null` means autodetect (via /etc/synoinfo.conf).
# Set to `true`/`false` to force.
# matrix_base_host_is_synology: true

# Password for the Matrix service account created by the playbook.
# The account is created as expired so this password cannot be used to log in.
matrix_synology_user_password: "your-strong-password"

# User and group that will be created automatically by the playbook
matrix_user_name: "matrix"
matrix_group_name: "matrix"

# Data path on your Synology volume
matrix_base_data_path: "/volume1/docker/matrix"

# Use Synology Container Manager's Docker daemon instead of installing Docker
matrix_playbook_docker_installation_enabled: false
devture_systemd_docker_base_host_command_docker: "/var/packages/ContainerManager/target/usr/bin/docker"
devture_systemd_docker_base_docker_service_name: "pkg-ContainerManager-dockerd.service"

# Use Synology's NTP service
devture_timesync_ntpd_service: "chronyd"

# Reverse proxy settings — use HTTPS at the DSM reverse proxy level
matrix_playbook_ssl_enabled: true
traefik_config_entrypoint_web_secure_enabled: false

# Bind to localhost only — DSM reverse proxy handles public traffic
traefik_container_web_host_bind_port: '127.0.0.1:81'
matrix_playbook_public_matrix_federation_api_traefik_entrypoint_host_bind_port: '127.0.0.1:8449'

# Trust X-Forwarded-* headers from the local reverse proxy
traefik_config_entrypoint_web_forwardedHeaders_insecure: true

matrix_playbook_public_matrix_federation_api_traefik_entrypoint_config_custom:
forwardedHeaders:
insecure: true
```

## Running the Playbook

```shell
# Full setup
ansible-playbook -i inventory/hosts setup.yml --tags=setup-all

# start
ansible-playbook -i inventory/hosts setup.yml --tags=install-all,start

# Stop all services
ansible-playbook -i inventory/hosts setup.yml --tags=stop

# Apply config changes (always include start to restart running containers)
ansible-playbook -i inventory/hosts setup.yml --tags=stop,setup-all,start
```

> **Important:** Always include `stop` before `setup-all,start` when changing configuration. Running `setup-all` alone does not restart already-running containers.

## Creating Matrix Users

After the services are running, create your first Matrix user:

```shell
# option 1:
sudo docker exec -it matrix-synapse register_new_matrix_user http://localhost:8008 -c /data/homeserver.yaml -u your_username -p your_password

# option 2:
ansible-playbook -i inventory/hosts setup.yml --extra-vars='username=your_username password=your_password admin=yes|no' --tags=register-user
```

+ 20
- 0
roles/custom/matrix-base/defaults/main.yml Прегледај датотеку

@@ -204,6 +204,26 @@ matrix_group_system: true
matrix_user_uid: ~
matrix_user_gid: ~

# Controls Synology DSM-specific handling. `null` means autodetect (via /etc/synoinfo.conf).
# Set to `true`/`false` to force.
matrix_base_host_is_synology: ~

# Password for the Matrix service account on Synology DSM.
# Must be set to a non-empty value in your vars.yml when running on Synology.
# The account is created as expired so the password cannot be used to log in.
matrix_synology_user_password: ""

# Version constraint for the requests Python package installed on Synology hosts.
# requests >= 2.32 dropped the http+docker URL scheme used by the Docker SDK,
# causing "Not supported URL scheme http+docker" errors. Installed into the
# system Python interpreter (ansible_python_interpreter) on the remote host.
matrix_base_synology_requests_version_constraint: "requests<2.32"

# Synology volume that needs shared mount propagation so that Docker
# bind-propagation=slave mounts (used by matrix-synapse for its media store)
# work correctly. Defaults to /volume1 (DSM's default Docker storage volume).
matrix_base_synology_volume_path: "/volume1"

matrix_base_data_path: "/matrix"
matrix_base_data_path_mode: "750"



+ 16
- 0
roles/custom/matrix-base/tasks/detect_platform.yml Прегледај датотеку

@@ -0,0 +1,16 @@
# SPDX-FileCopyrightText: 2026 Chiu Ki Sit
#
# SPDX-License-Identifier: AGPL-3.0-or-later

---

- name: Detect Synology DSM
ansible.builtin.stat:
path: /etc/synoinfo.conf
register: matrix_base_synoinfo_conf_stat
when: matrix_base_host_is_synology is none

- name: Set matrix_base_host_is_synology from detection
ansible.builtin.set_fact:
matrix_base_host_is_synology: "{{ matrix_base_synoinfo_conf_stat.stat.exists }}"
when: matrix_base_host_is_synology is none

+ 13
- 0
roles/custom/matrix-base/tasks/main.yml Прегледај датотеку

@@ -4,6 +4,7 @@
# SPDX-FileCopyrightText: 2020 Marcel Partap
# SPDX-FileCopyrightText: 2022 Marko Weltzer
# SPDX-FileCopyrightText: 2022 Warren Bailey
# SPDX-FileCopyrightText: 2026 Chiu Ki Sit
#
# SPDX-License-Identifier: AGPL-3.0-or-later

@@ -15,6 +16,11 @@
block:
- ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml"

- tags:
- always
block:
- ansible.builtin.include_tasks: "{{ role_path }}/tasks/detect_platform.yml"

# This needs to always run, because it populates `matrix_user_uid` and `matrix_user_gid`,
# which are required by many other roles.
- tags:
@@ -24,6 +30,13 @@
block:
- ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_matrix_user.yml"

- tags:
- setup-all
- install-all
block:
- ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_synology_prerequisites.yml"
when: matrix_base_host_is_synology

- tags:
- setup-all
- install-all


+ 24
- 0
roles/custom/matrix-base/tasks/setup_matrix_base.yml Прегледај датотеку

@@ -7,11 +7,20 @@
# SPDX-FileCopyrightText: 2022 Sebastian Gumprich
# SPDX-FileCopyrightText: 2024 - 2025 Suguru Hirahara
# SPDX-FileCopyrightText: 2024 László Várady
# SPDX-FileCopyrightText: 2026 Chiu Ki Sit
#
# SPDX-License-Identifier: AGPL-3.0-or-later

---

# Snapshot ownership before any changes so we can decide whether a recursive
# chown is needed (only when uid/gid actually differs from expected).
- name: Check current ownership of Matrix base path (Synology)
ansible.builtin.stat:
path: "{{ matrix_base_data_path }}"
register: matrix_base_data_path_stat
when: matrix_base_host_is_synology

- name: Ensure Matrix base paths exists
ansible.builtin.file:
path: "{{ item }}"
@@ -28,3 +37,18 @@
src: "{{ role_path }}/templates/bin/remove-all.j2"
dest: "{{ matrix_bin_path }}/remove-all"
mode: '0750'

# On Synology, name-based chown works for directly-touched paths but leaves
# existing sub-paths with stale numeric ownership when uid/gid changes between
# runs. We recurse only when the pre-task uid/gid didn't match, so normal runs
# skip the expensive tree walk entirely. chown -R is used instead of the file
# module's recurse option to avoid Ansible iterating every entry in Python.
- name: Ensure Matrix base path ownership is correct using numeric UID/GID (Synology)
ansible.builtin.command: chown -R {{ matrix_user_uid }}:{{ matrix_user_gid }} {{ matrix_base_data_path }}
changed_when: true
when: >-
matrix_base_host_is_synology and (
not matrix_base_data_path_stat.stat.exists or
matrix_base_data_path_stat.stat.uid | int != matrix_user_uid | int or
matrix_base_data_path_stat.stat.gid | int != matrix_user_gid | int
)

+ 5
- 23
roles/custom/matrix-base/tasks/setup_matrix_user.yml Прегледај датотеку

@@ -1,31 +1,13 @@
# SPDX-FileCopyrightText: 2020 - 2022 Slavi Pantaleev
# SPDX-FileCopyrightText: 2022 Marko Weltzer
# SPDX-FileCopyrightText: 2026 Chiu Ki Sit
#
# SPDX-License-Identifier: AGPL-3.0-or-later

---

- name: Ensure Matrix group is created
ansible.builtin.group:
name: "{{ matrix_group_name }}"
gid: "{{ omit if matrix_user_gid is none else matrix_user_gid }}"
state: present
system: "{{ matrix_group_system }}"
register: matrix_group
- ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_matrix_user_synology.yml"
when: matrix_base_host_is_synology

- name: Ensure Matrix user is created
ansible.builtin.user:
name: "{{ matrix_user_name }}"
uid: "{{ omit if matrix_user_uid is none else matrix_user_uid }}"
state: present
group: "{{ matrix_group_name }}"
home: "{{ matrix_base_data_path }}"
create_home: false
system: "{{ matrix_user_system }}"
shell: "{{ matrix_user_shell }}"
register: matrix_user

- name: Initialize matrix_user_uid and matrix_user_gid
ansible.builtin.set_fact:
matrix_user_uid: "{{ matrix_user.uid }}"
matrix_user_gid: "{{ matrix_group.gid }}"
- ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_matrix_user_linux.yml"
when: not matrix_base_host_is_synology

+ 31
- 0
roles/custom/matrix-base/tasks/setup_matrix_user_linux.yml Прегледај датотеку

@@ -0,0 +1,31 @@
# SPDX-FileCopyrightText: 2020 - 2022 Slavi Pantaleev
# SPDX-FileCopyrightText: 2022 Marko Weltzer
#
# SPDX-License-Identifier: AGPL-3.0-or-later

---

- name: Ensure Matrix group is created
ansible.builtin.group:
name: "{{ matrix_group_name }}"
gid: "{{ omit if matrix_user_gid is none else matrix_user_gid }}"
state: present
system: "{{ matrix_group_system }}"
register: matrix_group

- name: Ensure Matrix user is created
ansible.builtin.user:
name: "{{ matrix_user_name }}"
uid: "{{ omit if matrix_user_uid is none else matrix_user_uid }}"
state: present
group: "{{ matrix_group_name }}"
home: "{{ matrix_base_data_path }}"
create_home: false
system: "{{ matrix_user_system }}"
shell: "{{ matrix_user_shell }}"
register: matrix_user

- name: Initialize matrix_user_uid and matrix_user_gid
ansible.builtin.set_fact:
matrix_user_uid: "{{ matrix_user.uid }}"
matrix_user_gid: "{{ matrix_group.gid }}"

+ 69
- 0
roles/custom/matrix-base/tasks/setup_matrix_user_synology.yml Прегледај датотеку

@@ -0,0 +1,69 @@
# SPDX-FileCopyrightText: 2026 Chiu Ki Sit
#
# SPDX-License-Identifier: AGPL-3.0-or-later

---

- name: Fail if matrix_synology_user_password is not set
ansible.builtin.fail:
msg: >-
You must set `matrix_synology_user_password` to a non-empty value in your vars.yml.
This password secures the Matrix service account on Synology DSM.
The account is created as expired so the password cannot be used to log in.
when: matrix_synology_user_password == '' or matrix_synology_user_password is none

- name: Check if Matrix user exists (Synology)
ansible.builtin.command: id {{ matrix_user_name }}
register: matrix_user_check
changed_when: false
failed_when: false

# Created with expired=1 (cannot log in)
# as this is a service account. If you pre-create the user, you are responsible
# for securing it; the playbook will not modify an existing account's settings.
- name: Ensure Matrix user is created (Synology)
ansible.builtin.command: >
/usr/syno/sbin/synouser --add {{ matrix_user_name }}
"{{ matrix_synology_user_password }}" "{{ matrix_user_name }}" 1 "" 0
when: matrix_user_check.rc != 0
changed_when: true
no_log: true

- name: Ensure Matrix user password is up to date (Synology)
ansible.builtin.command: /usr/syno/sbin/synouser --setpw {{ matrix_user_name }} "{{ matrix_synology_user_password }}"
when: matrix_user_check.rc == 0
changed_when: false
no_log: true

- name: Check if Matrix group exists (Synology)
ansible.builtin.command: /usr/syno/sbin/synogroup --get {{ matrix_group_name }}
register: matrix_group_check
changed_when: false
failed_when: false

- name: Ensure Matrix group is created (Synology)
ansible.builtin.command: /usr/syno/sbin/synogroup --add {{ matrix_group_name }} {{ matrix_user_name }}
when: matrix_group_check.rc != 0
changed_when: true

- name: Get Matrix user UID (Synology)
ansible.builtin.command: id -u {{ matrix_user_name }}
register: matrix_user_uid_result
changed_when: false

- name: Get Matrix group info (Synology)
ansible.builtin.command: /usr/syno/sbin/synogroup --get {{ matrix_group_name }}
register: matrix_synogroup_result
changed_when: false

- name: Initialize matrix_user_uid and matrix_user_gid
ansible.builtin.set_fact:
matrix_user_uid: "{{ matrix_user_uid_result.stdout }}"
matrix_user_gid: >-
{{
matrix_synogroup_result.stdout_lines
| select('match', '^Group ID:')
| first
| regex_search('\[(\d+)\]', '\1')
| first
}}

+ 27
- 0
roles/custom/matrix-base/tasks/setup_synology_boot_fix.yml Прегледај датотеку

@@ -0,0 +1,27 @@
# SPDX-FileCopyrightText: 2026 Chiu Ki Sit
#
# SPDX-License-Identifier: AGPL-3.0-or-later

---

- name: Deploy Matrix boot recovery script (Synology)
ansible.builtin.template:
src: "{{ role_path }}/templates/bin/matrix-synology-boot-fix.j2"
dest: "{{ matrix_bin_path }}/matrix-synology-boot-fix"
mode: "0750"
owner: root
group: root

- name: Deploy Matrix boot recovery service (Synology)
ansible.builtin.template:
src: "{{ role_path }}/templates/systemd/matrix-synology-boot-fix.service.j2"
dest: /etc/systemd/system/matrix-synology-boot-fix.service
mode: "0644"
register: matrix_synology_boot_fix_service

- name: Reload systemd and enable Matrix boot recovery service (Synology)
ansible.builtin.systemd:
name: matrix-synology-boot-fix.service
daemon_reload: true
enabled: true
when: matrix_synology_boot_fix_service.changed

+ 34
- 0
roles/custom/matrix-base/tasks/setup_synology_prerequisites.yml Прегледај датотеку

@@ -0,0 +1,34 @@
# SPDX-FileCopyrightText: 2026 Chiu Ki Sit
#
# SPDX-License-Identifier: AGPL-3.0-or-later

---

- name: Ensure requests Python package is constrained for Docker SDK compatibility (Synology)
ansible.builtin.pip:
name: "{{ matrix_base_synology_requests_version_constraint }}"
state: present

# Determine whether the volume is already a shared mount, so that the
# make-shared command below only runs (and only reports `changed`) when it
# actually needs to. We read /proc/self/mountinfo (always present on Linux)
# and look for the ` shared:` optional tag on the volume's mount point line.
# grep exits non-zero on no-match or any error, so the make-shared command is
# skipped only when shared propagation is positively confirmed; every other
# case falls through to running it (which is idempotent).
- name: Determine current mount propagation of the Synology volume
ansible.builtin.command: grep -E ' {{ matrix_base_synology_volume_path }} .* shared:' /proc/self/mountinfo
register: matrix_base_synology_volume_propagation
changed_when: false
failed_when: false

# Run immediately during setup so matrix services can start without a manual
# step. The boot-fix service handles this on every subsequent reboot.
# noqa command-instead-of-module: ansible.builtin.mount does not support
# changing mount propagation (--make-shared); command is the only option here.
- name: Ensure the Synology volume has shared mount propagation
ansible.builtin.command: mount --make-shared {{ matrix_base_synology_volume_path }} # noqa command-instead-of-module
when: matrix_base_synology_volume_propagation.rc != 0
changed_when: true

- ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_synology_boot_fix.yml"

+ 54
- 0
roles/custom/matrix-base/templates/bin/matrix-synology-boot-fix.j2 Прегледај датотеку

@@ -0,0 +1,54 @@
#!/bin/sh
# SPDX-FileCopyrightText: 2026 Chiu Ki Sit
#
# SPDX-License-Identifier: AGPL-3.0-or-later
#
# Boot recovery for Matrix services on Synology DSM.
#
# This script runs after multi-user.target (outside Container Manager's dependency
# chain) and does two things:
#
# 1. Makes {{ matrix_base_synology_volume_path }} mount-shared so Docker bind-propagation=slave mounts work.
# Inserting this into the systemd chain Before=pkg-ContainerManager-dockerd.service
# causes Container Manager to detect a broken dependency and prompt for repair,
# so it must run here instead, after Docker is already up.
#
# 2. Starts any enabled matrix-*.service that systemd skipped at boot.
# Synology's systemd drops services with multi-level dependency chains
# (e.g. traefik -> socket-proxy -> docker) from the boot activation queue.
# Services that need bind-propagation=slave (e.g. matrix-synapse) are
# created after step 1, so the propagation is already in effect.

# Wait up to 120s for Docker to be ready
i=0
while [ "$i" -lt 60 ]; do
{{ devture_systemd_docker_base_host_command_docker }} info >/dev/null 2>&1 && break
i=$((i + 1))
sleep 2
done

if ! {{ devture_systemd_docker_base_host_command_docker }} info >/dev/null 2>&1; then
echo "matrix-synology-boot-fix: Docker not ready after 120s, aborting" >&2
exit 1
fi

# Make {{ matrix_base_synology_volume_path }} shared so Docker bind-propagation=slave mounts work correctly.
# Must run after Docker is up to avoid interfering with Container Manager's
# integrity checks, but before matrix-synapse (and any other service using
# bind-propagation=slave) creates its containers.
/bin/mount --make-shared {{ matrix_base_synology_volume_path }}
echo "matrix-synology-boot-fix: {{ matrix_base_synology_volume_path }} set to shared mount propagation"

# Start any enabled matrix-*.service that is inactive or failed.
# Both states indicate the service did not come up at boot — either skipped by
# Synology's boot ordering or failed due to Docker/mount-propagation not being
# ready yet (the conditions above now satisfy those prerequisites).
{{ devture_systemd_docker_base_host_command_systemctl }} list-unit-files 'matrix-*.service' --state=enabled --no-legend 2>/dev/null | \
while read -r unit _state; do
[ "$unit" = "matrix-synology-boot-fix.service" ] && continue
status="$({{ devture_systemd_docker_base_host_command_systemctl }} is-active "$unit" 2>/dev/null)"
if [ "$status" = "inactive" ] || [ "$status" = "failed" ]; then
echo "matrix-synology-boot-fix: starting $unit (was $status)"
{{ devture_systemd_docker_base_host_command_systemctl }} start "$unit"
fi
done

+ 16
- 0
roles/custom/matrix-base/templates/systemd/matrix-synology-boot-fix.service.j2 Прегледај датотеку

@@ -0,0 +1,16 @@
# SPDX-FileCopyrightText: 2026 Chiu Ki Sit
#
# SPDX-License-Identifier: AGPL-3.0-or-later

[Unit]
Description=Matrix Services Boot Recovery (Synology)
# Run after multi-user.target so all matrix services have been attempted first.
After=multi-user.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart={{ matrix_bin_path }}/matrix-synology-boot-fix

[Install]
WantedBy=multi-user.target

Loading…
Откажи
Сачувај