How to use multiple workshops in a project¶
A project may require different toolchains for different components,
such as a Go backend and a Node.js frontend.
Instead of putting everything into a single workshop definition,
you can define multiple workshops in the same project directory.
Each workshop is an independent environment
with its own base image, SDKs, and actions;
at the same time, the workshops share a single project directory
mounted at /project/.
Set up definitions¶
When a project uses multiple workshops,
store their definitions in the .workshop/ subdirectory
instead of a single workshop.yaml in the project root.
Each file must be named after its workshop,
so the name field matches the file name
(without the .yaml extension).
Here is a project layout with two workshop definitions and a shared in-project SDK:
my-project/
├── .workshop/
│ ├── frontend.yaml
│ ├── backend.yaml
│ └── common-tools/
│ └── sdk.yaml
├── web/
└── api/
The frontend workshop uses the node SDK
for the browser-facing part of the project:
name: frontend
base: ubuntu@24.04
sdks:
- name: node
channel: 24
actions:
build: |
npm run build
The backend workshop uses the go SDK
for the server-side code:
name: backend
base: ubuntu@22.04
sdks:
- name: go
channel: 1.26
actions:
test: |
go test ./...
Each workshop can use a different base image, a different set of SDKs, and its own actions, all while sharing the project directory.
What’s more, you can share in-project SDKs across workshops, as described in a section below.
Note
You cannot mix a root-level workshop.yaml
with files in .workshop/.
If Workshop finds both,
it reports an error.
Launch and manage workshops¶
Launch both workshops at once:
$ workshop launch frontend backend
When a project has multiple workshops, the workshop name is required in every command; you cannot omit it as you would with a single-workshop project.
Check the status of both workshops:
$ workshop list
WORKSHOP STATUS NOTES
frontend Ready -
backend Ready -
Run an action in a specific workshop:
$ workshop run frontend -- build
$ workshop run backend -- test
Shell into one of the workshops:
$ workshop shell backend
Execute a one-off command:
$ workshop exec frontend -- node --version
Stop and start workshops independently:
$ workshop stop frontend
$ workshop start frontend
Or stop both at once:
$ workshop stop frontend backend
To see the status of workshops in the current project, use the workshop list command without arguments:
$ workshop list
WORKSHOP STATUS NOTES
frontend Ready -
backend Ready -
To see the status of workshops across all projects on the system,
use the --global flag:
$ workshop list --global
PROJECT WORKSHOP STATUS NOTES
/home/user/my-project frontend Ready -
/home/user/my-project backend Ready -
/home/user/other-project dev Ready -
When you no longer need the workshops, remove them:
$ workshop remove frontend backend
Cross-workshop networking¶
You cannot connect a plug in one workshop to a slot in another; workshop connect rejects such attempts. However, all workshops on the same machine share a common host, and the tunnel interface can bridge through it.
The idea is to compose two independent tunnels: one that exposes a service from the backend workshop to the host, and another that lets the frontend workshop reach that host port. This is different from a regular intraworkshop connection, where a single tunnel links a plug to a slot inside the same workshop. Here, the host sits in the middle, and each workshop configures its own half of the bridge.
The backend workshop exposes its API on the host
by pairing a system plug with a regular SDK slot:
name: backend
base: ubuntu@22.04
sdks:
- name: go
channel: 1.26
slots:
api:
interface: tunnel
endpoint: localhost:8080 # service inside the workshop
- name: system
plugs:
api:
interface: tunnel
endpoint: localhost:8080 # port on the host
The frontend workshop reaches the host port
by pairing a regular SDK plug with a system slot:
name: frontend
base: ubuntu@24.04
sdks:
- name: node
channel: 24
plugs:
api:
interface: tunnel
endpoint: localhost:8080 # where the client connects
- name: system
slots:
api:
interface: tunnel
endpoint: localhost:8080 # host-side port (bridged from backend)
Launch both workshops.
The backend tunnel auto-connects
because its plug is on the system SDK with a matching name,
but the frontend tunnel requires a manual step:
$ workshop launch frontend backend
$ workshop connect frontend/node:api
Verify the connection:
$ workshop connections frontend
INTERFACE PLUG SLOT NOTES
tunnel frontend/node:api frontend/system:api manual
After this, any service listening on port 8080 inside the backend workshop
is reachable at localhost:8080 from within the frontend workshop.
Note
The host port must be free before launching the backend workshop, or the tunnel will fail to activate. If you need several cross-workshop tunnels, use a different port for each. See How to forward ports with tunneling for tunnel basics and troubleshooting.
See also¶
Explanation:
How-to guides:
Reference: