Current setup and deployment guide for Linux, macOS, and Windows.
This guide reflects the current RustChan architecture:
- Tor onion hosting is built in via Arti. You do not install or manage a separate
torservice. ffmpegis optional, but strongly recommended if you want WebP thumbnails, WebM transcoding, video thumbnails, and audio waveforms.
- What RustChan Needs
- Quick Start
- Install Rust
- Install ffmpeg
- Verify WebP and WebM Support
- Build and Run
- First-Run Files and Layout
- Important settings.toml Options
- Tor Onion Service
- HTTPS and TLS
- Linux Service Setup
- Reverse Proxy Notes
- Admin Bootstrapping
- Banner Artwork Requirements
- Updating
- Troubleshooting
RustChan is a single Rust binary. A basic install only needs:
- Rust toolchain to build it
- a writable working directory
ffmpegif you want the enhanced media pipeline
RustChan does not require:
- Docker
- Postgres or MySQL
- Redis
- a separate Tor daemon
git clone https://github.com/csd113/RustChan.git
cd RustChan
cargo build --release
./target/release/rustchan-cliOn first launch RustChan creates rustchan-data/settings.toml, rustchan-data/logs/, and the rest of its runtime directories next to the binary.
Then in another terminal:
./target/release/rustchan-cli admin create-admin admin "ChangeThisPasswordNow"
./target/release/rustchan-cli admin create-board b "Random" "General discussion"Open:
http://localhost:8080- admin panel:
http://localhost:8080/admin
If TLS is enabled in settings.toml, RustChan also serves HTTPS on port 8443 by default.
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"
rustc --version
cargo --versionInstall Rust with rustup-init.exe from rustup.rs, then open a new PowerShell window and verify:
rustc --version
cargo --versionffmpeg is optional, but RustChan is significantly better with it.
When ffmpeg is available, RustChan can:
- extract video thumbnails
- generate audio waveform thumbnails
- convert supported image thumbnails to WebP
- transcode MP4 uploads to WebM when VP9 and Opus are available
Without ffmpeg, RustChan still runs, but video and audio handling degrades gracefully.
sudo apt update
sudo apt install -y ffmpegsudo dnf install -y ffmpegIf your base Fedora repos do not provide the codec-enabled build you want, use RPM Fusion.
brew install ffmpegwinget install --id Gyan.FFmpeg -eThen make sure the FFmpeg bin directory is on PATH.
ffmpeg -version
ffprobe -versionIf you want RustChan to refuse startup when ffmpeg is missing, set:
require_ffmpeg = trueRustChan checks more than just whether ffmpeg exists. It also checks whether your build includes:
libwebpfor WebP image thumbnails and conversionslibvpx-vp9for WebM video encodinglibopusfor WebM audio encoding
Use these commands:
ffmpeg -encoders | rg libwebp
ffmpeg -encoders | rg libvpx-vp9
ffmpeg -encoders | rg libopusIf you do not have rg, use:
ffmpeg -encoders | grep libwebp
ffmpeg -encoders | grep libvpx-vp9
ffmpeg -encoders | grep libopusYou want all three to appear.
libwebp: WebP thumbnail and image conversion supportlibvpx-vp9+libopus: MP4 to WebM transcoding support
On Debian-family systems, the usual install is:
sudo apt update
sudo apt install -y ffmpeg libwebp-dev libvpx-dev libopus-devThe important part is still the actual ffmpeg -encoders output. Package names alone do not guarantee your installed FFmpeg binary was built with every encoder enabled.
Most Homebrew FFmpeg installs are fine, but verify with:
ffmpeg -encoders | rg 'libwebp|libvpx-vp9|libopus'If one is missing, reinstall FFmpeg from a build source that includes that codec set.
Use a full FFmpeg build rather than a minimal one, then verify with:
ffmpeg -encoders | Select-String libwebp
ffmpeg -encoders | Select-String libvpx-vp9
ffmpeg -encoders | Select-String libopusRustChan will log warnings and continue:
- missing
libwebp: image thumbnails stay in original-friendly formats where needed - missing VP9 or Opus: MP4 uploads are stored as MP4 instead of transcoded to WebM
These warnings appear in the console at startup and in rustchan-data/logs/.
cargo build --releaseBinary:
- Linux/macOS:
target/release/rustchan-cli - Windows:
target/release/rustchan-cli.exe
./target/release/rustchan-cli./target/release/rustchan-cli --port 9090
./target/release/rustchan-cli serve --chan-netBy default RustChan stores runtime state in rustchan-data/ next to the binary:
rustchan-data/
├── settings.toml
├── chan.db
├── logs/
│ └── rustchan.YYYY-MM-DD.log
├── backups/
│ ├── full/
│ └── boards/
├── runtime/
│ ├── tls/
│ ├── tor/
│ │ ├── state/
│ │ └── cache/
│ ├── favicon/
│ └── tmp/
└── boards/
## Banner Artwork Requirements
RustChan `1.1.4` adds board banners plus a separate home-page announcement banner.
Banner upload requirements:
- exact `468x60` aspect ratio
- minimum size `468x60`
- recommended size `936x120`
- input can be PNG, JPEG, or WebP
- RustChan converts uploaded banner images to WebP automatically
Board banner placement:
- board index: under the board name/description, above `[Index] [Catalog] [Archive]`
- catalog: under the board name/description, above `Sort By:` and `Show OP Comment:`
- no banner on thread pages
- no banner on archive pages
- no banner on search pages
Home page banner placement:
- separate centered banner box on the home page
- intended for MOTD/news/announcement use
Banner link behavior:
- internal board and internal-path links work directly
- external links can be enabled in the admin panel
- when enabled, external banner clicks go through an on-site warning page before redirecting
Important notes:
settings.tomlis generated automatically on first runcookie_secretis generated automatically on first run- Tor state and onion keys live under
rustchan-data/runtime/tor/state/ - logs rotate daily under
rustchan-data/logs/
The generated file documents every setting inline. These are the ones most operators care about first:
forum_name = "RustChan"
site_subtitle = "select board to proceed"
default_theme = "fluorogrid"
enabled_builtin_themes = ["terminal", "aero", "dorfic", "forest", "chanclassic", "neoncubicle", "fluorogrid"]
port = 8080
max_image_size_mb = 8
max_video_size_mb = 50
max_audio_size_mb = 150
enable_tor_support = true
# tor_only = false
# tor_bootstrap_timeout_secs = 120
# tor_max_concurrent_streams = 512
# tor_service_nickname = "rustchan"
require_ffmpeg = false
# ffmpeg_path = "/usr/local/bin/ffmpeg"
# ffprobe_path = "/usr/local/bin/ffprobe"
ffmpeg_timeout_secs = 120
[tls]
enabled = true
port = 8443
# redirect_http = true
# http_port = 8080enable_tor_support = true: built-in onion service is ontor_only = true: bind RustChan to loopback and serve only through Torrequire_ffmpeg = true: fail startup if ffmpeg is missing[tls].enabled = true: enable RustChan's native HTTPS listenerffmpeg_timeout_secs = 120: max runtime for a single ffmpeg job
RustChan includes built-in Tor onion service hosting through Arti.
You do not need to:
- install
tor - write a
torrc - manage a hidden service directory manually
On current builds, the generated settings.toml enables Tor support by default:
enable_tor_support = trueOn first startup with Tor enabled, RustChan:
- creates the Tor runtime directories
- bootstraps to the Tor network
- generates or loads the onion service keypair
- starts serving the site over
.onion
The first bootstrap usually takes longer than later boots because Tor directory data has to be downloaded and cached.
Back up:
rustchan-data/runtime/tor/state/
That directory contains the persistent onion identity. If you lose it, the next startup will generate a new onion address.
If you want RustChan reachable only through Tor:
enable_tor_support = true
tor_only = trueIn this mode RustChan binds to loopback instead of 0.0.0.0, so clearnet access is blocked.
RustChan creates the Tor state directory with restricted permissions on Unix. If you move the data directory manually, preserve write access for the RustChan service user.
RustChan has built-in HTTPS support.
The generated settings.toml currently includes:
[tls]
enabled = true
port = 8443This means:
- HTTP is available on the main app port
- HTTPS is available on
8443 - on first run, RustChan can generate a local self-signed development certificate
Keep built-in TLS enabled and use the self-signed certificate.
Many operators still prefer putting nginx or Caddy in front and terminating TLS there.
RustChan also supports ACME-based certificates when built with the tls-acme feature and configured in [tls.acme].
Run RustChan as a dedicated unprivileged user.
sudo useradd --system --home /var/lib/rustchan --create-home --shell /usr/sbin/nologin rustchancargo build --release
sudo install -o root -g root -m 0755 target/release/rustchan-cli /usr/local/bin/rustchan-cli
sudo mkdir -p /var/lib/rustchan
sudo chown -R rustchan:rustchan /var/lib/rustchanThis creates settings.toml and the runtime layout:
sudo -u rustchan -H sh -lc 'cd /var/lib/rustchan && /usr/local/bin/rustchan-cli'Stop it after the first start, edit /var/lib/rustchan/rustchan-data/settings.toml, then continue.
Create /etc/systemd/system/rustchan.service:
[Unit]
Description=RustChan
After=network-online.target
Wants=network-online.target
[Service]
User=rustchan
Group=rustchan
WorkingDirectory=/var/lib/rustchan
ExecStart=/usr/local/bin/rustchan-cli
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
[Install]
WantedBy=multi-user.targetThen:
sudo systemctl daemon-reload
sudo systemctl enable --now rustchan
sudo journalctl -u rustchan -fYou can add overrides with:
sudo systemctl edit rustchanExample:
[Service]
Environment=CHAN_BIND=127.0.0.1:8080
Environment=CHAN_REQUIRE_FFMPEG=trueIf you put nginx or Caddy in front of RustChan:
- point the proxy at the RustChan HTTP listener
- set
CHAN_BEHIND_PROXY=trueif you want proxy headers trusted - set
CHAN_TRUSTED_PROXY_CIDRSto the proxy's loopback or private CIDR when the proxy is not on localhost - decide whether TLS terminates at the proxy or inside RustChan
Typical loopback setup:
internet -> nginx/caddy -> 127.0.0.1:8080 -> RustChan
If you use a reverse proxy and terminate TLS there, make sure your proxy forwards the usual headers and that RustChan is not accidentally exposed directly on the public interface.
Create the first admin account:
./target/release/rustchan-cli admin create-admin admin "UseAStrongPassword"Create a board:
./target/release/rustchan-cli admin create-board tech "Technology" "Programming and hardware"Other useful commands:
./target/release/rustchan-cli admin list-admins
./target/release/rustchan-cli admin list-boards
./target/release/rustchan-cli admin reset-password admin "NewStrongPassword"git pull
cargo build --release
sudo install -o root -g root -m 0755 target/release/rustchan-cli /usr/local/bin/rustchan-cli
sudo systemctl restart rustchanBefore major updates, back up:
rustchan-data/chan.dbrustchan-data/boards/rustchan-data/runtime/tor/state/rustchan-data/settings.toml
Or use the built-in backup tools from the admin panel.
Run:
ffmpeg -version
ffmpeg -encoders | rg 'libwebp|libvpx-vp9|libopus'If one of those encoders is missing, RustChan will still run but some media features will be downgraded.
Check:
- outbound network connectivity
- whether the RustChan service user can write to
rustchan-data/runtime/tor/ - whether
tor_bootstrap_timeout_secsneeds to be raised
Also review:
rustchan-data/logs/rustchan.YYYY-MM-DD.log
Check:
- whether
[tls] enabled = trueis intentional - whether the configured HTTPS port is available
- whether your ACME or manual cert settings are correct if you use those modes
Make sure the RustChan user can write to:
rustchan-data/- the uploads directory
rustchan-data/runtime/
That usually means the Tor state directory was deleted, replaced, or not persisted:
rustchan-data/runtime/tor/state/
Back that directory up if the onion address matters.