$ cd pranavchip.com && cd /docs

CONTINUWUITY MATRIX SERVER DOCUMENTATION
========================================
Pranav Chiploonkar <mail@pranavchip.com>

Created: 2026-02-14
Updated: 2026-02-15


I. MOTIVATION
=============
With the upcoming changes announced to Discord - i.e. an ID-based age 
verification system:

<https://discord.com/press-releases/discord-launches-teen-by-default-
settings-globally>

To that end, it is imperative to have a FOSS alternative available that 
allows maintenance of data sovereignty. The network effect is strong
and it is unlikely that a large portion of the userbase will migrate 
elsewhere. But it behooves me to pave the way, if nothing else.

For this project, we will use the Matrix Protocol 
via the following applications:

(1) SERVER
----------
Continuwuity <https://continuwuity.org/>https://continuwuity.org/>

A fork of Conduwuit <https://github.com/x86pup/conduwuit>, which itself 
was a fork of Conduit <https://conduit.rs/>, it is a Rust based server 
designed for performance.

"We aim to provide a stable, well-maintained alternative for current 
conduwuit users and welcome newcomers seeking a lightweight, efficient
Matrix homeserver."

(2) CLIENTS
-----------
Desktop/Web: Cinny <https://matrix.org/ecosystem/clients/cinny/>
    A Matrix client focusing primarily on simple, elegant and secure
    interface. (Read: Discord 2.0)

Android/iOS: Element X <https://matrix.org/ecosystem/clients/element-x/>
    Next generation Element on mobile with native OIDC, sliding sync and
    Matrix RTC for calls.

Below we document the process of setting up the Continuwuity server on a
modest VPS box.


II. HARDWARE USED
=================
[Hetzner CPX32]
vCPU:   4
RAM :   8 GB
ZRAM:   8 GB
SSD : 160 GB
NET :  20 TB (egress)
Cost: $11.99/mo 


III. OPERATING SYSTEM CONFIGURATION
===================================
The server runs Ubuntu 24.04.4 LTS x86_64. We shall install convenience
packages and tailscale (for networking):

    $ sudo apt update
    $ sudo apt upgrade
    $ sudo apt install micro neofetch btop bat
    
For seamless secure networking, generate a Tailscale install script at
<https://login.tailscale.com/admin/machines/new-linux>. For more
information on Tailscale, visit: <https://tailscale.com/why-tailscale>

    $ curl -fsSL https://tailscale.com/install.sh | sh && \\
    $ sudo tailscale up --auth-key=[authkey]

As mentioned in (I), 8 GB of ZRAM was configured as swap using the 
following process:

(1) Install required packages

    $ sudo apt update
    $ sudo apt install systemd-zram-generator
    
(2) Configure zram

    $ micro /etc/systemd/zram-generator.conf

    ========================================
    [zram0]
    zram-size = ram
    compression-algorithm = zstd
    ========================================
    
In the example snippet above, we set the swap size to be equal to the
RAM size. This means our 8 GB machine will have an additional 8 GB of
compressed RAM for overflow, which in most modern hardware is more
efficient than using SSD-backed swap. You can read more here:
<https://en.wikipedia.org/wiki/Zram>

(3) Fix missing zram kernel module

On the Hetzner box we used, the zram module was not loaded out of the
box. To remedy this, we can install:

    $ sudo apt install linux-modules-extra-$(uname -r)

Verify the module was successfully loaded:

    $ modinfo zram
    
You should see something like:

    > /lib/modules/.../kernel/drivers/block/zram/zram.ko.zst
    
Load the module:

    $ sudo modprobe zram

Verify and confirm device creation:

    $ lsmod | grep ^zram
    $ ls -l /sys/class/zram-control
    $ ls -l /sys/block/zram0
    $ ls -l /dev/zram0

Paste the outputs into an LLM (such as ChatGPT) for confirmation.

(4) Start zram service

    $ sudo systemctl start systemd-zram-setup@zram0.service
    $ sudo systemctl status systemd-zram-setup@zram0.service
    
(5) Verify swap activation

    $ swapon --show
    > NAME       TYPE      SIZE USED PRIO
    > /dev/zram0 partition 7.6G   0B  100
    
    $ zramctl
    > NAME       ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
    > /dev/zram0 zstd          7.6G   4K   64B   20K       4 [SWAP]
    

With helper packages and swap configured, we are ready to move on to
the next phase - the server!


IV. INSTALLING CONDUWUITY
=========================

(1) Creating system user

Before we install the binary, we need to create a separate, system user
for the server. This is good security hygiene and follows the principle 
of least privilege: there is no need for the server to have root access 
to the machine. And if a vulnerability is exploited, the blast radius 
will be significantly smaller than full root escalation.

On Ubuntu (and Debian-based distros) - which is what we are using,

    $ sudo adduser --system continuwuity --group --disabled-login \
      --no-create-home
      
(2) Downloading the binary

As of 2026-02-15, releases can be obtained from:
<https://forgejo.ellis.link/continuwuation/continuwuity/releases>

From the docs:
"For x86_64 systems with CPUs from the last ~15 years, use the -haswell-
optimised binaries for best performance. These binaries enable hardware-
accelerated CRC32 checksumming in RocksDB, which significantly improves 
database performance. The haswell instruction set provides an excellent 
balance of compatibility and speed."

As such, we will be downloading the latest release of the optimized
binary to /usr/bin in accordance with the UNIX Filesystem Hierarchy
Standard (FHS).

    $ cd /usr/local/bin
    $ wget [url]/conduwuit-haswell-linux-amd64-maxperf

Shorten the name for ease of use:

    $ mv conduwuit-haswell-linux-amd64-maxperf condwuit
    
Make the binary executable:

    $ chmod +x ./conduwuit

(3) Creating a systemd service

An example file can be found here:
<https://forgejo.ellis.link/continuwuation/continuwuity/src/branch/main
/pkg/conduwuit.service>

    $ micro /etc/systemd/system/conduwuit.service

Various parameters can be edited to match our particular setup. Here
are changes we made:

    [Service]
    # DynamicUser=yes
    User=continuwuity
    Group=continuwuity
    Type=notify-reload
    ReloadSignal=SIGUSR1
    
    ...
    
    ExecStart=/usr/local/bin/conduwuit \ 
    --config ${CREDENTIALS_DIRECTORY}/conduwuit.toml
    

(4) Creating the config file

We need to create te config file at the following location:
    
    $ mkdir /etc/conduwuit
    $ micro /etc/conduwuit/conduwuit.toml

An example config file can be found at:
<https://continuwuity.org/reference/config.html>

DIFF OF CHANGES MADE TO conduwuit-example.toml
----------------------------------------------
-#server_name =
+server_name = "unrated.me"

-#address = ["127.0.0.1", "::1"]
+address = ["127.0.0.1"]

-#port = 8008
+port = 8008

-#database_path =
+database_path = "/var/lib/conduwuit"

-#database_backup_path =
+database_backup_path = "/var/lib/conduwuit-backups"

-#database_backups_to_keep = 1
+database_backups_to_keep = 3

-#new_user_displayname_suffix = "🏳️‍⚧️"
+#new_user_displayname_suffix = ""

-#max_request_size = 20971520
+max_request_size = 536870912

-#allow_registration = false
+allow_registration = true

-#registration_token =
+registration_token = "[redacted string]"

-#admins_list = []
+admins_list = ["@praetor29:unrated.me"]

-#client =
+client = "https://matrix.unrated.me"

-#server =
+server = "matrix.unrated.me:443"

-#support_role = "m.role.admin"
+support_role = "m.role.admin"

-#support_email =
+support_email = "unratedynamics@protonmail.com"

-#support_mxid =
+support_mxid = "@praetor29:unrated.me"
------------------------------------------------

(5) Configuring correct config/database permissions

    $ sudo chown -R root:root /etc/conduwuit
    $ sudo chmod -R 755 /etc/conduwuit
    
    $ sudo mkdir -p /var/lib/conduwuit
    $ sudo mkdir -p /var/lib/conduwuit-backups
    
    $ chown -R continuwuity:continuwuity /var/lib/conduwuit
    $ chown -R continuwuity:continuwuity /var/lib/conduwuit-backups
    
    $ sudo chmod 700 /var/lib/conduwuit
    $ sudo chmod 700 /var/lib/conduwuit-backups
    

(6) Setting up reverse proxy (Caddy)

First we need to install Caddy:

    $ sudo apt install caddy
    
Then we create the caddyfile:

    $ mkdir /etc/caddy/conf.d
    $ micro /etc/caddy/conf.d/conduwuit_caddyfile
       
    ==========================================================
    # Matrix entrypoint
    matrix.unrated.me {
    	request_body {
    	        max_size 512MB
    	    }
        reverse_proxy 127.0.0.1:8008
    }

    # Delegation
    unrated.me {
        handle /.well-known/matrix/server {
            header Content-Type "application/json"
            respond `{"m.server":"matrix.unrated.me:443"}` 200
        }

        handle /.well-known/matrix/client {
            header Content-Type "application/json"
            respond `{"m.homeserver":{"base_url":"https://
            matrix.unrated.me"}}` 200
        }
        
        handle /.well-known/matrix/support {
            ereverse_proxy 127.0.0.1:8008
        }

        handle {
            respond 404
        }
    }
    ==========================================================
    
Import it into the primary Caddyfile:

    $ micro /etc/caddy/Caddyfile
    
    ============================
    import /etc/caddy/conf.d/*
    ============================

(7) Configuring DNS

An important step in the process is pointing the DNS records of the
domain you own (in this case, unrated.me) to the IPv4 (and IPv6)
address of the VPS hosting the server.

In this case, by navigating to Cloudflare (who is the domain registrar),
<https://dash.cloudflare.com/c42b68446162f3a892935f73e2dc60aa/
unrated.me/dns/records>

We create the following records:

Type   Name        Content                 Proxy status   TTL
==============================================================
A      matrix      46.224.134.82           DNS only       Auto
A      unrated.me  46.224.134.82           DNS only       Auto
AAAA   matrix      2a01:4f8:c012:e2f0::1   DNS only       Auto
AAAA   unrated.me  2a01:4f8:c012:e2f0::1   DNS only       Auto
==============================================================

Note that A maps onto IPv4 and AAAA maps onto IPv6.
Also ensure that the proxy is disabled - and set to *DNS only*.

Now, enable the caddy service:

    $ sudo systemctl enable --now caddy
    $ sudo systemclt reload caddy
    
With this done, we should have the reverse proxy up and running at
<https://matrix.unrated.me>. Navigate to the URL with your browser and
ensure you see the "Caddy works!" page.

(8) Starting Conduwuity (at last!)

    $ sudo systemctl enable conduwuit
    $ sudo systemctl start conduwuit
    $ sudo systemctl status conduwuit
    
If the status is active and running... rejoice!! Navigating to
<https://matrix.unrated.me> should reveal "Welcome to Continuwuity!"

Verify federation: 

V. CONNECTING TO THE SERVER
===========================
Using any [matrix] client, attempt registering a new user account using
the "registration_token" created in /etc/conduwuit/conduwuit.toml, and 
setting the homeserver to "matrix.unrated.me"

At this point, restarting the server once to activate the admin role
would be beneficial. It might also be more stable to populate the admin
list *after* creating the user account.

The server is now functional! Further optimizations will follow, but
this marks the end of the main server documentation.

========================================================================

Note: As of the date of publishing, this server is offline due to
             hosting costs, so none of the finer details here
             (IP addresses, etc.) are a problem.