Skip to content

Install a server release

Citadel server releases are standalone ZIP archives. Download the archive for a supported operating system shown below from the GitHub Releases page, extract it, then run the included server. You do not need to clone the repository, install Rust, or compile anything.

Server archives are deliberately server-only: they contain the server binary, configuration, starter game script, maps directory, and any platform service files, but no client SDK or engine asset. Download a dedicated client SDK archive from the same release when you need one.

Each release also includes SHA256SUMS.txt. Download it beside the archive and verify the archive you selected before extracting it. The manifest lists all release assets, so do not run sha256sum -c SHA256SUMS.txt unless you downloaded every asset from that release.

Host Download
Windows 64-bit citadel-windows-x86_64-v{version}.zip
Linux x86_64 / AMD64 citadel-linux-x86_64-musl-v{version}.zip
Linux ARM64 / AArch64 citadel-linux-aarch64-musl-v{version}.zip

The Linux archive contains a statically linked musl executable. It is intended for normal x86_64 Linux distributions, including servers based on Ubuntu, Debian, Fedora, and RHEL, without depending on the host’s glibc version.

The ARM64 archive supports 64-bit ARM hosts such as Raspberry Pi OS 64-bit, AWS Graviton, and Oracle ARM. Do not use it on a 32-bit Raspberry Pi OS install.

The examples below use the latest verified release at the time this guide was updated (v0.9.11). Replace v0.9.11 with the release tag you selected if a newer release is available.

Choose x86_64-musl for AMD64/x86_64 Linux or aarch64-musl for 64-bit ARM. This downloads only a published release binary and its checksum manifest; it does not clone the repository or require Rust, Cargo, or a build toolchain.

Terminal window
VERSION=0.9.11
ARCH=x86_64-musl # use aarch64-musl on 64-bit ARM
ARCHIVE="citadel-linux-${ARCH}-v${VERSION}.zip"
BASE="https://github.com/franadoriv/citadel/releases/download/v${VERSION}"
curl -fLO "${BASE}/${ARCHIVE}"
curl -fLO "${BASE}/SHA256SUMS.txt"
grep -F " ${ARCHIVE}" SHA256SUMS.txt | sha256sum -c -
unzip "${ARCHIVE}"
cd "${ARCHIVE%.zip}"
./citadel check
./citadel serve

./citadel and ./citadel serve are equivalent. Run the binary from the extracted directory so it discovers the included citadel.toml, scripts/, and maps/ directories. The first serve creates data.sqlite, applies migrations, and starts the configured listeners.

The published Windows asset is the x86_64/AMD64 ZIP. This PowerShell flow uses only the public release archive and checksum manifest—no source checkout, Rust, or build toolchain is required. It matches the manifest’s exact <sha256><two spaces><filename> entry and stops if that entry is missing or the hash differs:

Terminal window
$version = 'v0.9.11'
$asset = "citadel-windows-x86_64-$version.zip"
$base = "https://github.com/franadoriv/citadel/releases/download/$version"
Invoke-WebRequest "$base/$asset" -OutFile $asset
Invoke-WebRequest "$base/SHA256SUMS.txt" -OutFile SHA256SUMS.txt
$assetPattern = [regex]::Escape($asset)
$checksumLine = Get-Content SHA256SUMS.txt |
Where-Object { $_ -match "^[0-9A-Fa-f]{64} $assetPattern$" } |
Select-Object -First 1
if (-not $checksumLine) { throw "No SHA-256 entry found for $asset." }
$expected = $checksumLine.Substring(0, 64).ToLowerInvariant()
$actual = (Get-FileHash -LiteralPath $asset -Algorithm SHA256).Hash.ToLowerInvariant()
if ($actual -ne $expected) { throw 'Checksum verification failed.' }
Expand-Archive -LiteralPath $asset -DestinationPath .
Set-Location $asset.Replace('.zip', '')
.\citadel.exe check
.\citadel.exe serve

The default command is serve, so .\citadel.exe and .\citadel.exe serve are equivalent. Run it from the extracted directory so it discovers the included citadel.toml; use --config <path> only when deliberately choosing a different configuration file.

The startup banner prints the dashboard, health, and transport addresses. On a local install the dashboard is normally http://127.0.0.1:7350/dashboard.

3. Check configuration before opening it to players

Section titled “3. Check configuration before opening it to players”

Each archive includes an editable citadel.toml. The Linux archives also include a starter Lua script under scripts/main.lua and a maps/ directory; choose or add the corresponding script and map locations for a Windows server. Validate configuration without opening network listeners:

Terminal window
.\citadel.exe check

Edit citadel.toml and restart the server to change ports, database, game logic location, or enabled transports. See the full configuration reference.

The Linux archive includes systemd/citadel.service. This template runs the server as a dedicated unprivileged user, restarts it after failures, and keeps the SQLite database in /var/lib/citadel instead of the installation folder.

Terminal window
sudo useradd --system --user-group --home-dir /var/lib/citadel citadel
sudo install -d -o citadel -g citadel /opt/citadel
sudo cp -a citadel-linux-*/. /opt/citadel/
sudo install -m 0644 /opt/citadel/systemd/citadel.service /etc/systemd/system/citadel.service
sudo systemctl daemon-reload
sudo systemctl enable --now citadel
sudo systemctl status citadel

Edit /opt/citadel/citadel.toml before starting a public server, then restart with sudo systemctl restart citadel. View logs with journalctl -u citadel -f. The unit intentionally does not open firewall ports or provide TLS certificates; configure those explicitly for your environment.

For a public server, put a CA-issued certificate and its key on the host (for example, via Certbot), readable only by the service account or a restricted group. Configure the same pair for direct QUIC and WebTransport TLS:

[transport.tls]
certificate_file = "/etc/letsencrypt/live/game.example.com/fullchain.pem"
private_key_file = "/etc/letsencrypt/live/game.example.com/privkey.pem"

Open UDP 7351 (native QUIC) and UDP 7353 (WebTransport) when those listeners are public. The certificate must cover the hostname clients use. Restart Citadel after renewal because certificate files are read at startup.

Citadel’s WebSocket listener remains plain ws:// by design. Put it and the HTTP dashboard behind an HTTPS reverse proxy that terminates TLS and forwards WebSocket upgrades to 127.0.0.1:7352; keep the dashboard protected with its own strong credentials or network access controls. Do not proxy HTTP/3/QUIC as ordinary TCP: clients must reach Citadel’s UDP port directly.

Stop the server, back up citadel.toml, your scripts/, maps/, and the database file or external database, then extract the new archive into a new directory. Copy only the files you intentionally customized, run citadel check, and start the new version. Do not overwrite an existing installation blindly: release templates may gain new configuration defaults.