Continuwuity on Ubuntu 24.04 on Azure User Guide
Overview
This guide covers the deployment and configuration of Continuwuity on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. Continuwuity is a lightweight Matrix homeserver written in Rust — the actively maintained community successor to conduwuit and Conduit, and published under the Apache-2.0 licence.
Matrix is an open standard for secure, decentralised real-time communication. A homeserver is the piece you run: it stores your users, rooms and messages and speaks the Matrix client-server API that apps such as Element connect to. Continuwuity's design goal is that one process should be enough — a single binary plus an embedded RocksDB store, with no external PostgreSQL, no Redis and no separate application stack to run alongside it.
The cloudimg image assembles that into a ready-to-run appliance. nginx terminates TLS on port 443 and reverse-proxies the client-server API to the homeserver, which binds to loopback only. On first boot the VM generates its own homeserver signing key, TLS certificate, a single admin account and a registration token — nothing is shared between deployments, and there is no default login.
The image ships the official upstream Continuwuity v26.7.2 release binary (the static musl build), fetched from the project's own release and pinned by SHA-256. The exact artifact, its digest and its provenance are recorded on the image at /opt/continuwuity/VERSION. Continuwuity runs under systemd as continuwuity.service under an unprivileged continuwuity account.
Secure by default. An open Matrix homeserver is an abuse and spam vector, so this image never ships one. Registration is closed behind a per-VM registration token — a new account cannot be created without it — and exactly one admin account is created at first boot with a unique, generated password. You prove all of this the moment the VM is up: continuwuity-selftest confirms the API is answering, that an unauthenticated registration is refused, and that the per-VM admin can log in and create a room.
What is included:
- Continuwuity v26.7.2 (official upstream static release binary, SHA-256 pinned, redistributed unmodified)
- nginx terminating TLS on 443 with a per-VM self-signed certificate generated at first boot
- A single admin account with a per-VM password, created on first boot — no default login
- Registration closed behind a per-VM registration token
- A per-VM homeserver signing key generated inside RocksDB on first boot — never baked into the image
continuwuity-selftest, a one-command proof that the client-server API round-trips- Ubuntu 24.04 LTS, fully patched at build time, with unattended security updates left enabled
- 24/7 cloudimg support
Key facts:
| Item | Value |
|---|---|
| Platform | Ubuntu 24.04 LTS (Azure Gen2) |
| Default SSH user | azureuser |
| Homeserver service | continuwuity.service (runs as continuwuity) |
| TLS / reverse proxy | nginx.service on ports 80 and 443 |
| Client-server API | 127.0.0.1:6167 (loopback only, behind nginx) |
| Config | /etc/continuwuity/continuwuity.toml |
| Database | /var/lib/continuwuity (embedded RocksDB) |
| Credentials summary | /root/continuwuity-credentials.txt (root only, 0600) |
| Recommended VM size | Standard_B2s (2 vCPU, 4 GiB) |
Prerequisites
Before deploying, ensure you have:
- An active Azure subscription
- An SSH key pair, or the Azure Portal ability to generate one
- Permission to create virtual machines, virtual networks and network security groups
- A network security group that allows inbound TCP 22 from your management network, and inbound TCP 443 (and 80 for the HTTP-to-HTTPS redirect) from wherever your users connect
Recommended VM size: Standard_B2s (2 vCPU, 4 GiB). Continuwuity is deliberately light — at idle with a handful of users it uses on the order of 100 MiB. Size up to Standard_B2ms or larger for many active users, large rooms, or federated traffic. The database and media store grow on the OS disk over time, so give the disk headroom and monitor its usage.
Step 1: Deploy from the Azure Portal
- In the Azure Portal, choose Create a resource and search the Marketplace for Continuwuity on Ubuntu 24.04 LTS by cloudimg.
- Select the offer and choose Create.
- On Basics, pick your subscription, resource group and region, name the VM, and choose size
Standard_B2s. - Set the authentication type to SSH public key and provide your key.
- On Networking, attach a network security group that allows inbound TCP 22, 80 and 443 as described above.
- Review and create. When deployment finishes, note the VM's public IP address.
Step 2: Deploy from the Azure CLI
az group create --name continuwuity-rg --location eastus
az vm create \
--resource-group continuwuity-rg \
--name continuwuity \
--image <cloudimg-continuwuity-image-urn> \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard
# open ssh + the HTTPS client-server API (and 80 for the redirect)
az vm open-port --resource-group continuwuity-rg --name continuwuity --port 22 --priority 1001
az vm open-port --resource-group continuwuity-rg --name continuwuity --port 443 --priority 1002
az vm open-port --resource-group continuwuity-rg --name continuwuity --port 80 --priority 1003
The homeserver's server_name is set on first boot to the VM's public IP address, so it is ready to use as soon as the VM is up. If you intend to use a real domain (and federation), set that up before onboarding users — see Step 8 — because the Matrix server_name cannot be changed after the database is initialised without a wipe.
Step 3: Connect and confirm the homeserver is running
SSH in as azureuser and confirm both services are healthy and the pinned release is in place:
sudo systemctl status continuwuity --no-pager | head -6
sudo systemctl is-active continuwuity.service nginx.service
cat /opt/continuwuity/VERSION
You should see continuwuity.service active (running), nginx.service active, and the provenance file recording the pinned upstream release and its SHA-256 digest:
● continuwuity.service - Continuwuity Matrix homeserver (cloudimg)
Active: active (running) since ...
active
active
product=Continuwuity
version=26.7.2
upstream=https://forgejo.ellis.link/continuwuation/continuwuity

Step 4: Prove the client-server API round-trips
The image ships continuwuity-selftest, which proves the homeserver is genuinely serving the Matrix client-server API — not merely listening on a port. It queries the API over TLS, confirms an unauthenticated registration is refused, then logs in as the per-VM admin and creates a room:
curl -sk https://127.0.0.1/_matrix/client/versions | head -c 120
echo
sudo continuwuity-selftest
Expected output:
{"versions":["r0.0.1","r0.1.0","r0.2.0","r0.3.0", ...
continuwuity-selftest — proving the Matrix CS API round-trip for <SERVER_NAME>
[ OK ] GET /_matrix/client/versions returned the version list over TLS on :443
[ OK ] token-less registration was correctly REJECTED (registration_token required)
[ OK ] per-VM admin @admin:<SERVER_NAME> logged in and obtained an access token
[ OK ] the admin token created a room (!...) — CS API round-trip is complete
continuwuity-selftest: PASS — CS API up, open registration refused, per-VM admin logs in and creates a room.

Step 5: Read this VM's credentials
First boot writes a credentials summary, readable only by root, containing this VM's server_name, the admin login and the registration token:
sudo cat /root/continuwuity-credentials.txt
It looks like this (values are unique to your VM):
continuwuity.server_name=<your VM public IP or domain>
continuwuity.client_url=https://<your VM public IP or domain>
continuwuity.admin_user=admin
continuwuity.admin_mxid=@admin:<your VM public IP or domain>
continuwuity.admin_password=<generated on first boot>
continuwuity.registration_token=<generated on first boot>
Keep this file safe. The admin account is your Matrix server administrator, and the registration token is what lets you add more users (Step 7).
Step 6: Sign in with a Matrix client
Continuwuity has no web console of its own — you use a standard Matrix client. Using Element (web, desktop or mobile):
- Choose Sign in and then Edit / Other homeserver.
- Enter the homeserver URL from your credentials file —
https://<your VM public IP or domain>. - Sign in as username
adminwith theadmin_passwordfrom the credentials file.
Because the image ships a self-signed certificate, your client (or browser) will warn about the certificate until you install a real one (Step 8). The admin account is automatically a member of the server's admin room, from which you administer the server by chatting commands to the server bot.
Step 7: Add more users (registration stays closed)
Registration on this server is not open — a new account requires the per-VM registration token, which is exactly what stops your homeserver becoming a spam relay. You can confirm that an unauthenticated registration is refused, and see the network posture, directly:
curl -s -XPOST 'http://127.0.0.1:6167/_matrix/client/v3/register?kind=user' \
-H 'Content-Type: application/json' \
--data '{"username":"open","password":"Abc-123456","auth":{"type":"m.login.dummy"}}'
echo
ss -lnt | grep -E ':443|:6167|:80 '
The registration is rejected (no valid registration flow without the token), and you can see that the homeserver listens on 127.0.0.1:6167 only, while nginx owns 0.0.0.0:443 and 0.0.0.0:80:
{"errcode":"M_INVALID_PARAM","error":"No flows include the supplied stage"}
LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
LISTEN 0 511 0.0.0.0:443 0.0.0.0:*
LISTEN 0 128 127.0.0.1:6167 0.0.0.0:*
To let a colleague join, give them the registration_token from your credentials file; they enter it in their Matrix client when registering. To close registration entirely once your users are set up, set allow_registration = false in /etc/continuwuity/continuwuity.toml and run sudo systemctl restart continuwuity.

Step 8: Per-VM secrets, a real certificate and federation
Everything secret on this VM is generated on first boot and unique to it: the homeserver ed25519 signing key (stored inside RocksDB, never baked into the image), the admin password, the registration token, and the nginx TLS certificate and key.
sudo ls -l /root/continuwuity-credentials.txt
grep -E 'server_name|admin_mxid|signing_key_ids' /root/continuwuity-credentials.txt

Install a real certificate. For production, point a DNS name at the VM and replace the self-signed certificate. The nginx vhost already leaves an ACME challenge path open, so a certificate tool such as certbot can be used, or drop your own certificate and key at /etc/continuwuity/tls/cert.pem and /etc/continuwuity/tls/key.pem and run sudo systemctl reload nginx.
Federation. Federation endpoints are enabled, and nginx serves the /.well-known/matrix/server and /.well-known/matrix/client delegation files. Because the image ships with a self-signed certificate and an IP server_name, other homeservers cannot federate with this VM until you deploy it with a real domain name and a real certificate. Note that server_name is fixed once the database is initialised — plan your domain before onboarding users if you intend to federate.
Step 9: Managing the service
sudo systemctl restart continuwuity # restart the homeserver
sudo systemctl restart nginx # restart the TLS reverse proxy
sudo journalctl -u continuwuity -f # follow the homeserver log
Configuration lives in /etc/continuwuity/continuwuity.toml; edit it and restart continuwuity to apply. The Continuwuity configuration reference documents every option.
Filesystem layout and ports
| Path / Port | Purpose |
|---|---|
/usr/local/bin/continuwuity |
the homeserver binary (pinned v26.7.2) |
/etc/continuwuity/continuwuity.toml |
homeserver configuration |
/var/lib/continuwuity |
embedded RocksDB store (accounts, rooms, signing key, media) |
/etc/continuwuity/tls/ |
per-VM TLS certificate and key |
/root/continuwuity-credentials.txt |
per-VM admin login + registration token (root only) |
127.0.0.1:6167 |
client-server API (loopback only) |
:443 |
Matrix client-server API over TLS (nginx) |
:80 |
HTTP-to-HTTPS redirect + ACME challenge path |
Troubleshooting
- A Matrix client warns about the certificate. Expected until you install a real certificate (Step 8) — the image ships a per-VM self-signed one.
- A colleague cannot register. Registration requires the token from
/root/continuwuity-credentials.txt; without it, registration is refused by design. continuwuity.serviceis not active. Checksudo journalctl -u continuwuity -n 100. On a customer VM the homeserver and nginx start only after first boot has written this VM's configuration and TLS material.- Federation is not working. A self-signed certificate and an IP
server_namecannot federate; deploy with a real domain and certificate (Step 8).
Security notes
- Registration is closed behind a per-VM token; there is no open registration and no default login.
- The homeserver binds to loopback only; nginx is the sole public surface (80/443).
- The homeserver signing key, admin password, registration token and TLS key are all generated per-VM on first boot — none is baked into the image.
- Ubuntu is fully patched at build time and unattended security updates are left enabled.
Support
Every cloudimg image includes 24/7 support by email and live chat, 365 days a year, with a 24-hour response SLA. Contact support@cloudimg.co.uk for deployment, configuration or scaling questions.
cloudimg is not affiliated with or endorsed by the Continuwuity project. Continuwuity is redistributed unmodified under the Apache-2.0 licence; cloudimg adds packaging, an nginx TLS reverse proxy, hardened configuration and first-boot automation.