Getting Started
Tom Labs can run in two modes: on an Actual VPS (TomCloudLab) or as a local Docker VPS (local_dev_lab).
Installs Docker + Traefik + WireGuard + Code Server + PostgreSQL. Automatically detects your OS and provisions a complete secure lab environment in seconds.
Manual Server Infrastructure
Tom Labs Orchestration Layer
No manual configs. No port forwarding. No hassle.
Choose Your Migration Path
Tom Labs supports two deployment models:
Option 1: For a public server with a static IP.
Option 2: For local development or behind a firewall using Cloudflare Zero Trust.
Run interactively on a fresh Ubuntu 24.04 server:
curl -fsSL https://cloud.tomweb.in/install.sh | sudo bash
- Select [1] VPS Bare-Metal Server Setup
- Enter your public domains when prompted
- The script installs everything natively!
Run locally on your Mac/Linux/Windows machine:
curl -fsSL https://cloud.tomweb.in/install.sh | sudo bash
- Select [2] Docker Container Local Setup
- The script generates your configs and starts the orchestration container!
Step 2: Required Configuration & Build
Before you can use Tom Labs, you must configure your environment and build the lab images. Follow the instructions for your chosen setup option:
ℹ️ Option 1 Users: Configure Environment
# 1. Edit configuration files with your API keys
nano /var/www/env.json
nano /var/www/labs/session.json
# 2. Build the Essentials Lab natively on the host
labsctl build essentials:lab
⚠️ Option 2 Users: Configure & Enter Container
# 1. Navigate to the default installation directory
cd ~/tom-cloud-labs
# 2. Edit configuration files with your API keys
nano env.json
nano session.json
# 3. Add your Cloudflare TUNNEL_TOKEN
nano docker-compose.yml
# 4. Apply your changes
docker compose down && docker compose up -d
# 5. Enter the orchestration container to build labs
docker exec -it TomCloudLab bash
labsctl build essentials:lab
Architecture Deep Dive: The Installation Flow
How install.sh securely fetches the repository and instantly hands off to Migrate.sh for an interactive setup experience.
Downloads the latest repo from GitHub"] B --> C["Migrate.sh
Instantly takes over & interactively prompts you"] C --> D["Option 1: VPS
Configures bare-metal natively"] C --> E["Option 2: Docker
Generates container orchestration"] D --> F["Runs directly on host"] E --> G["Runs inside container"] classDef default fill:#f9f9f9,stroke:#e5e7eb,stroke-width:1px,color:#111827,rx:8px,ry:8px,padding:16px; classDef dark fill:#1c1917,stroke:#44403c,stroke-width:2px,color:#f8fafc,rx:8px,ry:8px; classDef option1 fill:#ecfdf5,stroke:#a7f3d0,stroke-width:2px,color:#065f46; classDef option2 fill:#fff1f2,stroke:#fecdd3,stroke-width:2px,color:#9f1239; class B dark; class D option1; class E option2;
The Two Layers
install.sh |
Migrate.sh |
|
|---|---|---|
| Size | ~150 lines | ~1800 lines |
| Job | Check root/OS, fetch a pinned copy of the repo, hand off | Everything else — the actual provisioning |
| Changes how often | Rarely | Whenever a feature is added |
| Lives where | Hosted at the curl URL | Inside the repo, fetched fresh each run |
install.sh never installs Apache, MySQL, MongoDB, Docker, etc. itself. It only ensures git, curl, openssl exist, clones a pinned version of the repo, then execs Migrate.sh — at which point install.sh is gone and you're inside the real installer.
Option 1 (VPS) vs Option 2 (Docker)
This separation already exists in Migrate.sh. The Docker-only block is gated by a single condition. Everything inside it — generating Dockerfile, docker-compose.yml, entrypoint.sh, init-services.sh, config.json, then running docker compose up -d --build — only runs when that condition is true, and the block exits when done.
The VPS section never references any of those four files. It installs Apache, PHP, MySQL, MongoDB, PostgreSQL, Redis, RabbitMQ, WireGuard, and Traefik directly on whatever machine you ran it on, via apt-get and systemd.
| Option 1 — VPS | Option 2 — Docker | |
|---|---|---|
| Selected by | --mode=vps (or menu choice 1) |
--mode=docker (or menu choice 2) |
| docker-compose.yml | Never generated | Generated, then run via docker compose up |
| entrypoint.sh | Never generated | Generated, baked into the image |
| Core Services | Installed straight onto this machine | Installed only inside the container — host stays untouched |
| End result runs on | The machine you ran it on | A container managed by docker compose |
Re-run Safety & Practical Guidance
- It's safe to rerun
install.shas many times as needed after a failure — same command, same flags. WireGuard keys and DB users are generated defensively (e.g.,CREATE USER IF NOT EXISTS). - Want a permanently fixed password? Pass
DB_PASS=...andMQ_PASS=...explicitly instead of letting it auto-generate. - Check
/var/log/tom-cloud-labs-install.log(frominstall.sh) and/tmp/migrate_cmd.log(printed automatically byMigrate.shon failure) before retrying — most failures are transient network blips during apt/git, and a straight retry resolves them. install.shreuses credentials saved in/root/tom-cloud-labs-credentials.txtfrom a previous run unless explicitly overridden, preventing quietly rotating passwords on partial failures.
Verify Your Database (MongoDB Compass)
Tom Labs bundles MongoDB 8.0 securely. You can verify your connection and inspect user/lab records instantly using MongoDB Compass.
# For local setups, connect using this URI:
mongodb://admin:Tombootroot@127.0.0.1:27017/tom_labs_db?authSource=admin
# 1. Open MongoDB Compass
# 2. Paste the URI above
# 3. View your 'users' and 'deployed_labs' collections!