Ubuntu Workshop: Secure, Reproducible Dev Environments Built for the AI Era

Canonical's Workshop tool promises to eliminate the "works on my machine" problem for good — by wrapping complex, error-prone dev environments into fast, composable, agent-ready containers defined by a single YAML file.

Ubuntu Workshop: Secure, Reproducible Dev Environments Built for the AI Era
Photo by Stem List / Unsplash

What Is Ubuntu Workshop?

Canonical has quietly shipped one of the most interesting developer tools to come out of the Ubuntu ecosystem in recent years: Workshop. Still in active development, Workshop is a tool for creating secure, fast, and composable development environments — containers that are fully defined by a YAML file and can be spun up, torn down, and reproduced with perfect consistency.

If you've ever lost a day to broken Python environments, mismatched library versions, or the infamous "it works on my machine" problem, Workshop was designed with you in mind.

The Core Idea: Environments as Code

At the heart of Workshop is a deceptively simple concept: your entire development environment — languages, libraries, tools, runtimes — is described in a single YAML definition file checked into your repository alongside your code. When you (or a colleague, or a CI pipeline) runs workshop launch, that definition is materialised into a running container. Every time. Without surprises.

Each such environment is called a workshop (lowercase). Workshops are currently hosted by LXD, Canonical's system container and VM manager, giving them strong isolation properties without the overhead of full virtualisation. Your project directory is automatically mounted inside the container, so your code, data, and models are immediately accessible.

The lifecycle of a workshop is well-defined too: it moves between Off, Ready, Stopped, and Pending states — making it straightforward to pause, resume, or update an environment without losing work.

SDKs: Composable Units of Functionality

The modular magic of Workshop comes from SDKs — not software development kits in the traditional sense, but independent, connectable units of environment functionality. Think of an SDK as a reusable building block: one SDK might provide a specific version of Python with all the right ML libraries, another might bring in CUDA support, and a third might set up a ROS (Robot Operating System) toolchain.

SDKs can be published to and consumed from the SDK Store, meaning your team (or the broader community) can share and reuse environment definitions instead of copying Dockerfiles and hoping they still work six months later. Workshop explicitly positions itself as a better alternative to Dockerfiles for development environments — with proper dependency management, composability, and reproducibility baked in.

Interfaces: Connecting Your Workshop to the Outside World

One of Workshop's more powerful features is its interfaces system — a set of well-defined connection points between a workshop container and the host machine or external services. Currently available interfaces include:

  • Desktop — run GUI applications inside the workshop
  • GPU — pass through graphics hardware for AI/ML workloads
  • Camera — access webcams and video devices (useful for robotics and CV work)
  • SSH — connect via standard SSH
  • Tunnel — expose internal services
  • Mount — mount additional directories into the container

Port forwarding is also supported, making it easy to run web servers, Jupyter notebooks, or other services inside a workshop and reach them from the host browser.

IDE Integration and Workflows

Workshop isn't meant to be used in isolation from your existing tools. The official documentation covers how to:

  • Connect VS Code to a running workshop via Remote SSH
  • Run JetBrains Gateway for full IDE access
  • Launch JupyterLab directly in your browser from inside a workshop
  • Manage Python environments within a workshop
  • Run GitHub Actions locally using your workshop as the execution environment
  • Run workshops inside GitHub Actions for reproducible CI

This last point is particularly compelling: the same YAML definition that describes your local dev environment can be the definition that runs in CI. No more "passes locally, fails in CI" mysteries.

Built for AI Agents - And That's Not Marketing Fluff

Workshop ships with native support for agentic workflows. It publishes LLM-readable documentation and includes dedicated agentic skills for both operating workshops and scaffolding SDKs. This means an AI coding agent can launch, interact with, and manage a Workshop environment as part of an automated development pipeline — a capability that's increasingly relevant as agentic engineering becomes mainstream.

The official docs are explicit about the target domains: agentic engineering, AI/ML, robotics, IoT, and EdTech — all fields characterised by complex, multi-component project layouts that currently cause enormous environment management pain.

Real-World Example: Claude Code Inside a Workshop

One of the most compelling demonstrations of Workshop's SDK model in practice is the official claude-code-sdk, published by Canonical. It packages Anthropic's Claude Code CLI — the agentic coding tool — as a Workshop SDK, so you can drop a fully sandboxed AI coding assistant into any project with just a few lines of YAML.

The workshop definition is minimal. Create a workshop.yaml in your project directory:

# workshop.yaml
name: claude-code
base: [email protected]
sdks:
  - name: claude-code
    channel: latest/stable

actions:
  claude-yolo: claude --dangerously-skip-permissions "$@"
  claude-yolo-prompt: claude --dangerously-skip-permissions -p "$@"

Then launch the workshop and open a shell into it:

workshop launch
workshop shell
claude

That drops you into an interactive Claude Code session running inside the workshop container. Because the agent is sandboxed by Workshop's isolation layer, the --dangerously-skip-permissions flag is actually safe to use here — Claude can read and write files freely within the container without any risk of touching your host system.

For non-interactive, scripted use (e.g. in CI), the claude-yolo-prompt action lets you pass a prompt directly:

workshop run claude-yolo-prompt "Refactor the auth module to use async/await"

Credentials are persisted between workshop updates, so you authenticate once and Workshop handles the rest across relaunches and refreshes. The SDK also configures PATH automatically and injects a system prompt hint about the workshop environment so Claude Code understands its context.

This is a concrete example of what Workshop's composability makes possible: a reusable, shareable, reproducible AI coding environment that any team member can spin up with a single command — no setup docs, no "which version of node does Claude Code need?", no leftover state.

Getting Started

Workshop requires LXD as its container backend. You need to install it first, pinned to the 6/stable channel. Then install Workshop itself with classic confinement:

# Step 1: Install LXD (required backend)
sudo snap install --channel=6/stable lxd

# Step 2: Install Workshop
sudo snap install --classic workshop

Once both are installed, navigate to your project directory and launch your first workshop:

cd your-project/
workshop launch

The official tutorial at documentation.ubuntu.com/canonical-workshop then walks you through the full workflow — working with interfaces, sketching SDKs inline, and crafting full publishable SDKs. The project is open source on GitHub at github.com/canonical/workshop.

The Bigger Picture

Workshop is Canonical's answer to a problem that has plagued Linux developers for decades: environment reproducibility. Where tools like Docker brought containers to production workloads, Workshop brings them to the development workflow itself — with tighter OS integration, a proper composability model via SDKs, and first-class support for the kinds of complex, heterogeneous toolchains that AI, robotics, and systems developers deal with every day.


References: Ubuntu Workshop Documentation · GitHub: canonical/workshop · GitHub: canonical/claude-code-sdk