Multi-workshop patterns¶
One workshop per project is the default, but real work often pulls in more than one. A monorepo holds a Go backend and a Node frontend, each with its own toolchain. A coding agent needs to run over a branch without seeing sibling branches or unrelated host directories. Two long builds must progress without blocking your editing. A regression has to be confirmed against a new base image without disturbing the working setup.
Workshop supports these cases through two patterns that combine the same primitives in different ways: several workshops sharing one project directory, or several project directories each hosting one or more workshops of their own.
Two patterns¶
The two patterns differ in where the project boundary falls: within a single project directory, or across several directories. Both rely on the same underlying mechanics; they’re distinguished by intent and topology, not by special CLI flags.
One project, multiple workshops¶
Here, several workshops live in a single project directory
and share the project files mounted at /project/.
Their definitions sit in the .workshop/ subdirectory,
each in its own file named after the workshop:
my-project/
├── .workshop/
│ ├── frontend.yaml
│ ├── backend.yaml
│ └── common-tools/
│ └── sdk.yaml
├── web/
└── api/
Each workshop has its own base image,
its own SDK list,
and its own actions,
but they all see the same project files.
In-project SDKs,
stored as subdirectories of .workshop/,
can be referenced by any workshop in the project
and provide a clean way to share custom tooling.
The workshops are isolated as LXD containers: each has its own filesystem layers, its own running processes, and its own snapshot chain. What’s shared is the project content on the host, not the runtime. Direct interface connections between two workshops are rejected by workshop connect; if your workshops need to talk to each other, they may do so by bridging through the host with two independent tunnel connections, as described in How to use multiple workshops in a project.
Pick this pattern when several components of one project need different runtimes but the same source tree.
Multiple projects, one workshop each¶
Here, you work on multiple related project directories.
Each project directory has its own
workshop.yaml
(or its own .workshop/ subdirectory)
and its own .workshop.lock.
Workshops in different projects are fully independent:
the project files they mount at /project/ differ,
the containers are separate,
and the workshop definitions can diverge freely.
In day-to-day work this pattern is most often realized
with git worktree,
which gives you several working trees of the same repository
in sibling directories.
Each worktree is a distinct project from Workshop’s point of view,
gets its own project ID,
and can run a workshop that’s named identically to its sibling
without any collision.
The workshop list command,
invoked with --global,
shows the workshops across the projects currently tracked by Workshop,
including their project paths.
How to use workshops with Git walks through the mechanics.
Pick this pattern when the parts have to stay separated: different branches, different snapshots of the codebase, different base images for the same code, or different agents whose blast radius should not overlap.
At a glance¶
One directory, multiple workshops |
Multiple directories, one workshop each |
|
|---|---|---|
Definition location |
|
|
Mounted at |
The same directory in every workshop |
A different directory in each workshop |
Project files |
Shared across workshops |
Isolated per directory |
Containers and snapshots |
One per workshop |
One per workshop |
Cross-workshop networking |
Bridge through the host with two tunnels |
Same; each workshop reaches the others through the host like any other service |
Branch isolation |
All workshops see whatever branch the project is on |
Each directory pins its workshops to its branch |
Typical trigger |
Polyglot components of one codebase |
Parallel work on different branches or snapshots |
Scenarios¶
The patterns above answer most multiworkshop cases. The list below names the recurring ones, points to the pattern that fits, and links to the how-to that covers the mechanics.
Polyglot project components. A monorepo with parts in different languages or runtimes, for example a Go backend with a Node frontend, or Python data preparation alongside CUDA training and a Rust serving layer. Each component gets its own workshop in the same project; the project files are shared, the toolchains are not.
Shared internal tooling across components. When several workshops in one project rely on the same linter, formatter, or generator, package it as an in-project SDK rather than duplicating the setup in each workshop definition.
Parallel work on independent branches. Two unrelated features, a feature and a hotfix, or a feature and a pull-request review. Each branch is checked out in its own worktree, and each worktree runs its own workshop. Editing, building, and any agent activity in one worktree has no effect on the others.
A/B comparison of bases or SDK channels. Two worktrees hold the same code but their workshop definitions differ in
baseor in SDKchannel, letting you confirm a dependency bump, reproduce a version-specific bug, or evaluate a base image upgrade side by side with the working setup.Confinement for code-running agents. A coding agent in a worktree or a subdirectory sees only that slice of the repository; sibling worktrees and unrelated host directories stay out of reach. The workshop container adds a second isolation boundary beneath the worktree boundary, so even an agent invoked with relaxed permission flags cannot reach the host filesystem outside of what the workshop mounts.
Long-running task offload. A build, training run, migration, or large refactor keeps progressing in one workshop while you continue editing in another. Use one project with multiple workshops if the task should see your current edits, or separate projects via worktrees if it should be pinned to a specific commit.
Local reproduction of CI failures. Check out the failing commit in a dedicated worktree and define a workshop with the base image CI uses. Your everyday workshop stays on the working setup and continues to run.
Pattern combinations¶
The two patterns combine.
A monorepo with .workshop/frontend.yaml
and .workshop/backend.yaml
can also be checked out in two worktrees,
each running both workshops.
This is useful when reviewing a pull request
on the monorepo’s structure
while continuing development on the main branch:
the review worktree has its own frontend and backend workshops,
isolated from yours,
and workshop list invoked with --global
shows all four at once.
See also¶
Explanation:
How-to guides:
Reference: