How to self-host Rakazo for your own AI bot
Run Rakazo for your own AI bot on VPS with Node 22, pnpm, Postgres and Graphile Worker in Docker Compose, plus sandbox choice, keys and honest sizing.
Wetin self-hosting Rakazo really dey run
Self-hosting Rakazo mean say you dey run five things for one Linux server: PostgreSQL, one Graphile Worker process, the API, the web app, and one sandbox container for every bot wey dey awake. Rakazo na open-source alternative to Grok Bot, wey elie222 publish under Apache 2.0 licence. Every bot get im own thread, im own computer, im own memory, and im own history. E fit also create peers or short-lived subagents.
Na that last part make VPS (virtual private server) better place for this work, instead of desktop. Bot wey dey keep memory and run scheduled work must dey reachable while you dey sleep. Laptop wey suspend go drop the queue.
Rakazo still dey early beta as of August 2026, so treat this as working setup, no be finished appliance. The whole stack use TypeScript: React 19 and Vite for the web app, Hono for the API, Postgres with Prisma, Better Auth for accounts, and Graphile Worker for background jobs. Graphile Worker dey store im queue inside Postgres, so Redis no dey needed and you no need run second data store. .env.example dey set WAKEUP_DRIVER=graphile, meaning say when bot wake up, na Postgres-backed job dey run. If you stop Postgres, every scheduled bot action go stop too. If you prefer assemble agent from separate parts instead of running another person product, build your own agent from components na the other route.
Wetin make 1 GB plan no fit handle this
Count the processes. Postgres na one. The API na one Node process. The worker na second one. The web app na third one. The sandbox supervisor na fourth one. Then every bot wey dey run gets one container wey hold graphical Linux desktop and browser.
The project own self-host doc give one honest figure: machine wey get 2 vCPU and 4 GB fit handle the API, the worker and Postgres when E2B dey own the bot desktops. Na number for control plane alone be this, while dem dey host the heavy part for another place. Set SANDBOX_PROVIDER=docker and those desktops go move enter your VPS, so 4 GB go become the minimum instead of the target. Start with 8 GB if you plan keep more than one bot awake, and measure the real number with docker stats while bot dey work. The browser inside the sandbox na wetin dey increase memory use, so spec sheet no go tell you the actual number. For the general method to size box for agent work, how much RAM and CPU agent VPS really need explain the measurement well.
One setting dey prevent this matter from getting worse. .env.example dey ship SANDBOX_IDLE_MS=600000 with comment say e pauses E2B computers, or stops Docker ones, after that number of idle milliseconds. If computer idle for ten minutes, e go disappear. The smallest accepted value na 30000. Without that setting, every bot wey you ever open go hold memory forever.
Disk matter too. The sandbox image, the Node modules and the Postgres volume dey share one disk, so 40 GB na sensible starting point.
Pin version before you clone
Rakazo dey move fast and main no be release. As of 16 August 2026, repository get exactly one tag, v0.1.0-beta, wey dem publish on 13 August 2026 and mark as prerelease.
git clone https://github.com/elie222/rakazo.git
cd rakazo
git checkout 53b119a68d9ef843d23aa3b7e3719b6be7b51fdb
git log -1 --format='%H %ci'Na that commit v0.1.0-beta dey point to. Pin the commit instead of branch or tag. Branch fit change under you for the next git pull, and tag na movable label wey maintainer fit point to another place, so neither one identify tree wey you fit return to. Commit identifier no fit move. Write your own down beside your other server facts, because when upgrade break things, the cheap fix na git checkout <old commit> and rebuild, and that one only work if you know which commit dey work.
Requirements: Node 22, pnpm 9, and Docker
node -v
pnpm -v
docker --versionpackage.json dey declare "engines": { "node": ">=22" } and "packageManager": "pnpm@9.15.0", so node -v must print v22 or higher. Node package for Ubuntu archive dey usually old pass that one, so install am from NodeSource or nvm. pnpm dey come with Node through corepack:
corepack enable
corepack prepare pnpm@9.15.0 --activateDocker Engine plus compose plugin cover the remaining work, and your user must fit reach the daemon. If docker ps answer permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock, add your user to docker group and open new login shell. First understand wetin that permission grant: membership for docker be equivalent to root for the machine, because anybody for that group fit start container wey mount the host filesystem.
Configure .env, then start Postgres
cp .env.example .env
chmod 600 .envTwo values must change before anything faces a network. .env.example dey ship with BETTER_AUTH_SECRET=replace-with-32-plus-character-secret and ENCRYPTION_KEY=replace-with-64-char-hex-or-passphrase. Rakazo rejects those placeholder values outside development, so deploy wey no complete go fail clearly instead of running with secret wey dey published for repository.
openssl rand -base64 48
openssl rand -hex 32Then start the database by itself and run the migrations.
docker compose --env-file .env -f infra/compose/docker-compose.yml up postgres -d
pnpm install
pnpm db:generate
pnpm db:migrate
pnpm sandbox:buildpnpm sandbox:build dey build the bot computer image, wey dem define for package.json as docker build -t rakazo/computer:local infra/sandboxes/computer. Na graphical image, so first build go pull plenty things and e go take time. Confirm say e land with docker image ls rakazo/computer; e suppose print one row.
The compose file dey publish Postgres as 127.0.0.1:5433:5432, and na loopback only. Leave am like that. The development credentials na rakazo:rakazo, and dem dey repository. If Postgres port wey get published password dey reachable from internet, scanners fit find am within hours. The production compose file dey read POSTGRES_PASSWORD instead, so set am to random string when you reach there.
Di first run
pnpm devDis one go start four things: the API for port 3100, Graphile Worker, the Vite web app for 5173, and the sandbox supervisor for 7091. App dey for http://127.0.0.1:5173, and you suppose see sign-in page.
For VPS, you no dey sit for that machine, and you no suppose publish 5173 to reach am. Forward the ports through SSH (secure shell) from your own machine instead.
ssh -L 5173:127.0.0.1:5173 -L 3100:127.0.0.1:3100 you@your-serverPay attention to the difference between the two ways to run dis. pnpm dev run Vite for the host and bind am locally. The compose file get web service wey publish 5173:5173 for every interface. If you bring up the full development compose stack for public VPS, app go expose, so use the production file and its reverse proxy for anything wey you leave running.
Which sandbox provider dey safe for server?
This na the one setting wey you must set correctly. SANDBOX_PROVIDER for .env dey take four values.
dockerna the default. Each bot go get its own container for your machine, built from the image weypnpm sandbox:buildproduce. Na the fastest self-hosted setup.e2bdey run the bot computers for E2B and e needE2B_API_KEY. The project recommend am for public or multi-user deployments, because e keep bot computers separate from the host wey dey run your API and database.desktopdey run the bot commands directly for the API and worker host. The repository instruction clear: no use am for public or shared server.fakena in-process emulator for tests. E no be runtime.
Take that desktop warning serious. For desktop mode, no isolation boundary dey at all. So the bot go run shell commands as the user wey dey run the API process, with that user home directory, SSH keys, cloud credentials, and .env. Any text wey bot read for web page fit become command for your server. Desktop mode for server na how bot fit end up with your credentials. Use am for machine wey you dey sit down use, or no use am at all.
docker na real boundary, but e no perfect. One bot no fit read another bot files because each one get its own container. But the supervisor wey dey create those containers mount /var/run/docker.sock, and control of the host Docker socket mean control of the host. So keep the supervisor private. .env.example document SANDBOX_SUPERVISOR_TOKEN as optional separate service credential wey default to BETTER_AUTH_SECRET when e empty. This mean say if you leave that secret as the placeholder, e go protect the container-creating service with string wey anybody fit read for GitHub. Set both values. For the strongest separation wey dey available here, use e2b, or give Rakazo one machine wey no hold anything else. Na the same reason behind running coding agents inside disposable VM: the cheapest way to survive when agent do something wrong na make the machine no get any value.
Model API keys go where?
Rakazo no get managed model billing. Na you go bring the key. .env.example dey set PI_DEFAULT_PROVIDER=openrouter, so OPENROUTER_API_KEY na the normal place, and provider keys dey work through the same setting.
Keep the key inside .env, and no put am for any file wey you commit. Both compose commands for the repository dey pass --env-file .env, so values go reach the containers without dem ever write am inside YAML wey git dey track. You fit also leave OPENROUTER_API_KEY empty and paste key inside the app during onboarding. Na another reason be say ENCRYPTION_KEY need real random value instead of the placeholder wey come with am.
Set spending limit for the key with the provider before any bot use am. Bot wey enter loop na bot wey dey spend money, and per-key limit na the only stop wey no depend on you monitoring am. Give this key im own name so you fit revoke am alone.
From dev mode go something wey you fit leave dey run
Repository get production compose file wey dey run Postgres, the API, the worker, the web app, and Caddy for TLS (transport layer security) certificates wey e dey obtain automatically. E expect E2B for the bot computers.
sudo DEPLOY_USER=deploy bash infra/compose/harden-host.sh
docker compose --env-file .env -f infra/compose/docker-compose.prod.yml up -d --buildharden-host.sh dey disable SSH password login, set UFW (uncomplicated firewall) rules for SSH, HTTP and HTTPS, turn on fail2ban, and apply AppArmor profiles. Read am before you run am, because e go change how you dey log in. Keep second SSH session open while e dey run.
The production .env need more than the development one. The self-host doc list this minimum.
NODE_ENV=production
RAKAZO_HOST=app.example.com
BETTER_AUTH_URL=https://app.example.com
WEB_ORIGIN=https://app.example.com
API_URL=https://app.example.com
POSTGRES_PASSWORD=<random>
BETTER_AUTH_SECRET=<random>
ENCRYPTION_KEY=<random>
E2B_API_KEY=<your key>
OPENROUTER_API_KEY=<your key>
SANDBOX_PROVIDER=e2b
AGENT_RUNTIME=pi
DATA_DIR=/dataPoint an A record to the server before that first up. Caddy dey request certificate for the name wey dey inside RAKAZO_HOST, and the request go fail if the name no resolve to this box or if port 80 dey closed to outside.
Also set SIGNUP_ALLOWLIST=you@example.com. SIGNUPS_ENABLED=true na the default, so instance for public name go accept registrations from anybody wey find am, and every new account go get computer. Allowlist first. You fit relax am later if you want.
Treat docs/self-host.md for repository as the authority for production settings, because e dey change with the code and this guide no dey change with am. Since Compose dey do the work, ordinary rules still apply, and the Docker Compose basics for VPS cover why --env-file and named volumes matter more once stack don become something wey you leave alone for months.
Backups
Postgres and the data/ directory na the complete instance.
./scripts/backup.sh
./scripts/restore.sh backups/BACKUP_TIMESTAMPbackup.sh dey dump Postgres and archive data/. For machine wey you depend on, install infra/compose/backup-prod.sh as /usr/local/sbin/rakazo-backup with the timer wey repository supply, so rotation go happen by itself. Backup wey dey for the same disk with database no be backup, so copy am comot from the server. Then restore am once for spare server before you need am.
Why e dey fail, and wetin you go see
pnpm db:migrate no fit reach the database. The migration report say e no fit reach the database server for 127.0.0.1:5433. Either the Postgres container no dey up, or e dey up but e never ready. Run docker compose --env-file .env -f infra/compose/docker-compose.yml ps and check say the postgres service dey report healthy, because the compose file get health check wey dey run every three seconds. If container dey restart continuously, e usually mean say dem create the pgdata volume with different credentials. docker compose ... down -v go clear am, and e go delete the data join.
The port don already dey use. When you bring Postgres up, e fail with bind: address already in use if another thing dey hold 5433. Most times, na earlier Rakazo stack wey you forget stop. sudo ss -lntp | grep 5433 go show the process name.
Bot no ever get computer. If you get SANDBOX_PROVIDER=docker but no rakazo/computer:local image, nothing dey to start. docker image ls rakazo/computer go answer the problem for one line, and pnpm sandbox:build go fix am. If the supervisor no fit reach Docker socket, e no fit create containers too. The message go show the path: permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock.
Long command dey stop halfway. .env.example set SANDBOX_COMMAND_TIMEOUT_MS=300000, so one command inside bot computer go stop after five minutes. Increase am for slow builds instead of assuming say sandbox crash.
pnpm install dey fail for confusing ways. Check node -v before anything else. The workspace declare >=22, and older Node dey fail inside dependency code instead of showing message about versions.
Sign-in dey work locally but e no work through the domain. BETTER_AUTH_URL, WEB_ORIGIN and API_URL must all contain the same public origin wey dey for address bar, including the scheme. If stale http://127.0.0.1:5173 remain for any of dem, na usually that one dey cause session wey no dey stay active.
Updating a pinned checkout
The upgrade path for the self-host doc short: pull the new source, run the database migration, restart the API and the worker.
./scripts/backup.sh
git fetch --all
git checkout NEW_COMMIT_SHA
pnpm install
pnpm --filter @rakazo/db migrate
docker compose --env-file .env -f infra/compose/docker-compose.prod.yml up -d --buildBack up first. Migrations dey move forward, and beta no give you any reverse path wey you fit trust. Read the commits between your pinned SHA and the new one before you apply dem, because project wey young like this fit rename environment variables without announcement, and missing variable go show as service wey start then exit. If you still dey decide whether Rakazo na the correct thing to run at all, the roundup of self-hosted AI agents explain wetin else dey this category and wetin e cost to keep each one running.
FAQ
I fit run Rakazo for a 1 GB VPS?
No. Postgres, the API, the worker, the sandbox supervisor and the web app all dey run at the same time, and with SANDBOX_PROVIDER=docker every bot wey dey awake dey add one container wey hold graphical desktop and browser. The project own doc talk say 2 vCPU and 4 GB enough for the API, worker and Postgres only when E2B dey host the bot desktops. Treat 4 GB as the minimum for the control plane, and use more when the desktops dey run for your machine.
Desktop sandbox provider safe for server?
No. desktop dey run the bot commands directly for the API and worker host, as the user wey dey run that process, and the user files and credentials dey reachable. The repository talk say make you no use am for public or shared server. Use docker for one container per bot, or e2b when more than one person dey sign in.
Which Rakazo version I suppose install?
As of 16 August 2026, na one tag dey, v0.1.0-beta, wey dem publish on 13 August 2026 and mark as prerelease. Check out the commit wey e point to, 53b119a68d9ef843d23aa3b7e3719b6be7b51fdb, instead of tracking main. Branch fit change under you, and tag fit point to another place, so neither one identify a tree wey you fit return to. Record the commit, because rollback only possible when you know the one wey work.
Where I suppose put my OpenRouter API key?
Put am for .env as OPENROUTER_API_KEY, and never put am for compose file wey you commit. Both compose commands for the repository pass --env-file .env, so the value reach the containers without writing am inside tracked YAML. You fit also leave am empty and paste the key for the app during onboarding. Set spending limit for the key with the provider, because bot wey enter loop go continue call the model until something stop am.
I need domain name and TLS?
For anything beyond first test, yes. The production compose file dey run Caddy and obtain certificates automatically, and RAKAZO_HOST, BETTER_AUTH_URL, WEB_ORIGIN and API_URL must all carry the same public HTTPS origin. For first look, you fit skip the domain: run pnpm dev and forward port 5173 through SSH instead of publishing am.