Single-Core Deployment (All in One)
One mistershell/core container running everything — control plane, data services, and an embedded worker. The fastest way to a complete, working MisterShell.
This is one of four supported topologies. For the shared reference (environment variables, TLS, web-session flags, worker registration, scaling, troubleshooting), see the Deployment overview.
Components involved
Everything lives inside a single container:
| Component | Role |
|---|---|
| Reverse proxy | Terminates TLS on :443; :80 serves the full application over plain HTTP by default (set ENABLE_HTTP_REDIRECT=true for health + redirect only) |
| API + web UI | The control plane your users sign in to |
| Session gateway | WebSocket bridge for interactive sessions |
| Embedded worker | Runs every task against any resource the host can reach |
| Embedded database | Relational store (persisted at /data/db) |
| Embedded cache | In-memory hot cache (no volume needed) |
| Embedded app-state store | Live sessions, locks, coordination state |
| Embedded event bus | Standalone durable event store (persisted at /data/nats) |
| Local recordings | Session recordings on disk (/data/recordings) |
You provide only a Linux host with a container runtime and one secret (DB_ENCRYPTION_KEY).
What is NOT under MisterShell’s responsibility
Because the data services are embedded, this topology owns almost everything itself. What remains yours:
- The host and its uptime. A single container is a single point of failure — there is no application-tier redundancy in this topology. If you need that, move to an HA Cluster.
- Backups of the
/datavolume and the database. A consistent volume snapshot covers embedded storage, recordings, and the event store. The scheduled PostgreSQL archive is the portable database backup and remains necessary when the database is external. See Database Backup and Restore. - A trusted TLS certificate (optional). The container generates a self-signed one on first start; replacing it is your call — see TLS.
Architecture
flowchart TB
net["Internet"]
rw1["Remote worker · distant site"]
rw2["Remote worker · distant site"]
subgraph core["Core container — one image, all services embedded"]
proxy["Reverse proxy<br/>:443 TLS + WebSocket · :80 plain HTTP (redirect optional)"]
api["API + Web UI"]
gw["Session gateway"]
wk["Embedded worker"]
data["Embedded data services<br/>database · cache · app-state store · event bus (standalone)"]
vol[("/data volume<br/>database · recordings · event store")]
proxy --> api
proxy --> gw
api --- data
gw --- data
wk --- data
data --- vol
end
net --> proxy
rw1 -. "single outbound connection · optional" .-> proxy
rw2 -. "single outbound connection · optional" .-> proxy
Benefits
- One command to a full workspace. No external database, cache, or load balancer to stand up first.
- Everything embedded persists in one volume. A consistent
/datasnapshot covers the embedded database, recordings, and event store. It does not cover an external database, and the SFTP database archive covers PostgreSQL only—not recordings or the event store. TLS certificate files mounted at startup (and the self-signed bootstrap certificate) live on the container filesystem; a certificate installed from the web UI is stored in PostgreSQL. KeepDB_ENCRYPTION_KEYseparately. See Database Backup and Restore. - Grows with you. Add remote workers at any time to reach resources in other sites or network zones — the core stays a single container.
- Ideal for evaluation, proofs-of-concept, and small single-zone estates (up to a few hundred resources on one host).
Prescriptive deployment guidance
1. Start the container with a persistent volume
docker run -d -p 443:443 -p 80:80 \
-e DB_ENCRYPTION_KEY=your-secret-key \
-v mistershell_data:/data \
--cap-add SYS_ADMIN --security-opt apparmor=unconfined \
--name mistershell \
mistershell/core:latest
DB_ENCRYPTION_KEY encrypts sensitive values at rest — treat it as a credential and back it up; losing it means losing access to stored secrets. The --cap-add / --security-opt flags are required only for web-application sessions (the headless-Chrome sandbox); every other feature works without them.
2. Sign in as the first admin user
On first start with an empty workspace, an admin@mistershell.local account is created automatically. Its password is never written to the container logs. Set one from the operator console:
docker exec -it mistershell msh -y reset admin-user
The command prints the password once, to your terminal. Run it again at any time to rotate it or to recover from a lockout.
To have the password ready before the container ever starts — useful where you can set environment variables but cannot exec into the container — pass it at first boot instead:
-e INITIAL_ADMIN_PASSWORD='<a password meeting your policy>'
It is read only when seeding the admin into an empty install and ignored on every later start. It is taken as given — the password policy you configure later governs passwords set through the application, not this bootstrap value — so choose a strong one and change it once you are in.
Open https://<host>/ and sign in. Expect a browser certificate warning until you install a trusted certificate (see TLS).
3. (Optional) Externalize individual data services
You can keep the all-in-one shape but point any single data service at a managed endpoint — for example, to put your relational data on a backed-up managed database while keeping the rest embedded:
docker run -d -p 443:443 -p 80:80 \
-e DB_ENCRYPTION_KEY=your-secret-key \
-e DATABASE_URL=postgresql+asyncpg://user:password@db.example.com:5432/mistershell_db \
-v mistershell_data:/data \
--name mistershell \
mistershell/core:latest
Any non-localhost value in DATABASE_URL / CACHE_REDIS_URL routes to your own service; leave a variable unset (or localhost) to keep it embedded. Externalizing services on a single core is optional here — it becomes mandatory once you run more than one core (see HA Cluster).
4. Operator console (msh)
Every container runs an operator console for status checks and maintenance, reachable with:
docker exec -it mistershell msh
It offers show version, show system (cpu/memory/disk/network), show log (-f to follow), and show tech-support / write tech-support for a diagnostic bundle. Type bash at the console to drop to a shell. reset admin-user (shown in step 2 above) recovers admin access if the generated password is lost. Manual database backup and guarded restore are described in Database Backup and Restore.
Docker Compose
version: '3.8'
services:
mistershell:
image: mistershell/core:latest
ports:
- "443:443"
- "80:80"
environment:
DB_ENCRYPTION_KEY: ${DB_ENCRYPTION_KEY}
# Required only for web-application sessions (headless-Chrome sandbox).
cap_add:
- SYS_ADMIN
security_opt:
- apparmor:unconfined
volumes:
- mistershell_data:/data
restart: unless-stopped
volumes:
mistershell_data:
When to choose something else
| If you need… | Move to |
|---|---|
| Application-tier redundancy (no single point of failure) in one region | HA Cluster |
| A presence in several regions, one core each | Distributed |
| Both regional presence and per-region redundancy | Distributed with HA |