Atlas Lab is a localhost-first self-hosted platform made of a Node.js/TypeScript CLI, a layered Docker Compose stack, and an operational React dashboard served by Caddy.
It provides a core collaboration layer with GitLab CE, BookStack, and Penpot, plus optional AI and development layers. Everything is reachable through dedicated HTTPS ports on localhost, with persistent state stored in Docker volumes.
- π§ Overview
- ποΈ Architecture
- π Services, Ports, and URLs
- πΈοΈ Docker Networks
- πΎ Persistence
- π§° Host Requirements
- βοΈ Central Configuration
- π Quick Start
- π§ͺ CLI Workflows
- π₯οΈ Atlas Dashboard
- π¦ Backup and Restore
- π Default Credentials
- π§© Adding Services
- ποΈ Repository Layout
- π©Ί Troubleshooting
- π‘οΈ Security Notes
- π Official References
- π License
- Always-on core layer with Atlas Dashboard, GitLab CE, BookStack, and Penpot.
- Optional AI LLM layer with Open WebUI, Ollama, and n8n.
- Optional workbench layer with browser-based Node and Python environments plus shared PostgreSQL.
- HTTPS-only browser ingress on
localhost. - Self-contained npm package that can run without a local repository checkout.
- Image and volume backup workflows through the CLI.
- no internal DNS requirement
- no
hostsfile edits - no disposable init containers in Compose
- no hard dependency on a checked-out repo after packaging
- one operational flow for startup, bootstrap, diagnostics, backup, and restore
Atlas Lab is split into three explicit layers.
| Layer | Status | Includes | Purpose |
|---|---|---|---|
core |
always on | gateway, Atlas Dashboard, GitLab CE, BookStack, Penpot, and backing data services | baseline self-hosted platform |
ai-llm |
optional | Open WebUI, Ollama, n8n, AI gateway | local AI workflows and automation |
workbench |
optional | Node Forge, Python Grid, shared PostgreSQL, workbench gateway | browser-based development |
The current topology uses localhost plus dedicated HTTPS ports. That keeps the stack predictable on a single machine and avoids local DNS maintenance.
Bootstrap is handled by the TypeScript CLI.
The CLI:
- starts Docker Compose
- runs host preflight checks
- validates Compose and repository assets
- aligns the BookStack initial admin account
- aligns the Penpot root profile
- aligns the n8n owner account when the AI LLM layer is enabled
- reconciles Ollama models when the AI LLM layer is enabled
GitLab CE initializes its root account during first container boot through the GitLab Docker/Omnibus configuration.
All browser entry points are exposed over HTTPS on localhost.
| Service | Layer | URL / Endpoint | Notes |
|---|---|---|---|
| Atlas Dashboard | core |
https://localhost:8443/ |
operational dashboard |
| GitLab CE | core |
https://localhost:8444/ |
repositories, issues, merge requests |
| Open WebUI | ai-llm |
https://localhost:8446/ |
only with --with-ai-llm |
| Ollama | ai-llm |
https://localhost:8447/ |
HTTPS API with gateway auth |
| Penpot | core |
https://localhost:8448/ |
collaborative design workspace |
| Node Forge | workbench |
https://localhost:8450/ |
Node / TypeScript workspace |
| Python Grid | workbench |
https://localhost:8451/ |
Python workspace |
| BookStack | core |
https://localhost:8452/ |
structured internal documentation |
| n8n | ai-llm |
https://localhost:8453/ |
workflow automation |
| PostgreSQL | workbench |
localhost:15432 |
host-side desktop access |
Operational rules:
- browsers always go through Caddy
- optional layers never start implicitly
- host-side PostgreSQL clients must use
localhost:15432
| Network | Type | Purpose |
|---|---|---|
edge-net |
exposed | published ingress ports |
apps-net |
internal | GitLab CE, BookStack, and gateway-routed browser services |
bookstack-net |
internal | BookStack and its MariaDB database |
penpot-net |
internal | Penpot application services |
ai-llm-net |
internal | Open WebUI, Ollama, and n8n |
workbench-net |
internal | workbenches and PostgreSQL |
workbench-host-net |
bridge | host-side PostgreSQL bind |
services-egress-net |
selective egress | outbound access for core services |
workbench-egress-net |
selective egress | outbound access for workbench services |
The gateway remains the only public browser entry point for web services.
Atlas Lab uses named Docker volumes for runtime state.
Core volumes:
gateway-certsgateway-configgateway-sitegateway-datagitlab-configgitlab-logsgitlab-databookstack-configbookstack-dbpenpot-assetspenpot-postgres
Optional layer volumes:
ollama-datan8n-dataopen-webui-datapostgres-dev-data- Node and Python workbench home/workspace volumes
Recreating containers does not wipe state. Removing volumes does.
When migrating from an older local run, stop the stack with:
npm run dev -- downThe current Compose files no longer reference removed core services. Any older unused volumes remain on disk until you inspect and delete them manually.
Required software:
- Docker Engine with Docker Compose v2
- Node.js >= 20
- npm
AI LLM requirements:
- NVIDIA GPU
- working
nvidia-smi - Docker configured with NVIDIA GPU support
Recommended resources:
- CPU: 4 vCPU or better
- RAM: 8 GB minimum, 12-16 GB preferred
- disk: 20 GB free or more
- VRAM: 8 GB or more for comfortable Ollama usage
Ports that should be free:
84438444844684478448845084518452845315432whenworkbenchis enabled
The main runtime configuration lives in:
Key variables include:
LAB_HTTPS_PORT,GITLAB_HTTPS_PORT,PENPOT_HTTPS_PORT,BOOKSTACK_HTTPS_PORTOPENWEBUI_HTTPS_PORT,OLLAMA_HTTPS_PORT,N8N_HTTPS_PORTNODE_DEV_HTTPS_PORT,PYTHON_DEV_HTTPS_PORT,POSTGRES_DEV_HOST_PORTGITLAB_EXTERNAL_URL,GITLAB_URLGITLAB_ROOT_USERNAME,GITLAB_ROOT_PASSWORD,GITLAB_ROOT_EMAILBOOKSTACK_URL,BOOKSTACK_ROOT_EMAIL,BOOKSTACK_ROOT_PASSWORDPENPOT_ROOT_EMAIL,PENPOT_ROOT_PASSWORDN8N_ROOT_EMAIL,N8N_ROOT_PASSWORDOLLAMA_CHAT_MODEL,OLLAMA_EMBEDDING_MODEL,OLLAMA_RUNTIME_MODELS
Rule of thumb:
- change ports, versions, credentials, and models in
env/lab.env - change routing and runtime content in
config/gateway/templates/ - change CLI behavior in
src/
Check prerequisites:
docker version
docker compose version
node --version
npm --versionInstall dependencies:
npm installStart the core layer:
npm run dev -- upStart core plus AI LLM:
npm run dev -- up --with-ai-llmStart core plus workbench:
npm run dev -- up --with-workbenchStart the full lab:
npm run dev -- up --with-ai-llm --with-workbenchRun health checks:
npm run dev -- doctor --smoke
npm run dev -- doctor --with-ai-llm --smoke
npm run dev -- doctor --with-workbench --smokeStop the lab:
npm run dev -- downGitLab CE can take several minutes to finish its first boot. The CLI bootstrap also aligns the configured root account after GitLab is healthy, so rerunning atlas-lab bootstrap refreshes the root password stored in env/lab.env.
| Command | Role |
|---|---|
atlas-lab up |
starts core only |
atlas-lab up --with-ai-llm |
adds the AI LLM layer |
atlas-lab up --with-workbench |
adds the workbench layer |
atlas-lab up --with-ai-llm --with-workbench |
starts the full lab |
atlas-lab bootstrap |
reruns core bootstrap |
atlas-lab bootstrap --with-ai-llm |
reruns bootstrap, n8n owner alignment, and Ollama reconciliation |
atlas-lab doctor |
runs host and configuration checks |
atlas-lab doctor --smoke |
adds smoke tests for the core layer |
atlas-lab doctor --with-ai-llm --smoke |
adds smoke tests for the AI LLM layer |
atlas-lab doctor --with-workbench --smoke |
adds smoke tests for the workbench layer |
atlas-lab status |
shows Compose/runtime status |
atlas-lab down |
stops the stack |
atlas-lab save-images |
exports Docker images to a single archive |
atlas-lab restore-images |
restores Docker images from an archive |
atlas-lab save-volumes |
exports Docker volumes to a single archive |
atlas-lab restore-volumes |
restores Docker volumes from an archive |
Self-contained packaging:
npm run pack:local
npm install -g .\cli-node-docker-atlas-lab-<version>.tgz
atlas-lab statusThe dashboard frontend lives in:
Responsibilities:
- visualize layer state
- surface operational links
- expose local markdown briefings
- show credentials and runtime notes
- support
it/enlocalization
Local dashboard development:
npm run dev:atlas-dashboardAtlas Lab supports backup and restore for Docker images and Docker volumes.
Examples:
npm run dev -- save-images --with-ai-llm --with-workbench
npm run dev -- restore-images --input .\backups\images\atlas-lab-images.tar.gz
npm run dev -- down
npm run dev -- save-volumes --with-ai-llm --with-workbench
npm run dev -- restore-volumes --input .\backups\volumes\atlas-lab-volumes.tar.gzBootstrap is idempotent for GitLab CE, BookStack initial setup, Penpot, and the optional AI LLM services.
These credentials are intended for trusted local environments and are configurable through env/lab.env.
| Service | URL / Endpoint | Credentials |
|---|---|---|
| Atlas Dashboard | https://localhost:8443/ |
no dedicated login |
| GitLab CE | https://localhost:8444/ |
root / Qv7N4pL9xT2rB6Z8 |
| Open WebUI | https://localhost:8446/ |
root@openwebui.local / RootOpenWebUI!2026 |
| Ollama | https://localhost:8447/ |
gateway basic auth root / RootOllama!2026 |
| Penpot | https://localhost:8448/ |
root@penpot.local / RootPenpot!2026 |
| BookStack | https://localhost:8452/ |
root@bookstack.local / RootBookStack!2026 |
| n8n | https://localhost:8453/ |
owner bootstrap root@n8n.local / RootN8NApp!2026 |
| PostgreSQL host-side | localhost:15432 |
postgres / RootPostgresDev!2026 |
For desktop PostgreSQL clients:
- host:
localhost - port:
15432 - database:
lab - username:
postgres - password:
RootPostgresDev!2026
Use the same layered flow when adding, removing, or moving services. The tag describes the runtime contract, and the emoji keeps the intent visible in notes, issues, and commits.
| Tag | Use when | Runtime contract |
|---|---|---|
ποΈ core |
The service is always on and browser-facing | Add it to infra/docker/compose.yml, publish it through config/gateway/templates/Caddyfile.template, expose it in env/lab.env, and include it in dashboard/runtime config when it should be visible to users. |
π§ ai-llm |
The service belongs to optional AI workflows | Add it to infra/docker/compose.ai-llm.yml, route it through gateway-ai-llm, guard CLI checks behind --with-ai-llm, and add smoke/bootstrap only when that layer is enabled. |
π§° workbench |
The service belongs to optional development environments | Add it to infra/docker/compose.workbench.yml, route browser surfaces through gateway-workbench, and add host TCP preflight/smoke checks only for ports exposed to the desktop. |
π internal |
The service is a backing dependency only | Add Compose service, volumes, and internal networks, but skip Caddy, dashboard cards, and public smoke checks unless another service depends on them. |
π οΈ bootstrap |
The service needs deterministic initial state | Add or update a service under src/services/integrations/, call it from src/services/orchestration/bootstrap.service.ts, and validate required env in src/config/lab-env.schema.ts. |
π©Ί smoke |
The service should be health-checked by doctor --smoke |
Add required env to the smoke schema/types and add an HTTP, login, API, or TCP check in src/services/diagnostics/doctor.service.ts. |
- Add port, URL, image version, credentials, and secrets in
env/lab.env. - Add the service, volumes,
depends_on, and networks ininfra/docker/compose.yml. - Add the HTTPS route in
config/gateway/templates/Caddyfile.template. - Add required template variables in
infra/docker/images/gateway/bootstrap-gateway.sh. - Add runtime payload fields in
config/gateway/templates/runtime/lab-config.json.templatewhen the dashboard needs them. - Update dashboard schema, view-model builders, locale files, and network map nodes if the service should appear in the UI.
- Update host port preflight, smoke checks, tests, README tables, and content templates.
- Add the service in
infra/docker/compose.ai-llm.yml. - Publish browser/API routes through
gateway-ai-llmonly. - Keep CLI behavior behind
--with-ai-llm. - Add bootstrap and smoke checks only when AI LLM env validation passes.
- Update dashboard optional-layer cards so disabled services remain visibly optional instead of pretending to be online.
- Add the service in
infra/docker/compose.workbench.yml. - Route browser workspaces through
gateway-workbench. - Add host port preflight only for ports published to the host, such as desktop database access.
- Add dashboard cards or briefings only for workflows users directly open or inspect.
- Keep the service on an internal network.
- Add named volumes for persistent state.
- Add health checks when other services depend on readiness.
- Do not add public Caddy routes or dashboard cards unless the service becomes user-facing.
| Area | Purpose | Paths |
|---|---|---|
| CLI shell | entrypoint, command registration, terminal rendering | src/cli/, bin/ |
| domain services | runtime orchestration, diagnostics, integrations, archive workflows | src/services/ |
| shared contracts | config schemas, Docker helpers, utilities, shared types | src/config/, src/lib/, src/types/, src/utils/ |
| dashboard | React frontend plus Vite and TS config | apps/atlas-dashboard/ |
| runtime assets | packaged env files and gateway templates | env/, config/gateway/templates/ |
| infrastructure | Compose layers, Dockerfiles, startup scripts | infra/docker/ |
| verification and tooling | unit tests, release helpers, CI support | tests/, scripts/, .github/ |
Key files:
package.jsonenv/lab.envinfra/docker/compose.ymlinfra/docker/compose.ai-llm.ymlinfra/docker/compose.workbench.ymlconfig/gateway/templates/Caddyfile.templateconfig/gateway/templates/runtime/lab-config.json.templateinfra/docker/images/gateway/bootstrap-gateway.sh
Expected behavior. The lab uses a self-signed certificate for localhost.
Certificate download URL:
https://localhost:8443/assets/lab.crt
One of the configured lab ports is occupied or excluded by the system.
atlas-lab status
docker ps --format "table {{.Names}}\t{{.Ports}}\t{{.Status}}"GitLab CE runs its Omnibus reconfiguration on first boot and can take several minutes before https://localhost:8444/ is ready. Check status with:
docker compose --env-file env/lab.env -f infra/docker/compose.yml ps gitlab
docker compose --env-file env/lab.env -f infra/docker/compose.yml logs -f gitlabThis is usually a Docker daemon GPU pass-through issue.
nvidia-smi -L
docker infoWorkbenches are not part of the core layer. Start them explicitly:
npm run dev -- up --with-workbenchAtlas Lab is intended for:
- local use
- technical lab environments
- trusted networks
- development and prototyping
It is not an internet-facing production deployment hardened out of the box.
For stronger hardening:
- move secrets into an external secret-management system
- replace the default certificate with one signed by an internal CA
- tighten network segmentation further
- define recurring backup policies
- audit logs and default credentials
- Docker installation: https://docs.gitlab.com/ee/install/docker/
- Docker configuration: https://docs.gitlab.com/ee/install/docker/configuration.html
- Omnibus NGINX settings: https://docs.gitlab.com/omnibus/settings/nginx.html
- Compose startup order: https://docs.docker.com/compose/how-tos/startup-order/
- Compose networks: https://docs.docker.com/reference/compose-file/networks/
- Docker networking drivers: https://docs.docker.com/engine/network/drivers/
- Caddyfile concepts: https://caddyserver.com/docs/caddyfile
- Reverse proxy: https://caddyserver.com/docs/caddyfile/directives/reverse_proxy
- Self-hosted user management: https://docs.n8n.io/hosting/configuration/user-management-self-hosted/
- Docker install: https://docs.n8n.io/hosting/installation/docker/
- Official documentation: https://www.bookstackapp.com/docs/
- LinuxServer image: https://docs.linuxserver.io/images/docker-bookstack/
- Environment configuration: https://docs.openwebui.com/getting-started/env-configuration/
- FAQ: https://docs.ollama.com/faq
- API reference: https://github.com/ollama/ollama/blob/main/docs/api.md
- Official docs: https://coder.com/docs/code-server/latest
This project is distributed under the MIT license.