Jump to initial setup, HTTP API, MCP, Owncast and Rocket.Chat, or checking capture.
Yes — Use the Normal Linux AppImage
Download the usual Linux app and make it executable. On a VPS without a desktop, launching the AppImage alone is not enough: use a virtual display and the --ssapp-headless-control flag. The steps below keep chat capture running after you disconnect from SSH and after a server reboot.
Headless mode keeps SSApp's Electron windows hidden, but the source pages are still real browser windows. Linux therefore needs a virtual display such as Xvfb. This is not a small background-only chat daemon.
Headless mode does not create a public control API. A controller on another computer uses the same Social Stream session and normal WebRTC or hosted WebSocket transport as other remote-control workflows.
Before You Start
- Use Ubuntu 22.04+, Debian 12+, or a similar Linux distribution.
- Allow at least 2 GB of memory for a small setup and more for several source windows.
- Choose a persistent profile directory for settings, sources, sessions, and browser data.
- Plan a one-time desktop or VNC session for sign-ins and other private setup.
Public source URLs that do not require sign-in are the easiest to operate remotely. OAuth, CAPTCHA, passwords, cookies, and account setup still require a person.
1. Install Xvfb and the AppImage
sudo apt-get update
sudo apt-get install -y xvfb x11-utils xauth curl
sudo mkdir -p /opt/socialstream
sudo mv ./YOUR_DOWNLOADED_FILE.AppImage /opt/socialstream/socialstreamninja.AppImage
sudo chmod 755 /opt/socialstream/socialstreamninja.AppImage
Download the current Linux AppImage from the Social Stream Ninja download page. Choose the download matching your server architecture (uname -m), then replace YOUR_DOWNLOADED_FILE.AppImage above with its exact filename. A source checkout and separate Node installation are not required.
2. Prepare the Profile and Sign In Once
Use the same account and data directory for setup and the background service. Create a dedicated account:
id ssapp >/dev/null 2>&1 || sudo useradd --system --create-home --home-dir /var/lib/ssapp --shell /usr/sbin/nologin ssapp
sudo install -d -o ssapp -g ssapp -m 700 /var/lib/ssapp
sudo apt-get install -y x11vnc
sudo -u ssapp Xvfb :99 -screen 0 1920x1080x24 -nolisten tcp -extension GLX
Leave that terminal running. In a second SSH terminal, open SSApp visibly on that virtual display:
sudo -u ssapp env DISPLAY=:99 SSAPP_USER_DATA_DIR=/var/lib/ssapp SSAPP_HEADLESS_CONTROL=0 \
/opt/socialstream/socialstreamninja.AppImage --ozone-platform=x11 --no-hwa
In a third SSH terminal, start temporary VNC access, restricted to the server itself:
sudo -u ssapp x11vnc -display :99 -localhost -rfbport 5900 -nopw -forever
On your own computer, open an SSH tunnel:
ssh -N -L 5900:127.0.0.1:5900 you@your-server
Connect your VNC viewer to localhost:5900. Set the Social Stream session ID and optional password, add sources, and complete any sign-ins. Enable Auto-activate on the sources you want to start when SSApp starts. Copy your chat dock and featured overlay links for later use.
Quit SSApp after setup, then stop VNC, the tunnel, and Xvfb with Ctrl+C in their terminals. Do not run setup and the service against the same profile at the same time. VNC attached to an already-headless instance will normally show an empty display because its windows are hidden.
Use SSAPP_USER_DATA_DIR, not Chromium's --user-data-dir. Complete sign-ins on the VPS; browser cookies copied from another OS may not decrypt.
3. Start the App Headlessly
sudo -u ssapp env SSAPP_USER_DATA_DIR=/var/lib/ssapp xvfb-run -a -s "-screen 0 1920x1080x24 -nolisten tcp -extension GLX" \
/opt/socialstream/socialstreamninja.AppImage \
--ozone-platform=x11 --ssapp-headless-control --no-hwa
The --ssapp-headless-control flag keeps the app windows hidden. This foreground command stops when you stop it; use the systemd service below for unattended operation. The main application still needs Xvfb; --ozone-platform=headless is not a replacement for the virtual display.
4. Control It from Another Computer
Use the same Social Stream session ID and optional password on the headless app and the remote controller. WebRTC is the normal transport. If it is unsuitable for the environment, use Social Stream's hosted WebSocket server mode.
Supported remote controls can add, start, stop, restart, mute, and hide public sources. They do not remotely complete sign-in, OAuth, CAPTCHA, cookies, credentials, or other private account setup.
See Sessions, Passwords, Relay, and Server Modes when the remote controller connects but messages or commands do not arrive.
Keep It Running with systemd
Stop the foreground app with Ctrl+C first. Create /etc/systemd/system/ssapp.service with sudo nano /etc/systemd/system/ssapp.service and paste this unit:
[Unit]
Description=Social Stream Ninja (headless)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=ssapp
StateDirectory=ssapp
WorkingDirectory=/opt/socialstream
Environment=SSAPP_USER_DATA_DIR=/var/lib/ssapp
ExecStart=/usr/bin/xvfb-run -a -s "-screen 0 1920x1080x24 -nolisten tcp -extension GLX" /opt/socialstream/socialstreamninja.AppImage --ozone-platform=x11 --ssapp-headless-control --no-hwa
Restart=on-failure
RestartSec=10
KillSignal=SIGTERM
TimeoutStopSec=30
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now ssapp
journalctl -u ssapp -f
The service uses the account and profile created in step 2. It starts at boot and restarts after an app failure. If you changed the installation path, update ExecStart to match.
Optional HTTP API for Scripts on the VPS
Headless mode does not enable the control API. To enable it for your service, run sudo systemctl edit ssapp and save this override:
[Service]
Environment=SSAPP_CONTROL_API=1sudo systemctl daemon-reload
sudo systemctl restart ssapp
curl -sS http://127.0.0.1:17777/api/v1/capabilities
curl -sS http://127.0.0.1:17777/api/v1/status
For a manual launch, add --ssapp-control-api to the app command instead. Run the following commands in an SSH shell on the VPS. The API intentionally has no token and binds only to 127.0.0.1; it is separate from your Owncast or Rocket.Chat web server. Keep it local.
Read ssappVersion, apiVersion, and the supported platforms in capabilities first. For example, if Twitch is supported, add a source (replace CHANNEL_NAME):
curl -sS http://127.0.0.1:17777/api/v1/command \
-H 'Content-Type: application/json' \
-d '{"action":"addSource","value":{"target":"twitch","username":"CHANNEL_NAME","autoActivate":true}}'
curl -sS http://127.0.0.1:17777/api/v1/command \
-H 'Content-Type: application/json' \
-d '{"action":"getSources","value":{}}'
Copy the source's stable id from the returned source list and replace SOURCE_ID below. Adding a source leaves it inactive; autoActivate controls future app launches.
curl -sS http://127.0.0.1:17777/api/v1/command \
-H 'Content-Type: application/json' \
-d '{"action":"startSource","value":{"sourceId":"SOURCE_ID"}}'
curl -sS http://127.0.0.1:17777/api/v1/command \
-H 'Content-Type: application/json' \
-d '{"action":"getSourceDiagnostics","value":{"sourceId":"SOURCE_ID"}}'
curl -sS http://127.0.0.1:17777/api/v1/command \
-H 'Content-Type: application/json' \
-d '{"action":"stopSource","value":{"sourceId":"SOURCE_ID"}}'
Check ok and payload in each response; failures return error. Read state after a change. If a request times out, check state before retrying it. Stop a source before changing its connection fields. Reload, removal, and shutdown commands require confirm: true.
curl -N http://127.0.0.1:17777/api/v1/events follows the Server-Sent Events feed until Ctrl+C. See the API and MCP guide for the complete reference. These are app/source controls; overlay actions such as featuring a chat message use the Social Stream dock and Social Stream commands.
Optional MCP for an AI Client on the VPS
MCP lets a compatible AI client call SSApp controls as tools. Enable the API above and keep the main app service running. Register this configuration in a client running on the VPS:
{
"mcpServers": {
"social-stream": {
"command": "/opt/socialstream/socialstreamninja.AppImage",
"args": ["--ssapp-mcp", "--ozone-platform=headless"],
"env": {
"SSAPP_CONTROL_URL": "http://127.0.0.1:17777"
}
}
}
}
The configuration location depends on the client. This launches a separate adapter over standard input/output; it does not start the main capture app. A client on your home computer would point at its own localhost, not your VPS. Use Social Stream's normal remote controls from another computer.
The packaged adapter is available from SSApp 0.4.7; 0.4.14 and newer advertise the complete tool set even before the app is available. Live capabilities still decide which calls work. No separate Node installation is needed. The headless Ozone flag here applies only to the MCP adapter; keep Xvfb for the main app.
Try: “Call ssapp_get_capabilities, then ssapp_get_status and ssapp_list_sources. Tell me which sources are capturing and whether any report errors.” Tools also cover source start/stop, diagnostics, captured events, screenshots, and approved app-window interactions. Private sign-ins and CAPTCHA still need a person.
See the Local Control API and MCP guide for the optional agent skill, version compatibility, and more controls.
Owncast, Rocket.Chat, and Featured Messages
You can run SSApp on the same VPS as Owncast and Rocket.Chat if it has enough resources. Installing SSApp does not by itself connect Rocket.Chat or put overlays into the video.
Supported chat source → SSApp → Social Stream dock / featured overlay
↓
Video input → server broadcaster renders overlays → Owncast → viewers
There is no built-in Rocket.Chat connector in the source trees checked for this guide. A separate integration is needed to bring those messages into Social Stream. Prove that messages reach the dock before configuring the video overlay.
Use the dock and featured overlay URLs copied during setup, with the same session/password and transport. Select a captured message in the dock to feature it. Your server broadcaster needs browser-source rendering to place these pages over video before sending the combined stream to Owncast. See Owncast's broadcasting instructions. SSApp is not that video broadcaster.
An overlay positioned over an embedded player on your website is a different option: it appears on that page, rather than being part of the video received by other players or recordings. Owncast documents embedding video and chat.
To switch off your home computer, the video source, broadcaster, chat capture, and any Rocket.Chat integration must all keep running independently of it. Budget for video rendering and encoding separately from SSApp's chat-capture memory.
Check the Complete Workflow Before Leaving It Unattended
- Send a real message in a connected chat and confirm it arrives in your Social Stream dock.
- Feature that message and confirm the featured overlay changes. For Owncast, verify it in the actual viewer video too.
- Disconnect VNC and SSH, then send more messages over several minutes. Capture should continue.
- Run
sudo systemctl restart ssapp, then confirm the same session and sources return and auto-activated sources receive new messages. - During a maintenance window, reboot the VPS and repeat the message check. A running process or successful API response alone does not prove chat capture works.
Use sudo systemctl status ssapp and sudo journalctl -u ssapp -n 100 --no-pager for service status and recent logs. To stop deliberately, use sudo systemctl stop ssapp.
For updates, stop the service, back up /var/lib/ssapp, replace the AppImage at the same path, and start the service again. Retain the previous executable until the new version passes the message checks.
Troubleshooting
| Problem | What To Check |
|---|---|
Missing X server or $DISPLAY | Launch through xvfb-run or start Xvfb and set DISPLAY. |
| Xvfb exits immediately | Keep -extension GLX in the Xvfb arguments; some installed GPU drivers break its GLX startup. |
| The AppImage will not mount | Extract with ./socialstreamninja.AppImage --appimage-extract in a writable directory, then put the extracted folder in /opt/socialstream/squashfs-root. Replace the AppImage path in setup, service, and MCP commands with /opt/socialstream/squashfs-root/socialstreamninja. |
| Remote commands do not arrive | Confirm both sides use the same session and password and that WebRTC or the hosted WebSocket mode is connected. |
| Sources or settings mix between instances | Give every instance a different SSAPP_USER_DATA_DIR and virtual display. |