Headless Server
Run Risuko as a headless download server without a GUI.
Risuko can run as a headless download server, accepting commands over JSON-RPC. This is useful for servers, NAS devices, Docker containers, or any environment without a display.
Starting the Server
Via CLI
risuko serve --rpc-port 16800serve runs in the foreground until it receives Ctrl+C or an RPC risuko.shutdown request. --rpc-port defaults to 16800; pass -v/--verbose for debug logging. There is no --rpc-secret flag — the server reads its secret from config (see Remote Access). When pbh-enable is set in config, a second Aria2Next-compat RPC for PeerBanHelper is bound to pbh-listen-port on the same rpc-host.
Via Node.js
// @risuko/risuko-js is a CommonJS native addon, so import the default
// export and read methods off it — named imports are not available
import risuko from "@risuko/risuko-js";
await risuko.startEngine({
rpcPort: 16800,
enableRpc: true,
});
// Engine is now running and accepting RPC commands
// Keep the process alive
process.on("SIGINT", async () => {
await risuko.stopEngine();
process.exit(0);
});Controlling the Server
Once the server is running, use any of these methods to control it:
From the CLI
# Add a download
risuko download https://example.com/file.zip --rpc-port 16800
# Check status
risuko status --rpc-port 16800
# Shut down
risuko shutdown --rpc-port 16800From curl
curl -X POST http://localhost:16800/jsonrpc \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":"1","method":"risuko.addUri","params":[["https://example.com/file.zip"]]}'From Node.js (RPC client)
You can also write a custom JSON-RPC client to talk to a remote server. The RPC Protocol page documents all available methods.
Remote Access
The RPC server binds to 127.0.0.1 by default and only accepts local connections. To accept connections from other machines, set rpc-host:
risuko config set rpc-host 0.0.0.0Once the server is reachable from the network, make sure an authentication secret is set. On first run the engine generates a random one and saves it in system.json; to choose your own, edit that file directly. The engine reads rpc-secret from system.json in the config directory — risuko config set writes to user.json, which the engine ignores for this key:
{ "rpc-secret": "choose-a-secret" }CLI clients then pass --rpc-secret <secret>; raw JSON-RPC clients prepend "token:<secret>" to the params array (see RPC Protocol).
Running as a systemd Service
[Unit]
Description=Risuko Download Engine
After=network.target
[Service]
Type=simple
User=risuko
ExecStart=/usr/local/bin/risuko serve --rpc-port 16800
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.targetsudo systemctl enable risuko
sudo systemctl start risukoDocker
FROM debian:bookworm-slim
COPY risuko /usr/local/bin/risuko
RUN chmod +x /usr/local/bin/risuko && mkdir -p /downloads
ENV XDG_CONFIG_HOME=/config
EXPOSE 16800
VOLUME ["/downloads", "/config"]
CMD ["risuko", "serve", "--rpc-port", "16800"]XDG_CONFIG_HOME=/config places the config directory at /config/app.risuko.Risuko on a fresh install (the standalone CLI and the app binary both use it). Only if a legacy /config/dev.risuko.app directory already exists, the standalone CLI keeps using that instead (the app binary does so only when app.risuko.Risuko is absent). Create two files there before starting the container. system.json holds dir, which points downloads at the volume, and rpc-secret. user.json holds rpc-host, which must be 0.0.0.0. rpc-host is a user key: without user.json its default 127.0.0.1 overrides system.json, binding the container's loopback so the published port never reaches the server. Missing keys are filled from defaults.
mkdir -p /path/to/config/app.risuko.Risuko
cat > /path/to/config/app.risuko.Risuko/system.json <<'EOF'
{
"dir": "/downloads",
"rpc-secret": "choose-a-secret"
}
EOF
cat > /path/to/config/app.risuko.Risuko/user.json <<'EOF'
{ "rpc-host": "0.0.0.0" }
EOF
docker run -d \
-p 16800:16800 \
-v /path/to/downloads:/downloads \
-v /path/to/config:/config \
risukoSession Persistence
The engine automatically saves session state every 30 seconds and on shutdown. When restarted:
- Completed downloads are remembered
- Active downloads resume from where they left off
- Configuration persists in the config directory
The default config directory depends on the deployment method:
- CLI and app binary:
~/.config/app.risuko.Risuko(Linux),~/Library/Application Support/app.risuko.Risuko(macOS); an existing legacydev.risuko.appdirectory is still used (see Config Directory Locations) - Node.js API: same default as the CLI, configurable via
EngineConfig.configDir