# Generic deployment documentation

:::tip Getting help
If you run into any problems while setting up Continuwuity, ask us in
`#continuwuity:continuwuity.org` or [open an issue on
Forgejo][forgejo-new-issue].
:::

[forgejo-new-issue]: https://forgejo.ellis.link/continuwuation/continuwuity/issues/new

## Installing Continuwuity

### Prebuilt binary

Download the binary for your architecture (x86_64 or aarch64) -
run the `uname -m` to check which you need.

Prebuilt binaries are available from:

- **Tagged releases**: [see Release page][release-page]
- **Development builds**: CI artifacts from the `main` branch,
  [see `release-image.yml` for details][release-image]

The binaries require jemalloc and io_uring on the host system. Currently
we can't cross-build static binaries - contributions are welcome here.

[release-page]: https://forgejo.ellis.link/continuwuation/continuwuity/releases/
[release-image]: https://forgejo.ellis.link/continuwuation/continuwuity/actions/?workflow=release-image.yml

#### Performance-optimised builds

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.

If you're using Docker instead, equivalent performance-optimised
images are available with the `-maxperf` suffix (e.g.
`forgejo.ellis.link/continuwuation/continuwuity:latest-maxperf`).
These images use the `release-max-perf` build profile with
[link-time optimisation (LTO)][lto-rust-docs]
and, for amd64, target the haswell CPU architecture.

[lto-rust-docs]: https://doc.rust-lang.org/cargo/reference/profiles.html#lto

### Nix

Theres a Nix package defined in our flake, available for Linux and MacOS. Add continuwuity as an input to your flake, and use `inputs.continuwuity.packages.${system}.default` to get a working Continuwuity package.

If you simply wish to generate a binary using Nix, you can run `nix build git+https://forgejo.ellis.link/continuwuation/continuwuity` to generate a binary in `result/bin/conduwuit`.

### Compiling

Alternatively, you may compile the binary yourself.

#### Using Docker

See the [Building Docker Images](../development/index.mdx#building-docker-images)
section in the development documentation.

#### Manual

##### Dependencies

- Run `nix develop` to get a devshell with everything you need
- Or, install the following:
    - (On linux) `liburing-dev` on the compiling machine, and `liburing` on the target host
    - (On linux) `pkg-config` on the compiling machine to allow finding `liburing`
    - A C++ compiler and (on linux) `libclang` for RocksDB

##### Build

You can now build Continuwuity using `cargo build --release`.

Continuwuity supports various optional features that can be enabled during compilation. Please see the Cargo.toml file for a comprehensive list, or ask in our rooms.

## Adding a Continuwuity user

While Continuwuity can run as any user, it is better to use dedicated users for
different services. This also ensures that the file permissions
are set up correctly.

In Debian, you can use this command to create a Continuwuity user:

```bash
sudo adduser --system continuwuity --group --disabled-login --no-create-home
```

For distros without `adduser` (or where it's a symlink to `useradd`):

```bash
sudo useradd -r --shell /usr/bin/nologin --no-create-home continuwuity
```

## Setting up a systemd service

You can find an example unit for continuwuity below.
You may need to change the `ExecStart=` path to match where you placed the Continuwuity
binary if it is not in `/usr/bin/conduwuit`.

On systems where rsyslog is used alongside journald (i.e. Red Hat-based distros
and OpenSUSE), put `$EscapeControlCharactersOnReceive off` inside
`/etc/rsyslog.conf` to allow color in logs.

If you are using a different `database_path` than the systemd unit's
configured default (`/var/lib/conduwuit`), you need to add your path to the
systemd unit's `ReadWritePaths=`. You can do this by either directly editing
`conduwuit.service` and reloading systemd, or by running `systemctl edit conduwuit.service`
and entering the following:

```
[Service]
ReadWritePaths=/path/to/custom/database/path
```

### Example systemd Unit File

<details>
<summary>Click to expand systemd unit file (conduwuit.service)</summary>

```ini file="../../pkg/conduwuit.service"

```

</details>

You can also [view the file on Foregejo][systemd-file].

[systemd-file]: https://forgejo.ellis.link/continuwuation/continuwuity/src/branch/main/pkg/conduwuit.service

## Creating the Continuwuity configuration file

Now you need to create the Continuwuity configuration file in
`/etc/conduwuit/conduwuit.toml`. You can find an example configuration at
[conduwuit-example.toml](../reference/config.mdx).

**Please take a moment to read the config. You need to change at least the
server name.**

### Setting the correct file permissions

If you are using a dedicated user for Continuwuity, you need to allow it to
read the configuration. To do this, run:

```bash
sudo chown -R root:root /etc/conduwuit
sudo chmod -R 755 /etc/conduwuit
```

If you use the default database path you also need to run this:

```bash
sudo mkdir -p /var/lib/conduwuit/
sudo chown -R continuwuity:continuwuity /var/lib/conduwuit/
sudo chmod 700 /var/lib/conduwuit/
```

## Exposing ports in the firewall or the router

Matrix's default federation port is **:8448**, and clients use port **:443**. You will need to
expose these ports on your firewall or router. If you use UFW, the commands to allow them
are: `ufw allow 8448/tcp` and `ufw allow 443/tcp`.

:::tip Alternative port/domain setups
If you would like to use only port 443, a different port, or a subdomain for the homeserver, you will need to set up `.well-known` delegation. Consult the `[global.well_known]` section of the config file, and the [**Delegation/Split-domain**](../advanced/delegation) page to learn more about these kinds of deployments.
:::

## Setting up the Reverse Proxy

### Caddy

Caddy is the recommended reverse proxy as it is easy to use, has good defaults,
and handle TLS certificates automatically. After installing Caddy via your preferred
method, create `/etc/caddy/conf.d/conduwuit_caddyfile` and enter the following
(substitute `example.com` with your actual server name):

```
example.com, example.com:8448 {
    # TCP reverse_proxy
    reverse_proxy 127.0.0.1:8008
}
```

That's it! Just start and enable the service and you're set.

```bash
sudo systemctl enable --now caddy
```

### Other Reverse Proxies

Normally, your reverse proxy should route everything from port :8448 and :443 back to Continuwuity.

For more granular controls, you will need to proxy everything under these following routes:

- `/_matrix/` - core Matrix APIs, which includes:

  - `/_matrix/federation` and `/_matrix/key` - core Server-Server APIs. These should be available on port :8448

  - `/_matrix/client` - core Client-Server APIs. These should be available on port :443

- `/_conduwuit/` and `/_continuwuity/` - ad-hoc Continuwuity routes for password resets, email verification, and server details such as `/local_user_count` and `/server_version`.

You can optionally reverse proxy the following individual routes:

- `/.well-known/matrix/client` and `/.well-known/matrix/server` if using
  Continuwuity to perform delegation (see the `[global.well_known]` config section)
- `/.well-known/matrix/support` if using Continuwuity to send the homeserver admin
  [contact and support page][well-known-support]
- `/` and `/_continuwuity/logo.svg` if you would like to see the Continuwuity landing page

Refer to the respective software's documentation and online guides on how to do so.

[well-known-support]: https://spec.matrix.org/v1.18/client-server-api/#getwell-knownmatrixsupport

#### Caveats for specific reverse proxies

- Lighttpd is not supported as it appears to interfere with the `X-Matrix` Authorization
header, making federation non-functional. If you find a workaround, please share it so we can add it to this documentation.

- If using Apache, you need to use `nocanon` in your `ProxyPass` directive to prevent httpd from interfering with the `X-Matrix` header (note that Apache is not ideal as a general reverse proxy, so we discourage using it if alternatives are available).

- If using Nginx, you need to pass the request URI to Continuwuity using `$request_uri`, like this:

    - `proxy_pass http://127.0.0.1:6167$request_uri;`
    - `proxy_pass http://127.0.0.1:6167;`

    Furthermore, Nginx users need to increase the `client_max_body_size` setting (default is 1M) to match the `max_request_size` defined in conduwuit.toml.

## Starting Your Server

Now you can start Continuwuity with:

```bash
sudo systemctl start conduwuit
```

Set it to start automatically when your system boots with:

```bash
sudo systemctl enable conduwuit
```

Check Continuwuity logs with the following command:

```bash
sudo journalctl -u conduwuit.service
```

If Continuwuity has successfully initialized, you'll see output as below.

```
In order to use your new homeserver, you need to create its
first user account.
Open your Matrix client of choice and register an account
on example.com using registration token x5keUZ811RqvLsNa .
Pick your own username and password!
```

You can then open [a Matrix client][matrix-clients],
enter your homeserver address, and register with the provided token.
By default, the first user is the instance's first admin. They will be added
to the `#admin:example.com` room and be able to [issue admin commands](../reference/admin/index.md).

[matrix-clients]: https://matrix.org/ecosystem/clients

## How do I know it works?

To check if your server can communicate with other homeservers,
use an external testing tool:

- [Matrix Connectivity Tester](https://federationtester.mtrnord.blog/)
- [Matrix Federation Tester](https://federationtester.matrix.org/)

If you can register your account but cannot join federated rooms, check your configuration
and verify that your federation endpoints are opened and forwarded correctly.

As a quick health check, you can also use these cURL commands:

```bash
curl https://example.com/_conduwuit/server_version

# If using port 8448
curl https://example.com:8448/_conduwuit/server_version

# If federation is enabled
curl https://example.com:8448/_matrix/federation/v1/version

# For client-server endpoints
curl https://example.com/_matrix/client/versions
```

## What's next?

- For smooth federation, set up a caching resolver according to the [**DNS tuning guide**](../advanced/dns.mdx) (recommended)
- For Audio/Video call functionality see the [**Calls**](../calls.md) page.
- Consult the [Maintenance](../maintenance.mdx) page for guidance on maintaining your homeserver.
- If you want to set up an appservice, take a look at the [**Appservice Guide**](../appservices.md).
