Self-hosting guide

Install your own Matrix node and onboard users with registration tokens.

The default Meshly flow is now: user chooses a homeserver, enters username and password, and optionally enters a company-issued code. If your server requires a token, that code becomes the gate that prevents public signups.

Step 1. Use a dedicated Matrix subdomain

Good:   matrix.yourdomain.com
Avoid:  yourdomain.com/matrix
Avoid:  public open registration unless you explicitly want it

Step 2. Run the installer

The interactive installer will ask for domain, email, admin credentials, and the registration mode. In token mode it also creates the first registration token and writes it to /opt/meshly-node/initial-registration-token.txt.

curl -fsSL https://meshly.chat/install/meshly-node.sh | sudo bash

For scripted installs, pass the stack and registration mode explicitly:

curl -fsSL https://meshly.chat/install/meshly-node.sh | sudo bash -s -- \
  --domain matrix.yourdomain.com \
  --email ops@yourdomain.com \
  --admin-user owner \
  --admin-password 'replace-with-a-long-random-password' \
  --stack matrix-only \
  --registration-mode token \
  --registration-token-uses unlimited \
  --yes

For the full business stack, the installer now downloads the Meshly backend source bundle from meshly.chat, builds a local Docker image, and exposes /_meshly/client instead of /_synapse/admin:

curl -fsSL https://meshly.chat/install/meshly-node.sh | sudo bash -s -- \
  --domain matrix.yourdomain.com \
  --email ops@yourdomain.com \
  --admin-user owner \
  --admin-password 'replace-with-a-long-random-password' \
  --stack meshly-full \
  --registration-mode token \
  --registration-token-uses unlimited \
  --yes

If you later publish your own image, you can still override it explicitly with --meshly-image your-registry/meshly-control:tag.

On a clean VPS with free ports 80, 443, and 8448, the installer defaults to bundled Caddy and should finish end to end. On shared hosts where Apache or Nginx is already serving those ports, it switches to existing mode and only writes reverse-proxy snippets for you to merge manually.

The installer also checks the local loopback binds it needs for Synapse and the Meshly backend. If 127.0.0.1:8008 or 127.0.0.1:8081 are already in use, it automatically picks a safe alternate port and writes the matching proxy snippet for you.

The scripted install now supports both deployment profiles. By default, meshly-full builds a local backend image on the VPS from the source bundle published under /install/meshly-control/. If you prefer prebuilt images later, you can override the image name explicitly.

For meshly-full, the installer now also verifies that the time-tracking ledger lives on a persistent Docker volume mounted at /data. If that mount is missing or not writable, the installation stops instead of leaving you with a node that could lose legally relevant workday records after a container recreate.

Step 2b. Review the target Compose profiles

Meshly ships two explicit self-hosting profiles:

The second profile is the target shape for business modules such as user administration, registration-token lifecycle, time tracking, and future tools exposed through /_meshly/client.

Step 3. Verify the homeserver endpoints

curl https://matrix.yourdomain.com/_matrix/client/versions
curl https://matrix.yourdomain.com:8448/_matrix/federation/v1/version
curl https://matrix.yourdomain.com/_meshly/client/v1/capabilities

Meshly always needs the Matrix client API. The business stack also needs /_meshly/client reachable over HTTPS. Only the legacy matrix-only admin flow requires /_synapse/admin exposed to the app.

In meshly-full, also review the generated installation summary and keep the line about time-tracking persistence. It should explicitly say that the ledger was verified on a persistent Docker volume before you trust the deployment for attendance records.

If you used --proxy-mode existing, do not skip the generated proxy snippet. The install is not complete for app testing until the active vhost forwards /_matrix, /_synapse/client, and whichever admin surface matches your stack: /_synapse/admin for matrix-only or /_meshly/client for meshly-full.

Step 4. Create the first users from Meshly

  • Open Meshly and choose Use my own homeserver.
  • Enter matrix.yourdomain.com.
  • Choose Create account.
  • Enter username and password.
  • If the server is in token mode, enter the registration code provided by the admin.

Step 5. Manage users and tokens from Meshly

In matrix-only, the signed-in account must be a global Synapse admin and the app talks to /_synapse/admin directly. In meshly-full, the app instead talks to the Meshly backend through /_meshly/client. From there you can:

  • suspend or reactivate local users
  • delete accounts when needed
  • create new registration tokens
  • rotate or revoke leaked tokens

Step 6. Choose the mode that matches your security policy

token is the recommended mode for organisations. It keeps self-service onboarding simple without exposing the homeserver to arbitrary public signups.

After install

Run the checklist once DNS and TLS settle.