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.
1. Choose a server archive
Section titled “1. Choose a server archive”| 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.
2. Download, verify, extract, and start
Section titled “2. Download, verify, extract, and start”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.
Linux — no source checkout required
Section titled “Linux — no source checkout required”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.
VERSION=0.9.11ARCH=x86_64-musl # use aarch64-musl on 64-bit ARMARCHIVE="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.
Windows
Section titled “Windows”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:
$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 $assetInvoke-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 1if (-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 serveThe 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:
.\citadel.exe check./citadel checkEdit citadel.toml and restart the server to change ports, database, game
logic location, or enabled transports. See the full
configuration reference.
Run on Linux with systemd
Section titled “Run on Linux with systemd”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.
sudo useradd --system --user-group --home-dir /var/lib/citadel citadelsudo install -d -o citadel -g citadel /opt/citadelsudo cp -a citadel-linux-*/. /opt/citadel/sudo install -m 0644 /opt/citadel/systemd/citadel.service /etc/systemd/system/citadel.servicesudo systemctl daemon-reloadsudo systemctl enable --now citadelsudo systemctl status citadelEdit /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.
Production TLS and reverse proxy
Section titled “Production TLS and reverse proxy”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.
Updating
Section titled “Updating”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.