feat: Add voice and new web app to self hosted files (#196)

* chore: Use v0.11.1 for now as v0.11.x>1 contain emergency prod-only fix

This commit was made without the use of generative AI.

Signed-off-by: Jacob Schlecht <dadadah@echoha.us>

* feat: add voice to the compose, caddyfile, and livekit config

Web section of the compose is commented out for now

Added section to readme about the name of the project changing

This commit was made without the use of generative AI.

Signed-off-by: Jacob Schlecht <dadadah@echoha.us>

* chore: update many references to Revolt to reference Stoat

Signed-off-by: Jacob Schlecht <dadadah@echoha.us>

* feat: Add new dockerized web container

This commit was made without the use of generative AI.

Signed-off-by: Jacob Schlecht <dadadah@echoha.us>

* feat: Confirm reconfiguration if Revolt.toml exists

Also fix  not outputing new env vars to .env.web

This commit was made without the use of generative AI.

Signed-off-by: Jacob Schlecht <dadadah@echoha.us>

* feat: Add a migration script to make upgrading to voice easier

This commit was made without the use of generative AI.

Signed-off-by: Jacob Schlecht <dadadah@echoha.us>

* fix: Use old referral code

This commit was made without the use of generative AI.

Signed-off-by: Jacob Schlecht <dadadah@echoha.us>

---------

Signed-off-by: Jacob Schlecht <dadadah@echoha.us>
Co-authored-by: Declan Chidlow <accounts@vale.rocks>
This commit is contained in:
Jacob Schlecht
2026-02-18 20:38:03 -07:00
committed by GitHub
parent 340484159e
commit 54a88cf6cb
7 changed files with 191 additions and 38 deletions

View File

@@ -34,5 +34,19 @@
} }
} }
route /livekit* {
uri strip_prefix /livekit
reverse_proxy http://livekit:7880 {
header_down Location "^/" "/livekit/"
}
}
route /ingress* {
uri strip_prefix /ingress
reverse_proxy http://voice-ingress:8500 {
header_down Location "^/" "/ingress/"
}
}
reverse_proxy http://web:5000 reverse_proxy http://web:5000
} }

View File

@@ -2,12 +2,12 @@
<h1> <h1>
Stoat Self-Hosted Stoat Self-Hosted
[![Stars](https://img.shields.io/github/stars/revoltchat/self-hosted?style=flat-square&logoColor=white)](https://github.com/revoltchat/self-hosted/stargazers) [![Stars](https://img.shields.io/github/stars/stoatchat/self-hosted?style=flat-square&logoColor=white)](https://github.com/stoatchat/self-hosted/stargazers)
[![Forks](https://img.shields.io/github/forks/revoltchat/self-hosted?style=flat-square&logoColor=white)](https://github.com/revoltchat/self-hosted/network/members) [![Forks](https://img.shields.io/github/forks/stoatchat/self-hosted?style=flat-square&logoColor=white)](https://github.com/stoatchat/self-hosted/network/members)
[![Pull Requests](https://img.shields.io/github/issues-pr/revoltchat/self-hosted?style=flat-square&logoColor=white)](https://github.com/revoltchat/self-hosted/pulls) [![Pull Requests](https://img.shields.io/github/issues-pr/stoatchat/self-hosted?style=flat-square&logoColor=white)](https://github.com/stoatchat/self-hosted/pulls)
[![Issues](https://img.shields.io/github/issues/revoltchat/self-hosted?style=flat-square&logoColor=white)](https://github.com/revoltchat/self-hosted/issues) [![Issues](https://img.shields.io/github/issues/stoatchat/self-hosted?style=flat-square&logoColor=white)](https://github.com/stoatchat/self-hosted/issues)
[![Contributors](https://img.shields.io/github/contributors/revoltchat/self-hosted?style=flat-square&logoColor=white)](https://github.com/revoltchat/self-hosted/graphs/contributors) [![Contributors](https://img.shields.io/github/contributors/stoatchat/self-hosted?style=flat-square&logoColor=white)](https://github.com/stoatchat/self-hosted/graphs/contributors)
[![License](https://img.shields.io/github/license/revoltchat/self-hosted?style=flat-square&logoColor=white)](https://github.com/revoltchat/self-hosted/blob/main/LICENSE) [![License](https://img.shields.io/github/license/stoatchat/self-hosted?style=flat-square&logoColor=white)](https://github.com/stoatchat/self-hosted/blob/main/LICENSE)
</h1> </h1>
Self-hosting Stoat using Docker Self-hosting Stoat using Docker
</div> </div>
@@ -17,18 +17,14 @@ This repository contains configurations and instructions that can be used for de
> [!WARNING] > [!WARNING]
> If you are updating an instance from before November 28, 2024, please consult the [notices section](#notices) at the bottom. > If you are updating an instance from before November 28, 2024, please consult the [notices section](#notices) at the bottom.
> If you are updating an instance from before October 5, 2025, please consult the [notices section](#notices) at the bottom.
> If you are updating an instance from before February 18, 2026, please consult the [notices section](#notices) at the bottom.
> [!IMPORTANT] > [!IMPORTANT]
> A list of security advisories is [provided at the bottom](#security-advisories). > A list of security advisories is [provided at the bottom](#security-advisories).
> [!NOTE] > [!NOTE]
> Please consult _[What can I do with Stoat, and how do I self-host?](https://developers.revolt.chat/faq.html#admonition-what-can-i-do-with-revolt-and-how-do-i-self-host)_ on our developer site for information about licensing and brand use. > Please consult _[What can I do with Stoat and how do I self-host?](https://developers.stoat.chat/faq)_ on our developer site for information about licensing and brand use.
> [!NOTE]
> amd64 builds are not currently available for the web client.
> [!NOTE]
> This guide does not include working voice channels ([#138](https://github.com/revoltchat/self-hosted/pull/138#issuecomment-2762682655)). A [rework](https://github.com/revoltchat/backend/issues/313) is currently in progress.
## Table of Contents ## Table of Contents
@@ -102,6 +98,8 @@ apt-get update && apt-get upgrade -y
ufw allow ssh ufw allow ssh
ufw allow http ufw allow http
ufw allow https ufw allow https
ufw allow 7881/tcp
ufw allow 50000:50100/udp
ufw default deny ufw default deny
ufw enable ufw enable
@@ -141,7 +139,7 @@ apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docke
Now, we can pull in the configuration for Stoat: Now, we can pull in the configuration for Stoat:
```bash ```bash
git clone https://github.com/revoltchat/self-hosted stoat git clone https://github.com/stoatchat/self-hosted stoat
cd stoat cd stoat
``` ```
@@ -152,7 +150,7 @@ chmod +x ./generate_config.sh
./generate_config.sh your.domain ./generate_config.sh your.domain
``` ```
You can find [more options here](https://github.com/revoltchat/backend/blob/stable/crates/core/config/Revolt.toml), some noteworthy configuration options: You can find [more options here](https://github.com/stoatchat/stoatchat/blob/stable/crates/core/config/Revolt.toml), some noteworthy configuration options:
- Email verification - Email verification
- Captcha - Captcha
@@ -187,7 +185,7 @@ Pull the latest version of this repository:
git pull git pull
``` ```
Check if your configuration file is correct by opening [the reference config file](https://github.com/revoltchat/backend/blob/df074260196f5ed246e6360d8e81ece84d8d9549/crates/core/config/Revolt.toml) and your `Revolt.toml` to compare changes. Check if your configuration file is correct by opening [the reference config file](https://github.com/stoatchat/stoatchat/blob/df074260196f5ed246e6360d8e81ece84d8d9549/crates/core/config/Revolt.toml) and your `Revolt.toml` to compare changes.
Then pull all the latest images: Then pull all the latest images:
@@ -213,7 +211,7 @@ Prerequisites before continuing:
Clone this repository. Clone this repository.
```bash ```bash
git clone https://github.com/revoltchat/self-hosted stoat git clone https://github.com/stoatchat/self-hosted stoat
cd stoat cd stoat
``` ```
@@ -225,7 +223,7 @@ Create `.env.web` and download `Revolt.toml`, then modify them according to your
```bash ```bash
echo "HOSTNAME=http://local.stoat.chat" > .env.web echo "HOSTNAME=http://local.stoat.chat" > .env.web
echo "REVOLT_PUBLIC_URL=http://local.stoat.chat/api" >> .env.web echo "REVOLT_PUBLIC_URL=http://local.stoat.chat/api" >> .env.web
wget -O Revolt.toml https://raw.githubusercontent.com/revoltchat/backend/main/crates/core/config/Revolt.toml wget -O Revolt.toml https://raw.githubusercontent.com/stoatchat/stoatchat/main/crates/core/config/Revolt.toml
``` ```
Then start Stoat: Then start Stoat:
@@ -361,7 +359,7 @@ db.invites.insertOne({ _id: "enter_an_invite_code_here" })
> ``` > ```
> [!IMPORTANT] > [!IMPORTANT]
> If you deployed Stoat before [2023-04-21](https://github.com/revoltchat/backend/commit/32542a822e3de0fc8cc7b29af46c54a9284ee2de), you may have to flush your Redis database. > If you deployed Stoat before [2023-04-21](https://github.com/stoatchat/stoatchat/commit/32542a822e3de0fc8cc7b29af46c54a9284ee2de), you may have to flush your Redis database.
> >
> ```bash > ```bash
> # for stock Redis and older KeyDB images: > # for stock Redis and older KeyDB images:
@@ -416,9 +414,31 @@ db.invites.insertOne({ _id: "enter_an_invite_code_here" })
> >
> - Added `rabbit` (RabbitMQ) and `pushd` (Stoat push daemon) > - Added `rabbit` (RabbitMQ) and `pushd` (Stoat push daemon)
> [!IMPORTANT]
> As of October 5, 2025, the following breaking changes have been applied:
>
> - Rename docker compose project from revolt to stoat
>
> These will NOT automatically be applied to your environment.
>
> You must run the environment with the old revolt name to apply the update. After you run `docker compose pull` during the upgrade procedure, you must run `docker compose -p revolt down`. You may then continue with the upgrade procedure.
> [!IMPORTANT]
> As of February 18, 2026, livekit support and the new web app was added to the self host repo. In order to utilize the new voice features and the new web app, you must add configuration.
>
> Before beginning the upgrade process, please do the following:
>
> ```bash
> git pull
> chmod +x migrations/20260218-voice-config.sh
> ./migrations/20260218-voice-config.sh your.domain
> ```
>
> This should append the new configurations to your existing configuration. Only run this migration once, as if you run it more than once your instance will fail to start. You may then continue with the upgrade procedure.
## Security Advisories ## Security Advisories
- (`2024-06-21`) [GHSA-f26h-rqjq-qqjq revoltchat/backend: Unrestricted account creation.](https://github.com/revoltchat/backend/security/advisories/GHSA-f26h-rqjq-qqjq) - (`2024-06-21`) [GHSA-f26h-rqjq-qqjq stoatchat/stoatchat: Unrestricted account creation.](https://github.com/stoatchat/stoatchat/security/advisories/GHSA-f26h-rqjq-qqjq)
- (`2024-12-17`) [GHSA-7f9x-pm3g-j7p4 revoltchat/january: January service can call itself recursively, causing heavy load.](https://github.com/revoltchat/january/security/advisories/GHSA-7f9x-pm3g-j7p4) - (`2024-12-17`) [GHSA-7f9x-pm3g-j7p4 revoltchat/january: January service can call itself recursively, causing heavy load.](https://github.com/revoltchat/january/security/advisories/GHSA-7f9x-pm3g-j7p4)
- (`2025-02-10`) [GHSA-8684-rvfj-v3jq revoltchat/backend: Webhook tokens are freely accessible for users with read permissions.](https://github.com/revoltchat/backend/security/advisories/GHSA-8684-rvfj-v3jq) - (`2025-02-10`) [GHSA-8684-rvfj-v3jq stoatchat/stoatchat: Webhook tokens are freely accessible for users with read permissions.](https://github.com/stoatchat/stoatchat/security/advisories/GHSA-8684-rvfj-v3jq)
- (`2025-02-10`) [GHSA-h7h6-7pxm-mc66 revoltchat/backend: Nearby message fetch requests can be crafted to fetch entire message history.](https://github.com/revoltchat/backend/security/advisories/GHSA-h7h6-7pxm-mc66) - (`2025-02-10`) [GHSA-h7h6-7pxm-mc66 stoatchat/stoatchat: Nearby message fetch requests can be crafted to fetch entire message history.](https://github.com/stoatchat/stoatchat/security/advisories/GHSA-h7h6-7pxm-mc66)

View File

@@ -73,7 +73,7 @@ services:
# API server # API server
api: api:
image: ghcr.io/revoltchat/server:20250930-2 image: ghcr.io/stoatchat/api:v0.11.1
depends_on: depends_on:
database: database:
condition: service_healthy condition: service_healthy
@@ -89,7 +89,7 @@ services:
# Events service # Events service
events: events:
image: ghcr.io/revoltchat/bonfire:20250930-2 image: ghcr.io/stoatchat/events:v0.11.1
depends_on: depends_on:
database: database:
condition: service_healthy condition: service_healthy
@@ -101,15 +101,9 @@ services:
target: /Revolt.toml target: /Revolt.toml
restart: always restart: always
# Web App
web:
image: ghcr.io/revoltchat/client:master
restart: always
env_file: .env.web
# File server # File server
autumn: autumn:
image: ghcr.io/revoltchat/autumn:20250930-2 image: ghcr.io/stoatchat/file-server:v0.11.1
depends_on: depends_on:
database: database:
condition: service_healthy condition: service_healthy
@@ -123,7 +117,7 @@ services:
# Metadata and image proxy # Metadata and image proxy
january: january:
image: ghcr.io/revoltchat/january:20250930-2 image: ghcr.io/stoatchat/proxy:v0.11.1
volumes: volumes:
- type: bind - type: bind
source: ./Revolt.toml source: ./Revolt.toml
@@ -132,7 +126,7 @@ services:
# Tenor proxy # Tenor proxy
gifbox: gifbox:
image: ghcr.io/revoltchat/gifbox:20250930-2 image: ghcr.io/stoatchat/gifbox:v0.11.1
volumes: volumes:
- type: bind - type: bind
source: ./Revolt.toml source: ./Revolt.toml
@@ -141,7 +135,7 @@ services:
# Regular task daemon # Regular task daemon
crond: crond:
image: ghcr.io/revoltchat/crond:20250930-2 image: ghcr.io/stoatchat/crond:v0.11.1
depends_on: depends_on:
database: database:
condition: service_healthy condition: service_healthy
@@ -155,7 +149,7 @@ services:
# Push notification daemon # Push notification daemon
pushd: pushd:
image: ghcr.io/revoltchat/pushd:20250930-2 image: ghcr.io/stoatchat/pushd:v0.11.1
depends_on: depends_on:
database: database:
condition: service_healthy condition: service_healthy
@@ -169,6 +163,30 @@ services:
target: /Revolt.toml target: /Revolt.toml
restart: always restart: always
# Voice ingress daemon
voice-ingress:
image: ghcr.io/stoatchat/voice-ingress:v0.11.1
restart: always
depends_on:
database:
condition: service_healthy
rabbit:
condition: service_healthy
volumes:
- type: bind
source: ./Revolt.toml
target: /Revolt.toml
livekit:
image: ghcr.io/stoatchat/livekit-server:v1.9.6
command: --config /etc/livekit.yml
volumes:
- ./livekit.yml:/etc/livekit.yml
ports:
- "7881:7881"
- "50000-50100:50000-50100/udp"
restart: always
# Create buckets for minio. # Create buckets for minio.
createbuckets: createbuckets:
image: docker.io/minio/mc image: docker.io/minio/mc
@@ -183,3 +201,9 @@ services:
/usr/bin/mc mb minio/revolt-uploads; /usr/bin/mc mb minio/revolt-uploads;
exit 0; exit 0;
" "
# Web App
web:
image: ghcr.io/stoatchat/for-web:6c5970f
restart: always
env_file: .env.web

View File

@@ -1,17 +1,36 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# set hostname for Caddy if test -f "Revolt.toml"; then
echo "Existing config found, running this script will overwrite your existing config. Are you sure you'd like to reconfigure?"
select yn in "Yes" "No"; do
case $yn in
No ) exit;;
Yes ) break;;
esac
done
fi
# set hostname for Caddy and vite variables
echo "HOSTNAME=https://$1" > .env.web echo "HOSTNAME=https://$1" > .env.web
echo "REVOLT_PUBLIC_URL=https://$1/api" >> .env.web echo "REVOLT_PUBLIC_URL=https://$1/api" >> .env.web
echo "VITE_API_URL=https://$1/api" >> .env.web
echo "VITE_WS_URL=wss://$1/ws" >> .env.web
echo "VITE_MEDIA_URL=https://$1/autumn" >> .env.web
echo "VITE_PROXY_URL=https://$1/january" >> .env.web
# hostnames # hostnames
echo "[hosts]" >> Revolt.toml echo "[hosts]" > Revolt.toml
echo "app = \"https://$1\"" >> Revolt.toml echo "app = \"https://$1\"" >> Revolt.toml
echo "api = \"https://$1/api\"" >> Revolt.toml echo "api = \"https://$1/api\"" >> Revolt.toml
echo "events = \"wss://$1/ws\"" >> Revolt.toml echo "events = \"wss://$1/ws\"" >> Revolt.toml
echo "autumn = \"https://$1/autumn\"" >> Revolt.toml echo "autumn = \"https://$1/autumn\"" >> Revolt.toml
echo "january = \"https://$1/january\"" >> Revolt.toml echo "january = \"https://$1/january\"" >> Revolt.toml
# livekit hostname
echo "" >> Revolt.toml
echo "[hosts.livekit]" >> Revolt.toml
echo "worldwide = \"wss://$1/livekit\"" >> Revolt.toml
# VAPID keys # VAPID keys
echo "" >> Revolt.toml echo "" >> Revolt.toml
echo "[pushd.vapid]" >> Revolt.toml echo "[pushd.vapid]" >> Revolt.toml
@@ -24,3 +43,25 @@ rm vapid_private.pem
echo "" >> Revolt.toml echo "" >> Revolt.toml
echo "[files]" >> Revolt.toml echo "[files]" >> Revolt.toml
echo "encryption_key = \"$(openssl rand -base64 32)\"" >> Revolt.toml echo "encryption_key = \"$(openssl rand -base64 32)\"" >> Revolt.toml
livekit_key=$(openssl rand -hex 6)
livekit_secret=$(openssl rand -hex 24)
# livekit key
echo "" >> livekit.yml
echo "keys:" >> livekit.yml
echo " $livekit_key: $livekit_secret" >> livekit.yml
echo "" >> livekit.yml
echo "webhook:" >> livekit.yml
echo " api_key: $livekit_key" >> livekit.yml
echo " urls:" >> livekit.yml
echo " - \"https://$1/ingress/worldwide\"" >> livekit.yml
# livekit config
echo "" >> Revolt.toml
echo "[api.livekit.nodes.worldwide]" >> Revolt.toml
echo "url = \"https://$1/livekit\"" >> Revolt.toml
echo "lat = 0.0" >> Revolt.toml
echo "lon = 0.0" >> Revolt.toml
echo "key = \"$livekit_key\"" >> Revolt.toml
echo "secret = \"$livekit_secret\"" >> Revolt.toml

9
livekit.yml Normal file
View File

@@ -0,0 +1,9 @@
rtc:
use_external_ip: true
port_range_start: 50000
port_range_end: 50100
tcp_port: 7881
redis:
address: redis:6379
turn:
enabled: false

View File

@@ -1,4 +1,4 @@
// THIS FILE IS TAILORED TO REVOLT PRODUCTION // THIS FILE IS TAILORED TO STOAT PRODUCTION
// MIGRATING FROM A BACKUP & EXISTING CDN NODE // MIGRATING FROM A BACKUP & EXISTING CDN NODE
// INTO BACKBLAZE B2 // INTO BACKBLAZE B2
// //

View File

@@ -0,0 +1,45 @@
#!/usr/bin/env bash
#
# This script is intended for appending the configuration values for livekit.
# Please run this script from the project directory like so:
# ./migrations/20260218-voice-config.sh your.domain
# Append the new web environment variables to the .env.web
echo "Adding new environment variables to .env.web for new web app..."
echo "VITE_API_URL=https://$1/api" >> .env.web
echo "VITE_WS_URL=wss://$1/ws" >> .env.web
echo "VITE_MEDIA_URL=https://$1/autumn" >> .env.web
echo "VITE_PROXY_URL=https://$1/january" >> .env.web
# Append the hosts.livekit configuration
echo "Adding livekit worldwide host to Revolt.toml..."
echo "" >> Revolt.toml
echo "[hosts.livekit]" >> Revolt.toml
echo "worldwide = \"wss://$1/livekit\"" >> Revolt.toml
# Create livekit key and secret
livekit_key=$(openssl rand -hex 6)
livekit_secret=$(openssl rand -hex 24)
# Append keys and webhook to livekit.yml
echo "Adding livekit key and webhook configuration to livekit.yml..."
echo "" >> livekit.yml
echo "keys:" >> livekit.yml
echo " $livekit_key: $livekit_secret" >> livekit.yml
echo "" >> livekit.yml
echo "webhook:" >> livekit.yml
echo " api_key: $livekit_key" >> livekit.yml
echo " urls:" >> livekit.yml
echo " - \"https://$1/ingress/worldwide\"" >> livekit.yml
# Append livekit node configuration to Revolt.toml
echo "Adding livekit node configuration to Revolt.toml..."
echo "" >> Revolt.toml
echo "[api.livekit.nodes.worldwide]" >> Revolt.toml
echo "url = \"https://$1/livekit\"" >> Revolt.toml
echo "lat = 0.0" >> Revolt.toml
echo "lon = 0.0" >> Revolt.toml
echo "key = \"$livekit_key\"" >> Revolt.toml
echo "secret = \"$livekit_secret\"" >> Revolt.toml
echo "Done! <3"