rconsole command reference
Every command rconsole understands, with usage, options and examples. If a command exists in the code it is documented here (a test fails otherwise).
Contents
How commands work ·
Quick index ·
Basics ·
Files and editing ·
Your Linux systems (vm) ·
Hosting and exposing apps ·
Services: bots and workers ·
Staying alive: keep-alive, backups, reboot ·
Updating rconsole ·
Background jobs ·
Users and administration ·
Environment and AI ·
Fun commands ·
Interactive programs ·
Running anything else
How commands work
Type a command and press Enter. rconsole looks at the first word:
- Console commands (this document) are built in and run instantly. They are the same on every system.
- Interactive programs (
nano,vim,python,bash,ssh, …) open in a real terminal window. Close it with the ✕ button (top-right) or Esc; either ends that session. - Everything else (
ls,git,pip,apt,curl,python main.py, …) runs in a real shell on your current target: the server's host (admins only) or one of your VMs.
Targets: host or VM
- Admins start on the host; normal users work in their VMs and never see the host.
- The prompt shows where you are:
ark@rconsole:/srv$on the host,ark@debian:/root$in a VM. - Switch with the system dropdown (tab bar on desktop, ⚙ menu on phones),
vm use <name>, orvm mode. - With several VMs and none chosen, a command that needs one shows a picker in the output — choose a system (or install another) and the command runs.
- Force a target for one command by prefixing it:
| Prefix | Runs in |
|---|---|
@host cmd |
the server host (admins only) |
@vm cmd |
your active VM |
@vm:kali cmd |
the VM called kali |
Shell features that work everywhere
- Pipes, redirects,
&&,||,;, globbing and quoting work as in any shell:ls -la | grep py > files.txt && wc -l files.txt. sudoprefix: required for admin commands (marked 🔒 below). A non-admin who typessudo …is refused.sudo <anything else>just runs it.&at the end runs a command as a background job.~means your home (/rootin a VM). Tab bar+opens another tab; each tab has its own directory.- Plain (non-interactive) commands are cut off after 60 s; use
&,vm shellor a job for long work. - Aliases (see
alias) expand before anything else. - Inside a VM the commands you install in
~/.local/bin,~/.cargo/bin,~/.bun/bin,~/go/binare always onPATH, and exports in~/.profileapply to plain commands too.
Legend: 🔒 = needs sudo (admin). <x> = required, [x] = optional.
Quick index
| Command | What it does | |
|---|---|---|
help |
list commands | |
clear / cls |
clear the screen | |
history |
commands typed in this tab | |
rwhoami |
show your username | |
version |
show the rconsole version | |
cd |
change directory | |
alias / unalias |
command shortcuts | |
theme |
colour themes | |
logout |
sign out | |
edit |
built-in code editor | |
fm |
file manager | |
vm |
your Linux systems | |
shell |
interactive window on the host shell | admins only |
neofetch / fetch / rfetch |
system summary | |
expose / unexpose |
publish a running server at /name/ |
|
kprocess |
kill a process by PID | 🔒 |
service |
supervised bots/workers: autostart, restart on crash | |
keepalive |
stay awake on free hosting (self-ping) | |
backup |
encrypted backups, auto-restore on a fresh instance | 🔒 |
reboot |
restart rconsole without redeploying | 🔒 |
rconsole |
version info and rconsole update: check for a new release and install it safely |
admins to update |
jobs · jobout · jobtail · fg · kill |
background jobs | |
suser · auser · nauser |
list users / grant / revoke admin | 🔒 |
muser · ruser |
create / delete a user | 🔒 |
cpass · cuser |
change a password / your username | 🔒 |
rboot |
factory reset | 🔒 |
env |
per-user environment variables | 🔒 |
agent |
AI coding agent | 🔒 |
opencode |
OpenCode terminal AI | 🔒 |
hello / hi · cowsay · fortune · lolcat · figlet / banner · sl · matrix · colors |
eggshells | |
date · uptime · cal · echo · rev · wc |
small utilities |
Basics
help
Prints the list of console commands, shell features and admin commands.
help
clear / cls
Clears the output of the current tab. (History and state are kept.)
history
Lists the commands you typed in this tab, numbered, newest last (the last 500 are kept).
history
rwhoami
Prints your username.
version
Prints the rconsole version, e.g. rconsole 1.4.2 (also in the first line of help and at /healthz).
rconsole version prints more (where it is installed, the last update).
cd
Changes the tab's working directory. Each tab remembers its own directory, including after an interactive window
(nano, a shell, ...) closes: you land where you were, not back in the default directory. New tabs start in
/home/rconsole on the host and in /home in a VM (cd ~ still goes to /root). In the Docker image /home/rconsole is the persistent
workspace (<data>/workspace), which is part of every backup; without it (a plain install) the host starts in
<data>/workspace.
cd /srv/site # absolute
cd .. # up
cd ~ # home (/root in a VM)
cd # same as cd ~
On the host admins can go anywhere. In a VM you are confined to that VM's filesystem — .. and symlinks can't
escape it. Errors: No such file or directory, Not a directory.
alias
Defines persistent shortcuts (saved for your account).
alias # list all aliases
alias ll=ls -la # define (quotes optional)
alias ll # show one
An alias replaces the first word of what you type: after alias ll=ls -la, typing ll /tmp runs ls -la /tmp.
Names can't contain spaces.
unalias
Removes an alias: unalias ll.
theme
Lists or switches the colour theme (saved for your account and applied live).
theme # list themes, * marks the current one
theme dracula # switch
Themes: default light amber solarized dracula github ubuntu retro nord gruvbox matrix
tokyonight catppuccin monokai everforest ayu papercolor.
You can also use the theme button (tab bar on desktop, ⚙ settings menu on phones).
logout
Signs you out. Your tabs, history, aliases and running terminals are kept; log back in to resume.
Files and editing
edit
Opens the built-in code editor (syntax highlighting for ~65 languages, great on phones).
edit main.py # opens (creates it when you save)
edit /etc/hosts
Works on the host (admins) or inside the VM you are in. Files over 5 MB are refused.
The editor behaves like a small code editor:
| Keys (Ctrl on Windows/Linux, Cmd on Mac) | What it does |
|---|---|
Enter |
New line with the same indentation; one level deeper after { [ (, : (Python/YAML/Makefile), then/do/else or an HTML tag. Between {} / () / <div></div> it opens an indented block. Markdown lists and /** */ comments continue. |
Tab / Shift+Tab |
Indent / outdent (every selected line when there is a selection). Uses the file's own style: tabs, 2 or 4 spaces. |
( [ { " ' |
Closing character is added; typing it steps over it; Backspace between the pair removes both; with a selection the selection is wrapped. |
Ctrl+/ |
Toggle comment on the line(s) (#, //, --, <!-- -->, /* */ … by language). |
Ctrl+] / Ctrl+[ |
Indent / outdent line(s). |
Alt+↑ / Alt+↓ |
Move line(s) up / down. Alt+Shift+↑/↓ copies them. |
Ctrl+Shift+K |
Delete line. Ctrl+Enter / Ctrl+Shift+Enter insert a line below / above. |
Ctrl+L / Ctrl+J |
Select line / join lines. |
Home |
First non-blank character, then column 0. |
Ctrl+F / Ctrl+H / F3 |
Find / find and replace (match case, whole word, regex, $1 in replacements) / next match. |
Ctrl+G |
Go to line (42 or 42:7). Tapping Ln, Col in the status bar does the same. |
Ctrl+S / Esc |
Save / close the find bar, then the editor. |
Ctrl+Z / Ctrl+Y |
Undo / redo. |
The status bar shows line and column, the indentation style (tap to switch between 2 spaces, 4 spaces and tabs) and A− / A+, which change the editor's font size (remembered in this browser). On phones and tablets a symbol bar above the keyboard gives Tab, undo/redo, Find and the characters that are awkward to type.
The 📁 file browser: download and upload
The 📁 button (tab bar) opens a visual file browser. Besides browsing, creating, renaming, deleting and editing:
* ⬇ Download on every row: a file downloads as it is; a folder downloads as a .zip that is built while it
streams (symlinks inside it are skipped, so a link can never pull in a file from outside the folder).
* ⬆ Upload files adds one or many files to the folder you are looking at. ⬆ Upload folder uploads a whole
folder and keeps its structure (empty sub-folders are not sent: a browser only reports files).
* Files that already exist are not replaced until you confirm once for the whole batch. Each file is its own request,
so one failure does not stop the rest; the status line shows progress and what failed.
* The per-file limit is 64 MB by default (RCONSOLE_MAX_UPLOAD_MB). For bigger things use git clone, curl
or wget inside a VM, or upload a .zip and unzip it.
* Folder upload needs a browser that supports folder pickers (desktop Chrome, Edge, Firefox, Safari; on phones it
varies, in which case upload a .zip and unzip it).
* Everything goes through the same confinement as the rest of the console: in a VM you only see that VM.
The 📁 file browser: photos and videos
Clicking a photo (png jpg jpeg gif webp bmp ico avif svg) or a video (mp4 m4v webm ogv mov) opens it in a
viewer on top of the browser instead of the code editor: photos are shown fitted to the screen (click to switch to
actual size), videos play with the browser's own player (play/pause, seeking, volume, full screen).
* ‹ › (or the ←/→ keys, or a swipe on a photo) move through the photos and videos of the folder; ⬇ downloads
the current one; Close (or Esc) returns to the browser.
* Videos are streamed with range requests, so seeking works without downloading the whole file. If your browser
cannot play a video's codec (some .mov files), the viewer says so and offers the download.
* Everything goes through the same confinement as the rest of the console: in a VM you only see that VM's files.
SVG images are shown as pictures only; scripts inside them never run.
* Other file types still open in the editor as before; mkv/avi and similar are not previewed (use ⬇).
The 📁 file browser: select, compress, extract, properties
Selecting (works like a desktop file manager):
| Do this | To get this |
|---|---|
| Click the blank space of a row (anywhere except the name and the ⬇ ✎ 🗑 buttons) | Select just that row. The name still opens the file or folder. |
Ctrl/Cmd + click |
Add or remove a row. |
Shift + click |
Select the range from the last clicked row. |
| Drag on blank space | A rectangle selects every row it touches (Ctrl/Shift + drag adds to the selection); it scrolls when you drag near the top or bottom. |
| Double-click a row's blank space | Open it. |
The checkbox at the start of the selection bar, or Ctrl/Cmd + A |
Select all (empty or ticked; click it again to clear). There is no permanent select-all button: the checkbox appears once at least one item is selected. |
Esc |
Clear the selection (a second Esc closes the browser). Delete deletes the selection. |
| Phone / tablet: long-press a row | Select it, then drag without lifting to sweep over more rows. After that a tap toggles rows, and tapping a name no longer opens it until you clear the selection (✕ or Esc). A tap on blank space does nothing while nothing is selected, so scrolling never selects by accident. |
A bar appears above the list (only while something is selected) with the select-all checkbox, the count and total size and these actions: Compress, Extract (only when every selected item is an archive), Properties (only when exactly one item is selected), Delete (one confirmation for everything) and ✕.
Compress asks for a format and a name and makes one archive in the same folder (an existing file is never
overwritten: you get name (2).zip). Formats: zip, tar, tar.gz, tar.bz2, tar.xz, tar.zst
(Python 3.14+), 7z, rar and the one-file formats gz, bz2, xz, zst. Only formats that work on this server
are offered, and the one-file formats are greyed out unless exactly one plain file is selected.
- RAR cannot be created without WinRAR's proprietary
rartool, so the option only appears for admins who have installed it. RAR extraction works throughbsdtar(packagelibarchive-tools, included in the Docker image). 7zneedsbsdtartoo (admins in the host shell may alternatively use 7-Zip:7zz/7z/7za).- Symlinks are stored as links and never followed, so a link can never pull in a file from outside the folder. (7z and RAR cannot store links safely: selections that contain symlinks are refused for those two.)
Extract works on zip (also jar, war, apk, whl), tar, tar.gz/bz2/xz, gz, bz2, xz, zst and, through bsdtar, 7z,
RAR, CAB, ISO, CPIO, DEB, RPM, LZH and XAR. Choose Extract to a new folder (an archive with exactly one top folder
is extracted as that folder, otherwise a folder named after the archive is created) or Extract here. Existing files
are never overwritten (they are counted as skipped). Password-protected archives are not supported.
- Extraction refuses
.., absolute and drive-letter paths, never writes through a symlink, skips devices, FIFOs and hard links, and drops setuid bits. It stops when the result would exceed 2048 MB (RCONSOLE_MAX_EXTRACT_MB), 200,000 entries or the free disk space. - Compress and extract run as background jobs: a progress bar, a Cancel button, and one job per user at a time.
Properties (single item): type, location, size, size on disk, modified / accessed / changed times, permissions
(-rw-r--r-- and octal), owner and group (names are shown for the host admin; inside a VM only numeric ids), link
target, MIME type, and for zip / tar archives the number of entries and their unpacked size. Folder sizes count
what is inside without following links, and say so when a folder is too large to finish counting.
fm
An in-console file manager (also available as the 📁 button).
fm # current directory
fm /srv/app # start somewhere else
Commands inside fm:
| Command | Does |
|---|---|
cd <dir> |
enter a directory |
up |
go up one level |
open <file> |
edit a file in the editor |
cat <file> |
print a file |
rm <file> |
delete a file or empty directory |
mkdir <dir> / touch <file> |
create |
mv <a> <b> |
rename or move |
? · q |
help · quit (your directory carries over) |
shell
Admins only. Opens an interactive window on the host shell (the server itself), the same kind of window vm shell
opens for a VM. It always opens the host, whatever system the tab currently uses, and exit (or the ✕) closes it and
returns you to your tab and directory. It needs no sudo; a normal user gets a permission error and should use
vm shell instead. It takes no arguments (shell ls is refused: run ls directly).
shell # an interactive host shell, admins only
Your Linux systems (vm)
You can have several systems at once — Alpine, Debian, Ubuntu, Kali — each with its own root filesystem and
its own /root. Inside one you are root and can install anything. Debian is the default.
vm works for everyone and only ever touches your systems.
vm
| Subcommand | What it does |
|---|---|
vm / vm status [name] |
your systems, which is active, disk used |
vm list |
every system you can install (and which you have) |
vm install [name…] |
install one or more: debian ubuntu:24.04 kali alpine, or all. No name = Debian |
vm shell [name] |
interactive root shell in a VM (asks which, if several) |
vm run [--vm name] <cmd> |
run one command in a VM and print the output (90 s limit) |
vm use <name> |
make a VM the default for plain commands |
vm mode [host\|vm [name]] |
show / choose where plain commands run |
vm reset [name] --yes |
recreate a VM's system files, keep its /root |
vm remove <name\|all> --yes |
delete a VM and its /root |
vm setup <profile> [name] |
install Python / build tools / Node … (below) |
vm update [name] [--yes] [--stay] [--log] |
update a VM to the latest version, safely (Alpine: walks to the newest release one release at a time; Debian/Ubuntu/Kali: all newer packages of their release; --stay = packages only): locks it, snapshots, upgrades, verifies, and restores the snapshot on any problem. Name optional with one VM. Admins: from the host shell. --yes confirms stopping running terminals/jobs; --log shows the last run |
vm ps [name] |
processes running in a VM (each VM has its own PID space; plumbing hidden) |
vm kill <pid> [name] [--9] |
stop one process of a VM by the PID vm ps shows (never its init) |
vm deps [name] |
what a restore will reinstall; vm deps capture records now, vm deps restore reinstalls now |
vm doctor [name] |
step-by-step health check (shell, programs, root, write, DNS, internet, packages) |
vm help |
short usage |
vm list
vm install debian kali # two systems, one after the other
vm shell kali # root shell in Kali
vm use debian # plain commands now run in Debian
vm run --vm ubuntu apt update
@vm:kali nmap -V # one-off command in Kali
- Releases:
debian:bookworm,ubuntu:24.04,alpine:3.21. Names also acceptdeb,ubu,alp,archlinux. Arch is rolling: justarch. - Installs run in the background;
vm statusshows progress. You can't install the same system twice (usevm removefirst). vm mode hostis admins only.vm mode vmwith several systems asks which one.- Installs never stop to ask questions (
DEBIAN_FRONTEND=noninteractive), andpip installworks without--break-system-packages.
docker: containers without a daemon
Render (and every rconsole VM) is itself an unprivileged container, so no Docker daemon can run there, and a plain
Docker client always ends in cannot connect to /var/run/docker.sock. The docker command here is a small shim over
udocker: it unpacks the image and runs it in userspace.
docker run hello-world
docker run --rm -e NAME=x -v /root/data:/data python:3.12-slim python -c 'print("hi")'
docker pull alpine ; docker images ; docker ps ; docker rm NAME ; docker rmi alpine
drun alpine echo hi # short for docker run, always local
- Host shell (
vm mode host): ready in the image, runs anything, including static images likehello-world. - In a VM: run
vm setup docker(orvm setup udocker) once. proot cannot run inside proot, so containers use fakechroot: normal programs work, static binaries (hello-world) cannot. The shim says so; use the host shell. - A container made by
docker runis deleted afterwards unless you give--name. - Understood:
-e,-v,-w,-u,--entrypoint,--name,--rm,--env-file,-i/-t. Ignored with a warning:-p(containers share the host network, so an app is reachable on its own port),--restartand the like. - Not possible without a daemon:
-d,exec,logs,stop,build,compose, networks, volumes, desktop images such as webtop. Those commands explain why. - Real engine somewhere?
export DOCKER_HOST=ssh://user@server(withvm setup docker, which also installs the real client) sends every command there instead. - Settings:
DRUN_MODE(udocker execution mode; defaultP1on the host,F1in a VM),DRUN_PULL_OPTS(extraudocker pulloptions, e.g. a private registry),DOCKER_SHIM_LOCAL=1(never forward toDOCKER_HOST). - The first run downloads udocker's helper tools and the image, so it is slow.
vm setup
Installs a ready-made toolchain inside a VM as a background job with live progress:
| Profile | Installs |
|---|---|
python |
Python 3, pip, venv, compiler and headers for psycopg2, mysqlclient, Pillow, lxml, cryptography … |
build |
gcc, g++, make, cmake, autotools, pkg-config |
node |
Node.js, npm |
rust |
Rust, cargo |
db |
psql, mysql, redis-cli, sqlite3 |
tools |
nano, vim, wget, curl, git, ps, htop, zip, jq, ssh … |
docker |
docker run ... without a daemon: installs udocker, a docker command and drun (see docker), plus the real Docker client for DOCKER_HOST. Runs in userspace, so no -d, -p, exec, build or compose; in a VM static images such as hello-world can't run (use the host shell) |
udocker |
the same as docker, without the real Docker client |
kali |
Kali VMs only. The command-line Kali toolset (kali-linux-headless, no desktop) plus the basics it needs. Several GB and a long install; refused on any other system. Want more: apt install kali-linux-large |
all |
tools, build, python, node, rust, db (not docker or kali) |
vm setup # list profiles
vm setup python # then: pip install psycopg2 mysqlclient Pillow
vm setup python kali # a specific VM
vm setup docker # Docker client + compose
vm setup kali # in a Kali VM: the Kali toolset (`vm install kali` first)
neofetch / fetch / rfetch
System summary that fits your screen (logo beside, above, or hidden on phones).
* neofetch and fetch follow your target: in a VM they show that VM's system (distro, packages, shell);
on the host they show rconsole's summary. Typing neofetch inside vm shell works too.
* rfetch always shows rconsole's own summary.
* Flags: --no-logo; in a VM also --plain (no colours).
Hosting and exposing apps
Two ways to put something on the web through rconsole's domain, and they work together. Both sit behind
rconsole's login unless stated. (sudo serve and sudo gunicorn were removed in 1.2.2: these two cover them.)
expose |
service |
|
|---|---|---|
| What it does | publishes a server that is already running at /<n>/ |
keeps it running (autostart, restart on crash, logs) |
| Who starts the program | you (python main.py &, npm run dev, …) |
rconsole's supervisor |
| Combine | service add … --expose PORT:NAME does both in one line |
# a static site
service add site --vm debian --cwd /root/site --expose 8000:site python3 -m http.server 8000
# a Python web app (install it once: vm setup python, then pip install gunicorn)
service add app --vm debian --cwd /root/app --expose 8000:app gunicorn -b 127.0.0.1:8000 app:app
service logs app # what it printed (replaces `sprocess`)
expose
Publishes a server you already started — on the host or in any VM — at https://<your-domain>/<name>/.
python main.py & # a web server on port 8000
expose 8000 myapp # -> https://your-domain/myapp/
expose 8000 myapp --rewrite # also fix /static/… links inside HTML/CSS
expose 8000 hook --public # no login needed (admins only)
expose list # your exposures (admins see all)
expose rm myapp # stop exposing
- Names: lowercase letters, digits,
-(1–32), not only digits, not a reserved word (login,api,static,ws,healthz,console, …). Names are unique across all users; the owner or an admin can remove one. - Ports 1024–65535, never the console's own port. Up to 20 per user.
- You can expose before starting the app;
expose listshows[up]/[down]. - The app is served under the prefix
/<name>. rconsole sendsX-Forwarded-Prefix,X-Forwarded-HostandX-Forwarded-Proto, and rewrites redirects (Location) back into the prefix. Frameworks that support a prefix (DjangoFORCE_SCRIPT_NAME, FlaskProxyFix(x_prefix=1), Vite--base) can serve natively.--rewriteis a best-effort fix for root-relative links in HTML and CSS (not JavaScript). --public(admins only) removes the login requirement for that name — handy for webhooks and demos.- Not supported: WebSockets through the proxy. Requests are buffered (not streamed) and time out after 30 s.
- The console's own session cookie is never forwarded to your app.
unexpose
Same as expose rm: unexpose myapp (several names allowed; unexpose all removes all of yours).
kprocess
🔒 Kills a process: sudo kprocess <pid> for one, sudo kprocess for everything this session still hosts. It
refuses to kill the rconsole server itself. For anything you started with service, use service stop <n>.
Services: bots and workers
service
A service is a named command that rconsole keeps running: it starts at boot, is restarted when it crashes, can live in a VM or on the host, and survives redeploys (definitions are part of every backup). This is how you host a Telegram/Discord bot, a scraper, a queue worker or a web app.
| Subcommand | What it does |
|---|---|
service add <name> [options] <command…> |
create and start a service |
service list |
every service with state, uptime, restarts, where it runs |
service start, stop, restart <name\|all> |
control one service or all of yours |
service logs <name> [lines] |
recent output (and the last exit code) |
service rm <name> |
stop and delete (also removes its --expose) |
service help |
short usage |
Options for add (put them before the command; -- ends the options):
| Option | Meaning |
|---|---|
--vm <name> |
run inside that VM (default: your current system) |
--host |
run on the server itself (admins only) |
--cwd <dir> |
working directory (default: /home in a VM, /home/rconsole on the host) |
--env KEY=VALUE |
environment variable (repeatable) — good for bot tokens |
--expose PORT:NAME |
publish the app at /NAME/ (like expose) |
--no-autostart |
create it stopped; start with service start |
service add tgbot --vm debian --cwd /root/bot --env BOT_TOKEN=123:abc python3 bot.py
service add web --vm debian --cwd /root/app --expose 8000:web gunicorn -b 127.0.0.1:8000 app:app
service add job --vm debian sh -c 'while true; do python3 run.py; sleep 3600; done'
service list
service logs tgbot 100
- Restart policy: after a crash it is restarted after 2 s, then 4, 8, … up to 60 s between attempts; a run that
lasted a minute resets the delay.
service listshowsretry in …sand the last exit code. - After a redeploy or restore services start again; if their VM is still being rebuilt they simply retry until it is ready.
- The command text is kept exactly as you typed it (quotes,
;,&&). Names: lowercase letters, digits,-_. Up to 10 per user. Normal users can only run services inside their VMs. Admins see everyone's services; everyone else only their own.
Staying alive: keep-alive, backups, reboot
Made for free hosting tiers that sleep when idle and wipe their disk on every deploy — see FREE_HOSTING.md.
keepalive
Pings the site's own public URL (/healthz) every 10 minutes so a free instance never goes to sleep.
keepalive # status: URL, interval, last result
keepalive now # ping right now and show the result
keepalive off # (admins) pause until the next restart; keepalive on resumes
On by default on Render (the URL is detected). Elsewhere set RCONSOLE_PUBLIC_URL and RCONSOLE_KEEPALIVE=1;
RCONSOLE_KEEPALIVE_EXTRA=url1,url2 also pings your other free sites; RCONSOLE_KEEPALIVE_INTERVAL changes the
period (seconds, minimum 60).
backup
🔒 Encrypted snapshots of everything that matters, pushed to a private git repo (or a folder), restored automatically on a fresh instance.
sudo backup # status: target, last backup, size, problems
sudo backup now # take one right now
sudo backup restore --yes # replace local data with the latest backup
sudo backup help # setup steps
- Saved: users and secrets, per-user state, the workspace, exposures, services, each VM's
/root, and the list of VMs andvm setupprofiles. Not saved: VM system files (re-downloaded), caches,node_modules/venvs, logs, files over 20 MB, running processes. - Runs every 15 min if something changed, and once at shutdown. Size limit:
RCONSOLE_BACKUP_MAX_MB(default 40). - Encrypted with
RCONSOLE_BACKUP_PASSPHRASE(required). Destination:RCONSOLE_BACKUP_URL+RCONSOLE_BACKUP_TOKEN(git) orRCONSOLE_BACKUP_DIR(a folder). - On a blank instance (no users file) the latest backup is restored before anything else starts, then your VMs
are reinstalled in the background and
vm setupprofiles re-applied. - Restoring at boot never overwrites existing files;
sudo backup restore --yesdoes.
reboot
🔒 Restarts rconsole without redeploying — so a free host doesn't hand you a blank disk.
sudo reboot --yes # in place: final backup → stop everything → reload. Files and VMs stay.
sudo reboot --hard --yes # exit the process; the platform starts a fresh one (may need a restore)
Services start again by themselves and the page reconnects. Use it after changing environment variables on the
host, or to recover from a wedged state. Without --yes it only explains what it will do.
Updating rconsole
rconsole
Version information and the self-update. Checking is open to everyone; installing needs an administrator (no
sudo prefix needed).
rconsole # short help
rconsole version # running version, install directory, last update, rollback available?
rconsole update --check # is a newer release published? shows what is new, changes nothing
rconsole update # check, show what is new, ask, then update to the latest release
rconsole update --yes # the same without the question
rconsole update --rollback # go back to the version that was installed before the last update
rconsole update --force # also update a git checkout, or reinstall the same version / a rolled-back one
What rconsole update does, in order:
1. Locks the console. From the first step until the restart, every request except the health probe is answered
with 503: no command can run, no terminal, file edit, login or hosted app can be used, in any tab or browser. Open
tabs show a progress screen and reload themselves when it is over.
2. Downloads the release archive from the GitHub release (RCONSOLE_UPDATE_REPO, default
Salehin-07/rconsole-ark) and verifies its SHA-256 against the release's SHA256SUMS. No checksum, or a
mismatch: it stops.
3. Tests the new version before touching anything: strict unpack (no links, no .., size limits), correct
version, every file compiles, and the app is imported in a separate process with a throw-away data directory.
Changed Python dependencies are installed into <data>/update/site-<version>, never into the system.
4. Quiets the server: stops services, jobs and terminals and takes a final backup.
5. Replaces the program files one by one, atomically, after saving a rollback copy of every file it replaces
or removes. Any failure puts the old files back.
6. Restarts in place (like sudo reboot --yes): services start again by themselves and the page reconnects.
Your data is never touched: users, secrets, VMs and their /root, the workspace, services, exposures, settings
and backups live in the data directory, not in the program files. A failure in steps 1–3 changes nothing and stops
nothing; the console simply unlocks.
- Safety nets. A new version that never becomes healthy (it must stay up for ~25 s) and keeps failing to start is
rolled back automatically at the next container start;
python updater.py rollbackdoes it by hand even when the server will not start. A version rolled back this way is not offered again until you use--force. - Containers. A redeploy rebuilds the image from your repository, which would undo an in-place update, so the
verified release is kept in
<data>/update/releases(and in the encrypted backups).docker-entrypoint.shre-applies it at boot when the image is older. Changes to the image itself (theDockerfile: system packages) need a redeploy; the update tells you when a release has some. - Git checkouts are refused (use
git pull); add--forceto overwrite files from the release archive anyway. A read-only install directory is refused too. - Private fork or rate limit? Set
RCONSOLE_UPDATE_TOKEN(a GitHub token with read access) and pointRCONSOLE_UPDATE_REPOat your fork. The token is never passed to your commands. - Only one update runs at a time. If the restart does not happen, the lock is released after 90 s and the output says
to run
sudo reboot --yes.
Background jobs
Add & to any command to run it in the background (sleep 60 &). Jobs are per user and survive closing the tab.
Refer to a job as %n (its number).
jobs
Lists your jobs: number, pid, running/done, command.
jobout
jobout %n [lines] — last lines of a job's output (default 50).
jobtail
jobtail %n — live-follow a job's output; press any key to stop.
fg
fg %n — follow a job's output live and stop automatically when it ends.
kill
kill %2 # stop background job 2
kill SIGKILL %2 # send a signal to job 2
kill -9 1234 # anything else goes to the real shell's kill
Users and administration
Admin commands need sudo (🔒). Passwords must be at least 8 characters (RCONSOLE_MIN_PASSWORD). Usernames are
1–32 characters: letters, digits, . _ -, starting with a letter or digit.
suser
🔒 Lists all users and their role (admin/user); marks you with (you).
auser
🔒 sudo auser <username> — grant admin.
nauser
🔒 sudo nauser <username> — revoke admin (the last admin can't be demoted).
muser
🔒 Creates a user. It asks for username, password and confirmation. New users are normal (non-admin).
ruser
🔒 sudo ruser <username> — deletes a user together with their saved state, VMs, jobs, terminals and exposures
(the last admin can't be deleted).
cpass
🔒 Changes a password. It asks which user (Enter = yourself), then the new password twice. If you still use the
factory password (ark/ark), this is the command you must run first — until you do, only cpass, logout,
help, clear, history and rwhoami work.
cuser
🔒 Renames you. It asks for the new username. Your tabs, aliases, VMs and exposures move with the name.
rboot
🔒 Factory reset: stops hosted apps, jobs and terminals, wipes every user's saved state, VMs, logs and exposures, and resets the user list to the default admin. There is no undo.
Environment and AI
env
🔒 Per-user environment variables, exported into every command you run (and into your VMs). Values are masked when listed. Typical use: API keys for the AI tools.
sudo env # list (masked)
sudo env set OPENAI_API_KEY=sk-…
sudo env unset OPENAI_API_KEY
sudo env import # copy known provider keys from the server's environment
agent
🔒 A native AI coding agent that can run shell commands and read/write/list files in your current target (the
host for admins, otherwise the VM you are in). Needs a provider key (see env).
sudo agent # interactive session (persists until /exit)
sudo agent "add tests for utils.py"
sudo agent models # list the provider's models
sudo agent help
Inside the session: /help /clear /model <name> /provider /keys /models /compact /system
/exit (or /quit). On the host, obviously destructive shell commands are refused; inside a VM they are allowed.
opencode
🔒 Launches the OpenCode terminal AI. If it isn't installed it starts npm install opencode-ai as a job and tells
you to run it again when done. sudo opencode run "your prompt" runs a single prompt.
Fun commands (eggshells)
These are built in and need no installation.
hello / hi
Greets you by name.
cowsay
cowsay <text> — a cow says it.
fortune
A random quote.
lolcat
lolcat [text] — rainbow-coloured text (default: "rconsole is awesome").
figlet / banner
figlet <text> — big ASCII-art lettering (banner is the same).
sl
Steam locomotive (for when you typed sl instead of ls).
matrix
A frame of green falling characters.
colors
Prints the terminal colour palette.
date
Current date and time.
uptime
How long rconsole has been running.
cal
cal # the whole year
cal 3 # March of this year
cal 3 2027 # March 2027
echo
Prints its arguments. echo -n text omits the newline; echo -e "a\tb\nc" interprets \n \t \r \a \e \xNN.
When the line has a pipe or redirect (echo hi | tr a-z A-Z) the real echo runs in your shell instead.
rev
rev <text> reverses text; rev <file> [file…] reverses each line of files. (With pipes the real rev runs.)
wc
wc <text> or wc <file> [file…] — lines, words and characters, with a total for several files.
(With pipes the real wc runs.)
Interactive programs
These open in a real terminal window (a ✕ button in the top-right closes it; Esc does too):
nano vi vim nvim emacs less more most man top htop btm glances watch tmux screen
mc ranger nnn fzf lynx w3m mutt irssi telnet ssh bash sh zsh fish pwsh powershell
cmd cmd.exe python python3 py ipython pip irb node npm npx php lua opencode
Install what you need in a VM (vm setup tools, apt install vim), then just type the name.
Running anything else (real shell)
Any other word is run by a real shell in your current target, so every program you install works:
git, curl, pip, apt/apk, make, docker-less builds, python main.py, …
- Output is captured and shown when the command finishes (60 s limit). For long or interactive work use
vm shell,&, or an interactive program. - To keep a server running and reachable: start it with
&(or invm shell), then useexpose. vm run,@vm cmdand plain commands in VM mode all go through the same environment:PATHincludes your user tool directories,DEBIAN_FRONTEND=noninteractive,PIP_BREAK_SYSTEM_PACKAGES=1, and any variables you set withsudo env.
