DockerSelf-HostingAIAI Coding Agents
Kortix CompanyOS (formerly Suna): self-host the AI agent platform on your own server (Linux, Windows, Mac)
Before you start
- 20 min read
- 26 to run in terminal
- 1 file content
Boxes marked Run in terminal are what you type; plain text explains why. Check what you need first

What you get in one minute#
Kortix CompanyOS (the project formerly called Suna) is an open-source platform where AI agents do work for you and your team, each session in its own cloud computer, and you can run the control side on your own Linux server.
Logo: the official Kortix project (github.com/kortix-ai/suna)
Agents, skills, memory and connectors live in one git repository you own, and a person approves what the agents change. The repository address still says suna; the README now says Kortix CompanyOS. Old Suna tutorials describe an older setup.
Say it plainly: self-hosting here is not "everything on my machine". The web app, API, database and HTTPS run on your server. The agent sessions run in sandboxes at Platinum, a paid cloud service, and the AI models come from a provider you pay with your own key. Your server must be reachable from the internet so those sandboxes can call it back.
| What | Value (official docs, read October 2026) |
|---|---|
| Current version | v0.14.12, released 30 October 2026 (release page) |
| Default update track | stable (a release promoted after it runs in production) |
| Licence | Elastic License 2.0: free to use and self-host, but you may not sell it to others as a hosted service |
| Time needed | About 45 minutes plus DNS waiting (our estimate, not measured) |
| Server size | Not published. Per-container memory limits are listed under Performance |
| Ports | 80 and 443 open to the internet. Loopback only: frontend 13737, API 13738, Supabase 13740 |
| Official docs | kortix.com/docs/host and the repository |
At a glance:
- What it is: a company operating system for AI agents: agents, shared skills, a drive, connectors (3,000+ apps plus MCP) and scheduled or webhook triggers.
- Local on your server: web app, REST API, LLM gateway, a full Supabase stack with Postgres, a file store for recordings, and Caddy for HTTPS.
- Not local: Platinum sandboxes (every session), the Drive and App volumes (stored at Platinum), your model provider, and GitHub for project repositories.
- You must bring: a Linux server with a public IP, a domain with DNS records, a Platinum API key and a model provider key.
- Platforms: the server must be Linux. Windows and Mac are admin computers: you use a browser and SSH there. The
kortixcommand line runs on Linux and Mac, and on Windows inside WSL. - Cost: the software is free; Platinum bills prepaid credits per second (see Performance).
How it fits together#
You open your domain in a browser. Caddy on your server answers with a Let's Encrypt certificate and routes to the web app and the API. The API stores data in the local database, starts a Platinum sandbox for each session, calls your model provider and pushes project work to GitHub.
Drawn for this guide from the official self-hosting page. Orange boxes are outside services and need the internet.
Before you start#
| Need | Detail (official docs) |
|---|---|
| Server | A Linux server with a public IP. The bootstrap script runs on Linux only and installs Docker Engine and the Compose plugin if missing. No minimum CPU, RAM or disk is published |
| DNS | A or AAAA records for kortix.example.com and api.kortix.example.com, plus a wildcard *.p.kortix.example.com for previews |
| Ports | 80 and 443 open inbound. The docs use them for the certificate (HTTP-01) |
| Platinum | An account and an API key (PLATINUM_API_KEY). Without it sessions do not start and projects have no Drive |
| Model key | One provider key, added in the web app after the first sign-in. A self-hosted instance has no Kortix-managed models |
| GitHub | A GitHub identity for managed repositories, set at /admin/git after sign-in (or link an existing repository) |
Use your own domain wherever you see kortix.example.com.
Linux server: check Docker if it is already installed (the script installs it otherwise):
docker --version docker compose version
Windows: an admin computer only. Check the SSH client you will use to reach the server:
ssh -V
Mac: an admin computer only. Same check in Terminal:
ssh -V
Checklist:
- [ ] A Linux server you can SSH into, with
sudo - [ ] DNS records created and pointing at the server's public IP
- [ ] Ports 80 and 443 free on the server and open in its firewall
- [ ] Platinum API key and a model provider key ready, kept in a password manager
- [ ] You will back up
.env: it holds the encryption keyAPI_KEY_SECRET
Tested by DIY Lab Hub: not yet. This needs a public domain and paid keys, so every command comes from the official docs and the bootstrap script, read in October 2026. We did not run them. The docs publish no sample output, so "Check it worked" says what to look for.
Step 1: Create the DNS records and collect your keys#
The records must exist before the first start, because Caddy needs them to get the certificate. At your DNS provider, create A (or AAAA) records for kortix.example.com and api.kortix.example.com pointing at the server's public IP, plus a wildcard A record for *.p.kortix.example.com. At Platinum, create an API key. Keep both keys out of chat windows and screenshots.
Linux#
Check the records from any Linux computer (any random name tests the wildcard):
getent hosts kortix.example.com getent hosts api.kortix.example.com getent hosts test1.p.kortix.example.com
Windows (PowerShell)#
Resolve-DnsName kortix.example.com -Type A Resolve-DnsName api.kortix.example.com -Type A Resolve-DnsName test1.p.kortix.example.com -Type A
Mac (Terminal)#
dig +short kortix.example.com dig +short api.kortix.example.com dig +short test1.p.kortix.example.com
Check it worked. All three names return your server's public IP. If one is empty, wait for DNS and ask again.
Tip: Create the wildcard
*.p.<domain>record now. The docs say that without it browser previews fall back to a path proxy that breaks links, andkortix self-host doctorfails.
Step 2: Run the bootstrap script on the server#
The official bootstrap installs Docker if needed, installs the kortix command line, writes the Compose files and starts the stack with a TLS certificate. It is safe to run again. We read the script before writing this step: it takes the key from the environment variable PLATINUM_API_KEY if you set it, so the key stays out of your shell history. The docs run it straight from the dev branch of the repository; we download it first so you can read it.
Linux#
Run this on the server:
read -rs -p "Platinum API key: " PLATINUM_API_KEY; echo; export PLATINUM_API_KEY curl -fsSL https://raw.githubusercontent.com/kortix-ai/suna/dev/scripts/kortix-selfhost-up.sh -o kortix-selfhost-up.sh less kortix-selfhost-up.sh bash kortix-selfhost-up.sh --domain kortix.example.com --email [email protected]
--domain turns on Caddy and TLS. --email is the contact for the certificate. The first image pull can take several minutes.
Windows (PowerShell)#
Not supported as the server. The bootstrap script runs on Linux only, and a server must be reachable from the internet. Log in to your Linux server from PowerShell, then run the Linux commands above inside that session:
ssh <your-user>@<your-server-address>
Mac (Terminal)#
Not supported as the server. Log in to your Linux server and run the Linux commands there:
ssh <your-user>@<your-server-address>
Check it worked. The script ends with "kortix self-host is up." and lists the commands for status, logs, doctor, configure and update. Check the containers:
kortix self-host ps
Tip: If the script says it added your user to the
dockergroup, open a new shell before the nextkortix self-hostcommand, as the docs ask.
Step 3: Answer the setup questions and start#
The bootstrap sets no admin email and no preview domain, so you run configure once. Each answer is pre-filled with the current value, and Enter keeps it.
Linux#
On the server:
kortix self-host configure kortix self-host start
Give your admin email and the preview domain p.kortix.example.com. Press Enter to keep the Platinum key the bootstrap set. configure only writes files; start applies them.
Windows (PowerShell)#
Run the Linux commands in your SSH session to the server.
Mac (Terminal)#
Run the Linux commands in your SSH session to the server.
Check it worked. From any computer:
curl -I https://kortix.example.com
You should see an HTTP status line over HTTPS with no certificate error. On the server, kortix self-host status shows the containers, the last update and the schedule. On Windows use curl.exe -I https://kortix.example.com in PowerShell.
Tip: Caddy asks for each hostname's certificate on the first request, so the first visit can be slow. A lasting certificate error means DNS or port 80 is wrong.
Step 4: Sign up as admin, then close the doors#
The docs are firm about this: until you set EMAIL_URL or DISABLE_SIGNUP=true, anyone who reaches the instance can create a confirmed account for any address, the admin address included. Do it right after the stack starts.
Open https://kortix.example.com in your browser (Windows, Mac and Linux alike) and sign up with the address you gave as admin. Then, on the server:
Linux#
Either connect email (a bare EMAIL_URL makes the command ask for the value, so the password stays out of your history):
kortix self-host env set EMAIL_URL
Or, once your team has signed up, close sign-up:
kortix self-host env set DISABLE_SIGNUP=true kortix self-host start kortix self-host doctor
Windows (PowerShell)#
Run the Linux commands in your SSH session to the server.
Mac (Terminal)#
Run the Linux commands in your SSH session to the server.
Check it worked. kortix self-host doctor exits 0 and prints no failing check. It checks Docker, the Compose file, the preview domain, the email setting and open sign-up. The docs publish no sample output.
Tip: Closing sign-up with
DISABLE_SIGNUP=trueblocks everyone, the admin included, if done before your own account exists. Sign up first.
Step 5: Connect GitHub, add a model key, run a session#
These are browser steps, the same on every system.
- Connect managed git. Open
/admin/git. Kortix creates every project repository through this one GitHub identity. Pick "Create a GitHub App" (the docs recommend it), paste an existing App, or use an access token. - Create the team account. Your sign-up account is personal and cannot hold single sign-on. Create one project at
/new, then open the project menu, choose Switch Project, then Create an account. Only platform admins can create accounts by default. - Create a project in the team account.
- Add a model key in the project: Customize, then Models, then Providers. Each project needs its own key.
- Start a session from the project page.
Linux#
The command-line way to add a model key (run from a computer with the CLI, see Step 6):
kortix providers set <provider>
Windows (PowerShell)#
Use the web app. The command line runs in WSL; see Step 6.
Mac (Terminal)#
Same command as Linux:
kortix providers set <provider>
Check it worked. The session starts, a sandbox is created and the agent replies. If the session never starts, the Platinum key is missing or wrong (see Troubleshooting).
Tip: Start with the docs' own small prompt: "Summarize this week's commits and open a change request". Nothing reaches
mainuntil a person approves.
Step 6: Use the command line from your own computer (optional)#
The kortix command line does from a terminal what the web app does. It runs on Linux and Mac, and on Windows inside WSL.
Linux#
curl -fsSL https://kortix.com/install | bash kortix hosts add mycompany --url https://api.kortix.example.com --login kortix whoami
Windows (PowerShell)#
The installer does not run natively on Windows. Open your WSL shell and use the Linux commands:
wsl
Mac (Terminal)#
Same commands as Linux:
curl -fsSL https://kortix.com/install | bash kortix hosts add mycompany --url https://api.kortix.example.com --login kortix whoami
Check it worked. kortix whoami shows the host mycompany, your user and the active account. The browser opens so you can approve the login.
Put it behind HTTPS (with or without Traefik)#
This stack already includes HTTPS: in domain mode a bundled Caddy takes ports 80 and 443 and gets Let's Encrypt certificates by itself. Usually you need nothing more. Both routes need a public domain, because the Platinum sandboxes must reach your API.
With Traefik#
There is no official Traefik recipe, so this guide gives no Traefik labels. The generated stack has its own Caddy, and the docs say only one domain-mode instance per server can run because Caddy binds 80 and 443. If Traefik already owns those ports on your server, the supported choice is a second server or virtual machine for Kortix. Putting Traefik in front is possible, but the docs do not cover it and you would write the routes yourself.
Without Traefik: Caddy#
This is the default and the supported route. --domain in Step 2 turned on the bundled Caddy. You do not write a Caddyfile; kortix self-host init writes one. For orientation, this is the routing it does, taken from the docs' routing table. It is a simplified sketch, not the generated file, which also adds health checks, two replicas, an HSTS header and the wildcard blocks:
kortix.example.com {
@supabase path /rest/v1/* /auth/v1/* /storage/v1/* /realtime/v1/* /functions/v1/* /graphql/v1/*
handle @supabase {
reverse_proxy supabase-kong:8000
}
handle {
reverse_proxy frontend:3000
}
}
api.kortix.example.com {
handle /v1/llm* {
reverse_proxy llm-gateway:8090
}
handle {
reverse_proxy kortix-api:8008
}
}
What this means for you:
| Case | What to do |
|---|---|
| Public domain | Create the DNS records, open ports 80 and 443, run Step 2 with --domain. Certificates are automatic. |
| Home only, no public domain | A local certificate (tls internal) does not help here. Without a public address the sandboxes cannot reach your API, so sessions do not run. The docs call the no-domain mode "local": it binds loopback ports only and is for looking around. |
Check it worked. curl -I https://kortix.example.com and curl -I https://api.kortix.example.com both return an HTTP status line over HTTPS.
Security and testing#
| Control | How (official docs) |
|---|---|
| Public ports | Only Caddy publishes 80 and 443. Every other published port binds 127.0.0.1 |
| Secrets file | .env and docker-compose.yml are written with mode 0600. Keep it that way |
| Sign-up | Set EMAIL_URL or DISABLE_SIGNUP=true (Step 4). Account creation is restricted to platform admins by default |
| Connectors | They refuse private and internal addresses (connector_egress_blocked). List allowed internal hosts in KORTIX_CONNECTOR_EGRESS_ALLOW_HOSTS |
| Supabase Studio | Answers on 127.0.0.1:13740 on the server only. Use an SSH tunnel |
| Encryption key | API_KEY_SECRET in .env encrypts every stored secret. Back it up; the CLI refuses to rotate it |
Quick tests, on the server:
kortix self-host doctor kortix self-host ps kortix self-host logs kortix-api
What leaves your server: calls to Platinum, your model provider and GitHub, image pulls from Docker Hub, and the optional app catalog if you set COMPOSIO_API_KEY. The README says so: this is a self-hosted install, not a disconnected one.
Licence note: a separate free white-label licence exists for reselling. Its one requirement is Platinum as your exclusive compute provider, and Kortix may end it with notice.
Common mistakes#
These come from the official docs' own warnings, the project's issue tracker, and typical AI assistant answers.
| Mistake | Why it happens | Do this instead |
|---|---|---|
Installing without --domain and expecting agents to work | The no-domain "local" mode binds loopback ports only. The docs say sessions do not run, because the sandbox cannot reach your API | Use a domain and a public server for real use; treat local mode as a look around |
| Leaving out the Platinum key | Everything looks fine until a session fails. The docs: without PLATINUM_API_KEY sessions do not start and projects have no Drive | Set the key in Step 2, or later with kortix self-host configure |
| Leaving sign-up open | A new instance confirms every sign-up without an email. doctor reports open-sign-up | Sign up as admin first, then set EMAIL_URL or DISABLE_SIGNUP=true |
Forgetting the *.p.<domain> wildcard record | The page works without it, so people skip it. Previews then use a path proxy that breaks root-absolute links, and doctor fails | Add the wildcard A record and set the preview domain in configure |
Losing .env | It looks like a plain config file. API_KEY_SECRET in it decrypts every stored key and token; without it you get SECRET_UNDECRYPTABLE | Back up the instance folder (see Updates and backups) and keep a copy off the server |
| Following an old Suna tutorial | The repository address still says suna. Older setups used your own Supabase project and a Daytona key; the bootstrap script calls Daytona a legacy fallback. Issue #2459 shows an old Supabase Cloud setup failing on WSL2 | Use only the current self-hosting page and the bootstrap script from this guide |
| Running the server on Windows or Mac | The bootstrap script exits on non-Linux systems. Issues #3072 and #3073 (April 2026, closed) report a Mac Docker Desktop install stuck on "Unreachable" in an old version | Use a Linux server. Windows and Mac are for the browser, SSH and the CLI |
| Pinning a version and expecting auto-updates | A pinned --tag wins over the channel. The docs say a pin holds through every daily update | Run kortix self-host update when you want to move; unpin by updating without --tag |
| Selling access to your instance | "Open source" suggests anything goes. Elastic License 2.0 forbids a hosted service for others | Use it for your own team, or read the white-label licence |
| AI assistants: mixing old Suna steps into Kortix | Assistants can repeat older tutorials: a Supabase project and a Daytona key in a .env, or a plain docker compose up in the cloned repository. The current stack is generated by kortix self-host | Run only commands from the current docs and this guide; check every flag with kortix self-host --help |
Tip: Before running any command an AI assistant suggests, search the official self-hosting page for it. The CLI changed a lot between 0.8.x and 0.14.x.
Tip: Test one tiny session before inviting a team. A working sign-in does not prove the sandbox, the model key and GitHub all work.
Troubleshooting#
| Problem | Solution |
|---|---|
| Sessions never start | Check the Platinum key: kortix self-host env ls (secrets are masked), then kortix self-host configure and start. Look at kortix self-host logs kortix-api |
kortix self-host doctor fails preview-origins | Add the wildcard record *.p.<domain>, then kortix self-host env set KORTIX_PREVIEW_BASE_DOMAIN=p.<domain> KORTIX_PREVIEW_ALLOW_DIRECT_EDGE=true |
doctor fails open-sign-up | Set EMAIL_URL, or DISABLE_SIGNUP=true once your team is in |
| Certificate error on the first visit | Check DNS for both hostnames and that ports 80 and 443 reach the server. Caddy needs HTTP-01 |
| New project form: "Kortix-managed repositories are not available on this instance." | Set up managed git at /admin/git |
403 sso_personal_account | Your sign-up account is personal. Create a team account (Step 5) and set up SSO there |
409 SECRET_UNDECRYPTABLE or credential_undecryptable | API_KEY_SECRET changed or was lost. Restore .env from a backup, or enter each secret again |
session log release refused during an update | Pin the converting version first: kortix self-host update --tag 0.14.9, wait for the log line, then kortix self-host update |
| A change does not take effect | Run kortix self-host start; it recreates every service whose configuration changed |
Known bugs#
The issue tracker had no open issues when we looked in October 2026. The closed April 2026 reports (#3070, #3072, #3073, #3086) describe the older local-mode installer. Issue #3086 notes an installer exit on a flaky registry or DNS lookup during the image pull; if your first start stops with a network error, run kortix self-host start again.
Diagnostics:
kortix self-host status kortix self-host ps kortix self-host logs kortix-api kortix self-host doctor --json
Updates and backups#
Update. Auto-update is on by default: a container named kortix-updater pulls new images once a day at 02:00 New York time. It checks disk space, runs the database migration, then rolls the services; a failed migration or swap keeps the previous version serving. To do it yourself:
kortix self-host version kortix self-host update kortix self-host update --tag 0.14.12 kortix self-host rollback --release <version>
version shows the running version, the latest and the channel. A --tag pin holds through the daily runs. The stable images were last updated on 22 October 2026, so they can be older than 0.14.12; kortix self-host version shows what you run.
Back up. The docs split the data in two: the instance folder ~/.config/kortix/self-host/<instance>/ (it holds .env, the database and the stored files) and four Docker volumes. Stop the stack so the files are consistent. This script is the docs' own, with the instance named default:
kortix self-host stop
cd ~
sudo tar -czf kortix-backup.tgz -C ~/.config/kortix/self-host default
for v in db-config kortix-capture-data kortix-caddy-data kortix-updater-state; do
docker run --rm -v "kortix-default_$v":/data -v "$PWD":/backup alpine:3.20 \
tar -czf "/backup/$v.tgz" -C /data .
done
kortix self-host start
chmod 600 kortix-backup.tgz *.tgz
The backup holds every secret, so keep it private. Drive folders, App volumes and each session's /workspace live at Platinum and are not in this backup. To run it nightly at 03:00 on Linux, put the same commands in a script and add a crontab line; the stack is stopped for the duration, so choose a quiet hour.
Restore. On a server with Docker and the CLI, put the archives in your home folder, then:
mkdir -p ~/.config/kortix/self-host
sudo tar -xzf kortix-backup.tgz -C ~/.config/kortix/self-host
for v in db-config kortix-capture-data kortix-caddy-data kortix-updater-state; do
docker run --rm -v "kortix-default_$v":/data -v "$PWD":/backup alpine:3.20 \
tar -xzf "/backup/$v.tgz" -C /data
done
kortix self-host start
start warns that each volume was not created by Docker Compose; the docs call it harmless. Test a restore on a spare server first. kortix self-host uninstall deletes the database, files, recordings and certificates and cannot be undone.
Windows (PowerShell)#
Copy the backup off the Linux server from your PC (it has the keys, so store it somewhere safe):
scp <your-user>@<your-server-address>:~/kortix-backup.tgz .
Mac (Terminal)#
Use the same scp command from Terminal:
scp <your-user>@<your-server-address>:~/kortix-backup.tgz .
Performance and resources#
The docs publish no required CPU, RAM or disk for the server, so this guide gives none. They publish these defaults:
| Setting | Default |
|---|---|
kortix-api memory limit (KORTIX_API_MEMORY_LIMIT) | 2048m |
llm-gateway memory limit (KORTIX_GATEWAY_MEMORY_LIMIT) | 2048m |
frontend memory limit (KORTIX_FRONTEND_MEMORY_LIMIT) | 512m |
| Postgres memory limit | 1280m, fixed |
| Replicas in domain mode | 2 each of API, gateway and frontend |
| Logs | 3 files of 10 MB per container |
| Free disk the updater needs | 2048 MB (KORTIX_MIN_FREE_DISK_MB) |
| Sandbox stops after idle time | 15 minutes (KORTIX_SANDBOX_AUTOSTOP_MINUTES) |
| Default sandbox size | 2 vCPU, 4 GB RAM, 20 GB disk |
These are ceilings per container, not measured use. Measure your own server:
docker stats --no-stream df -h
Cost note. Platinum's website lists $0.0324 per vCPU-hour and $0.0108 per GB of RAM-hour, billed per second while a sandbox runs, with prepaid credits and no subscription. By our arithmetic a default 2 vCPU, 4 GB sandbox is about 11 cents per running hour. This is not an official figure; the page marked its prices verified in July 2026. Model calls are billed by your provider on top.
FAQ#
Is Kortix CompanyOS the same as Suna? It is the same repository and project, renamed. The README now says Kortix CompanyOS. Older Suna guides describe an older setup.
Is it free? The software is free under Elastic License 2.0. Sandboxes and model calls cost money.
Can I run it fully offline or on my own models only? Not from what the docs say. Sessions run in Platinum sandboxes, and the stack pulls images from Docker Hub. A project can connect any provider with your own key, but the docs do not describe a local-model setup, and we did not test one.
Can I run it on Windows or a Mac? Not as the server. Use a Linux server. Windows and Mac work as admin computers: browser, SSH, and the CLI (on Windows inside WSL).
Sources#
- Kortix self-hosting and developer docs (Self-hosting, CLI, Backup, Updates) - read October 2026
- kortix-ai/suna README, LICENSE and WHITE-LABEL-LICENSE.md - read October 2026
- Release v0.14.12 (30 October 2026) and the bootstrap script - read October 2026
- Docker Hub images kortix-api, kortix-frontend and kortix-gateway (tags
0.14.12,latest,stableseen) - October 2026 - Platinum (pricing and billing) - read October 2026
- GitHub issues #2459, #3063, #3070, #3072, #3073 and #3086 - read October 2026
- Our related guides: Supabase self-hosted with Docker (the database layer this stack bundles) and OpenHands with local models (another self-hosted coding agent)
Checked against the official docs on 2026-10-31.