Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Getting Started

Installing Venator is relatively simple, but you need to be confident with managing a server to get the most out of it. This guide will walk you through the minimum steps required to get a working installation of Venator.

This part of the guide is very in depth - consider using the TOC in the sidebar to help you navigate.

Prerequisites

To compile the server (for when you aren’t using a pre-built binary), you will need:

  • The latest version of Go.
  • A compatible Linux operating system: Debian-based, Arch, Fedora. Others may work but are not tested.
  • git and bash in your $PATH.
  • gcc is NOT currently required.
  • mdbook must be in your $PATH to compile Venator with embedded documentation.

To run the server, you will need:

  • PostgreSQL v14 or newer (check for issues regarding newly released PG versions).

To run the server, you will also want:

  • A reverse proxy, such as Caddy or Nginx.
  • A domain name (especially if you want to use federation).

Important

Once you have set your “server name”, it cannot be changed. This means, if you start off without a domain, and later want to switch to using one, you will have to delete your database and start fresh.

Compiling

If you wish to compile Venator (instead of using the binaries created by CI or attached to releases), you can do so with the handy build.sh script located at the root of this repository. While using this script in particular is not required (compiling with plain go build is sufficient), the build script conveniently injects build metadata into the binary for accurate version reporting, and offers shorthands to compile static and release-optimised builds.

Note

You do not need to compile Venator to run it. CI produces static binaries for AMD64 and ARM64 on each push to dev, and static binaries are also attached to each release.

Unless you need a dynamic binary, or are planning on hacking on Venator, you likely do not need to compile.

Please skip to Installing if you just want to install Venator.

With the build script

To get started, make sure you have the prerequisites detailed above. Then, you can clone the repository:

git clone https://codeberg.org/timedout/venator.git && cd venator

And then run the build script to produce a binary at ./bin/venatorctl:

./build.sh
#- will build dynamically-linked binary
#- will build debug binary (without optimizations)
#- Tag associated with the latest commit: N/A
#- Latest tag: N/A
#- Latest commit hash: ec0f1d0
#- Dirty? yes
#- Build date: 2026.03.09T19.48.00Z
#- Golang version: go1.26.0
#- OS/Arch: linux/amd64
#
#Compiling Venator
#...
#codeberg.org/timedout/venator/cmd/venatorctl
#
#real    0m1.941s
#user    0m1.779s
#sys     0m0.785s

Notice how the first two lines say will build dynamically-linked binary and will build debug binary (without optimizations)? This is because by default, the script will create a debug-oriented build. While this is still plenty fast, it is dynamically linked, and retains debug symbols, meaning it’s a few mebibytes larger than necessary for most people. If you aren’t planning on running through Venator with a debugger, you may wish to instead build a high-performance and/or static binary.

To compile a static binary, pass -static to build.sh:

./build.sh -static && file ./bin/venatorctl
#- will build static-linked binary without CGO (experimental!)
#- will build debug binary (without optimizations)
# ...
#./bin/venatorctl: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=..., BuildID[sha1]=..., with debug_info, not stripped

To compile a “release” binary (one without debug symbols), pass -release:

./build.sh -release && file ./bin/venatorctl
#- will build dynamically-linked binary
#- will build release binary (with optimizations)
#...
#./bin/venatorctl: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=..., BuildID[sha1]=..., stripped

You can even combine these flags (in any order) to compile a release+static binary:

./build.sh -static -release && file ./bin/venatorctl
#- will build static-linked binary without CGO (experimental!)
#- will build release binary (with optimizations)
#./bin/venatorctl: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=..., BuildID[sha1]=..., stripped

Without the build script

If for some reason you are unable to use the build script (consider opening an issue!), you can still compile without:

go build -o ./bin/ ./cmd/venatorctl

Note that this will produce a debug dynamic binary without any metadata. You will likely be unable to report bugs found when running this binary as it will not contain version data required to accurately troubleshoot problems.

Installing

In order to install Venator, you will first need a binary. These can be acquired from:

Please note that CI artefacts are zipped when downloaded - you will first need to unzip them before you can get the binary within.

Make sure you select the correct binary by checking the output of uname -m:

OutputVersion
x86_64AMD64
aarch64ARM64

Other architectures may work, but are not built in CI, nor tested. Downloading the wrong binary will result in an error message like exec format error: ./venator-arm64 when you try to run it.

Configuring

Important

The rest of this guide assumes your binary (from compiling or installing) is located at /usr/local/bin/venatorctl, and that /usr/local/bin is in your $PATH. It also assumes you have read+write+execute access to /etc/matrix-venator.

Before you daemonise Venator, you’re going to want to create the template configuration file. When Venator is unable to load a configuration file, it will create one with some default values, so we’re going to use this to create a sparse config file that you can modify with your values.

First, create the configuration file by running venatorctl --config /etc/matrix-venator/config.yaml. Upon success, this will create a YAML file at that location with some example values. You must edit at least:

  • server_name - set this to your server name (the part after the : in your user IDs).
  • database.url - set this to the connection URI of your postgres server. Must contain the username, password, host, and database name for the connection.

Caution

After you start the server for the first time the server_name cannot be changed. Make sure you’re certain before you hit run!

You may also wish to modify the other options, such as the registration.token (to change it to one of your choosing), changing the password requirements, increasing the max_request_bytes (to allow larger file uploads), or modifying the listeners.

All available configuration options are listed here: Configuration Reference.

Importing a previous installation’s signing key

It is possible to import another installation’s server signing key, provided you have it in a file with the format of ed25519 KeyID PrivateKeyPart, for example: ed25519 a_bcde hnBjtF9w9AQAWfnhAHIV3fdu9QH0YX1xWlb0qEPjE4w

You can then import this key via venatorctl signing-key import path/to/file. Once you confirm you want to import it, it will be imported as an “expired” key, meaning it can no longer be used to sign new events. It can, however, still be used to verify events sent from before you set up Venator.

Tip

If, for some reason, you wish to continue using the imported key to sign new events, you will need to manually do so via postgres: UPDATE owned_signing_keys SET expired_ts = NULL;.

While technically supported, you should not have multiple active signing keys - if Venator automatically generated one, you should invalidate it before continuing with venatorctl signing-key invalidate 'KEY_ID'. Again, once a key is expired, it cannot be used ever again.

Exporting your current key

If you wish to migrate your deployment to another homeserver implementation, you can export your active signing key into the synapse format with venatorctl signing-key export. This does not expire the key, so it can be re-used as an active key in another deployment (as long as it has the same server name).

Starting the server

To start Venator after configuring it, you can just run the binary like you did the first time:

venatorctl --config /etc/matrix-venator/config.yaml
#=== Venator v0.0.1-dev ===
#Parsing command line flags...
#Loading configuration from  /etc/matrix-venator/config.yaml...
#Initialising logging...
#Dropping output into logging system...
#2026-03-09T19:84:00Z DBG Validating configuration
#2026-03-09T19:84:00Z INF Initialising server
#2026-03-09T19:84:00Z INF running database migrations
#2026-03-09T19:84:00Z INF finished running database migrations elapsed_ms=181
#2026-03-09T19:84:00Z WRN no signing key found, generating new one. If this was not expected, I hope you have a backup of the one you expected.
#2026-03-09T19:84:00Z INF generated new signing key key_id=ed25519:vgJGqQ
#2026-03-09T19:84:00Z INF loaded signing key key_id=ed25519:vgJGqQ
#2026-03-09T19:84:00Z INF initialising media repository
#2026-03-09T19:84:00Z INF media repository initialised elapsed_ms=2
#2026-03-09T19:84:00Z INF Passing off server startup to server instance
#2026-03-09T19:84:00Z INF Starting server on
#2026-03-09T19:84:00Z INF server started. ^C to shut down.
#2026-03-09T19:84:00Z INF starting listener address=:8008 tls=false

If your configuration is malformed in such a way that Venator would not be able to operate, starting the server will fail, and it will tell you what you need to change.

As soon as you see server started. and starting listener, your server is ready to go! Keep it running like this for the next step.

Creating your first user

After you’ve started the server, there will be no users. There’s two ways you can register users on Venator: with a Matrix client, or with the venatorctl command itself.

With a Matrix client

If registration is enabled, you can just use a client of your choosing to register on the server. Open a client such as Element Web, Cinny, Sable, or Commet, and plug in your server name. From there, go to “register”, and put in the username and password you desire.

You will likely be challenged to supply the token that is under the registration section of your configuration. This is to prevent automated scripts or abusive users from finding your server, and registering accounts without your supervision.

Upon registering the first user, you will be granted admin, which allows you to control things that happen on your deployment via the admin API.

Any users registered after the first will simply be standard users who have no special control or rights on the server.

With the venatorctl command

If admin_pre_shared_secret is set, you can create the first user with venatorctl admin users create:

venatorctl --config=/etc/matrix-venator/config.yaml admin users create --admin d34db33f
#Will use generated password: "VNYYYL7EsbQA5ylkuQehHwzlhmE0Nyv3"
#Warning: Using pre-shared secret to authenticate with http://127.0.0.1:8008.
#Creating user "d34db33f"...
#Successfully created user "d34db33f".
#Successfully made "d34db33f" an administrator.

This will create the user @d34db33f:your.server.example, with the password VNYYYL7EsbQA5ylkuQehHwzlhmE0Nyv3. Since --admin was passed too, this user is automatically created as an administrator.

Forgot to pass --admin? You can use venatorctl admin users make-admin <localpart> at any time.

Daemonising

In order to run Venator 24/7, you will want to first interrupt the running server by hitting CTRL+C (running concurrent instances of Venator is not safe), and then install this unit file to /etc/systemd/system/matrix-venator.service.

You can then systemctl daemon-reload to init the unit file, and then use systemctl enable --now matrix-venator.service to both enable the service at startup, and also start it immediately. Once start returns, you can check the status and most recent log lines of Venator by running systemctl status matrix-venator.service:

systemctl status matrix-venator.service
#● matrix-venator.service - Venator Matrix homeserver
#     Loaded: loaded (/etc/systemd/system/matrix-venator.service; enabled; preset: enabled)
#     Active: active (running) since Sun 2026-04-19 19:48:00 BST; 1h 0min ago
#       Docs: https://timedout.codeberg.page/venator
#   Main PID: 391244 (venatorctl)
#      Tasks: 10 (limit: 57189)
#     Memory: 45.9M (peak: 46.5M)
#        CPU: 24.509s
#     CGroup: /system.slice/matrix-venator.service
#             └─391244 /usr/local/bin/venatorctl run
#
#Apr 19 19:84:00 venator-staging matrix-venator[391244]: Initialising logging
#Apr 19 19:84:00 venator-staging matrix-venator[391244]: Switching output to configured logging stream
#Apr 19 19:84:00 venator-staging matrix-venator[391244]: 2026-04-19T19:84:00+01:00 INF Initialising server
#Apr 19 19:84:00 venator-staging matrix-venator[391244]: 2026-04-19T19:84:00+01:00 INF ServerNoticeManager.worker > Worker starting
#Apr 19 19:84:00 venator-staging matrix-venator[391244]: 2026-04-19T19:84:00+01:00 INF DeviceManager.worker > Worker starting
#Apr 19 19:84:00 venator-staging matrix-venator[391244]: 2026-04-19T19:84:00+01:00 INF Passing off server startup to server instance
#Apr 19 19:84:00 venator-staging matrix-venator[391244]: 2026-04-19T19:84:00+01:00 INF Starting 1 listeners...
#Apr 19 19:84:00 venator-staging matrix-venator[391244]: 2026-04-19T19:84:00+01:00 INF Server started. ^C to shut down.
#Apr 19 19:84:00 venator-staging matrix-venator[391244]: 2026-04-19T19:84:00+01:00 INF Starting listener address=0.0.0.0:8008 protocol=tcp tls=false
#Apr 19 19:84:00 venator-staging systemd[1]: Started matrix-venator.service - Venator Matrix homeserver.