Run a server
This page takes you from a fresh checkout to a running OriginChats server. It covers originchats-osl, the current server. The older Python originchats server is legacy, and its commands don’t apply here.
Follow the server pages in order: this quickstart, then Configuration, Deployment, Storage and backups, and Updating.
Requirements
Section titled “Requirements”- The OSL CLI. OSL compiles to Go, so the machine also needs a Go toolchain.
src/go.moddeclares the Go version. - Git, if you want to use the updater later.
- Network access to Rotur (
rotur.devandapi.rotur.dev). Setup uses Rotur to identify the owner account.
Build the server
Section titled “Build the server”git clone https://git.rotur.dev/originchats/server-osl.git ~/originchats-oslcd ~/originchats-osl/srcosl compile main.osl -o ../originchats-oslcd ..This produces the originchats-osl executable in the repository root. Git ignores it.
The command line
Section titled “The command line”The executable has two commands.
| Command | What it does |
|---|---|
originchats-osl init [directory] |
Runs the interactive setup and creates a new database in directory. |
originchats-osl use <directory> |
Starts the server using the database in directory. |
A database directory holds everything one server stores: config.json, users, channels, messages, attachments, and the .env file with its secrets. One directory is one server.
Any other command, or no command, prints the usage and exits with status 1.
Create a database
Section titled “Create a database”Run setup against a new or empty directory:
./originchats-osl init ./dbIf you leave out the directory, setup asks for one and offers db as the default. ./db is the directory scripts/run.sh uses when you don’t pass one, and the repository’s .gitignore already ignores it.
Setup asks three things:
- Server name. Press Enter to accept
My originChats Server. - Server URL. The public address clients will use, such as
https://chat.example.com. It must start withhttp://orhttps://and include a host. A trailing/is removed. - Rotur login. Answer yes to open Rotur in a browser. Setup listens on
127.0.0.1:56199for the login callback and waits up to 120 seconds. If the port is in use, the browser can’t open, or the wait times out, setup asks you to paste a Rotur token instead. You can get one fromhttps://rotur.dev/auth.
Setup checks the token against Rotur. The account it belongs to becomes the server owner.
What setup creates
Section titled “What setup creates”Setup refuses to use a directory that already contains config.json or any other file. It builds the database in a hidden sibling directory and renames it into place only after every file is written, so a failed setup leaves nothing behind.
The new database contains:
config.jsonwithserver.name,server.url,server.owner.name, Rotur avatar and banner URLs forserver.iconandserver.banner, andsetup.oauth_callback_port. Everything else uses the defaults.users.jsonwith the owner account, holding theownerrole.roles.jsonwith four roles:owner,admin,moderator, anduser. See Manage a server.channels.jsonwithabout,announcements,welcome,general,random, andmods, split by two separators.- Empty
access.json,modlog.jsonl,rate_limits.json,reports.json,serverEmojis.json,serverStickers.json,threads_index.json, andwebhooks.json. - Directories for channel messages,
threads,users,polls,attachments,serverAssets,serverEmojis,serverStickers, andbackup. The server doesn’t write tobackup/; it’s there for your own copies. .envinside the database directory, holdingROTUR_TOKEN(the owner’s Rotur token).
Start the server
Section titled “Start the server”You can start the server directly or through the launcher.
Start directly
Section titled “Start directly”./originchats-osl use ./dbuse checks that the directory exists and contains config.json, changes into it, and loads .env. Variables already set in the process environment take priority over .env. It then validates the configuration, runs startup migrations, and starts HTTP and WebSocket service on one port.
By default the server listens on 127.0.0.1:5613. Change this with websocket.host and websocket.port.
Start with the launcher
Section titled “Start with the launcher”./scripts/run.sh # uses ./db./scripts/run.sh ~/chat-db # uses another database directoryscripts/run.sh is the recommended way to run a server. It:
- Recompiles
originchats-oslfrom the current source, without the build cache. - Runs
originchats-osl useon the database directory. - Restarts the server when it exits with status 75. The server exits with 75 only after an owner requests a restart or update through
server_maintenance. - Stops on any other exit status, and passes Ctrl+C or
SIGTERMon to the server.
Only servers started this way can restart or update themselves remotely. See Deployment.
run.sh doesn’t create a database. The directory must already exist and contain config.json, so run init first.
The repository’s opal.json also defines osl opal run serve, which runs scripts/run.sh.
Check that it works
Section titled “Check that it works”Request the public info page:
curl -i http://127.0.0.1:5613/infoThen connect a WebSocket client to /. The first frame the server sends is handshake. Check that:
val.server.urlandval.signing_urlare the public URL clients will connect to.val.auth_modeandval.capabilitiesmatch the login methods you want.val.attachmentsandval.limitsmatch your upload and message policy.
Log in as the owner and try channels_get, roles_list, users_list, and server_stats. Then log in as an ordinary user, because the owner bypasses channel permissions and can hide a broken setup.
Startup errors
Section titled “Startup errors”Startup errors print to the terminal and the process exits. run.sh doesn’t restart after these.
| Message | Fix |
|---|---|
Missing database directory |
Pass a directory to use. |
Database directory does not exist: <path> |
Check the path, or create the database with init. |
Database is not initialized: <path> |
The directory has no config.json. Run init on an empty directory. |
Invalid JSON in config.json: ... |
Fix the JSON syntax. |
Config value 'server.url' must be a complete http:// or https:// URL |
Set server.url to a full URL. |
Config value '<key>' must be a non-empty string |
Set server.name, server.owner.name, server.url, or websocket.host. |
Config value 'websocket.port' must be a port number between 1 and 65535 |
Use a whole number in range. |
Invalid notifications config: ..., Invalid automod config: ..., Invalid attachment compression config: ..., Invalid authentication config: ... |
See the matching section of Configuration. |
attachments.s3.<key> is required when attachment storage is s3 |
Set the S3 key in config.json or through its environment variable. |
unable to recover interrupted storage transaction |
See Storage and backups. |
If setup can’t open the browser callback, free port 56199 or paste a token by hand.
If the server runs but clients can’t reach it through your proxy, make sure the proxy forwards WebSocket upgrades on /. See Deployment.
