Skip to content

Templates & shared mounts

A template defines:

  • The container image to use.
  • Which launchers (apps) are available and how to start them.
  • Default resource suggestions (CPU, memory).
  • Optional per-template environment variables.
TypeOwnerWho sees it
Globalroot (admin)All users
User-ownedRegular userThat user only

The admin manages global templates from /admin/templates. For regular users, Templates opens on My templates and also contains Template gallery, My images, and My build history. The former separate user Images page and navigation item have been removed.

Template gallery contains every shipped template, including templates the administrator has not enabled or built yet. A user can create a workspace from a ready template or choose Clone & customize to make a private copy. Dockerfile-backed templates copy an editable build context into the user’s work directory; registry-backed templates keep their image reference.

My images first lists image name, size, creation date, and Not checked for active containers. Choosing Manage loads the more expensive active-container, reclaim, sharing, delete, and untracked-container checks. Make template remains available without that scan. The page also renders My templates before reusable global presets finish loading, so a busy Podman inventory does not block the user’s own work.

Admin Templates page - template list with enabled/disabled status, New Template form

  1. Open /admin/templatesNew template.
  2. Enter a name, a container image reference (e.g. docker.io/pytorch/pytorch:2.3.0-cuda12.1-cudnn8-runtime), and resource defaults. Image references must include an explicit registry host such as docker.io, ghcr.io, quay.io, or nvcr.io; unqualified names such as python:3.11 are rejected because the host’s Podman search-registry policy would make the source ambiguous.
  3. Add app launchers. Prefer Import launcher to copy a definition from the reusable catalog; use a manual launcher entry only for one-off apps. Launcher commands that start an app must bind ${HOST_PORT} and usually pass ${AUTH_TOKEN} or ${BASE_PATH} to the app.
  4. Save. Enabled templates appear in all users’ workspace creation dialogs immediately.

Built-in templates continue receiving shipped updates when you only enable or disable them. Editing their definition pins it to the administrator’s version instead; Reset to shipped defaults restores the bundled definition without changing enabled status or accepted terms. An upgrade never turns on a built-in template you deliberately left disabled.

Rebuild the built-in RStudio Server image after this release. The rebuilt image opens through the workspace gateway and keeps the RStudio session in the workspace’s persistent home. An RStudio launcher that an administrator previously customized may still need strip path prefix enabled.

Rebuild the R ML JupyterLab image to receive its documented machine-learning packages and one shared Python interpreter for JupyterLab and R’s Python bridge. It is CPU-first by default; select a GPU only when the work needs one. The template does not include R deep-learning packages such as torch or keras; use its README for the one-time installation guidance.

To update an existing template’s image (after pulling a new version):

  1. Open the template in the admin UI.
  2. Edit the Image field.
  3. Save. New workspaces created from this template will use the new image; existing running workspaces are unaffected.

Root admins manage reusable launcher definitions from /admin/launchers.

Each catalog launcher defines the app name, label, container port, protocol, command template, readiness path, probe command, install hint, optional start-time fields, and whether LabPod strips the proxy prefix. When you import a catalog launcher into a template, LabPod copies the definition into that template. Later catalog edits do not rewrite existing templates.

Use the catalog for common apps such as JupyterLab, TensorBoard, MLflow, code-server, RStudio, MATLAB, and ComfyUI. Use manual template ports only when the app is specific to one template.

LabPod includes an opt-in composite template for images that bundle JupyterLab, code-server, TensorBoard, MLflow, Aim, and a web terminal in one container.

The PyTorch Demo template is a ready-made composite of this kind: it pulls the public ghcr.io/labpod/pytorch-demo image (default cpu, GPU tags cu121/cu126/cu129), so you can enable it without building anything. Its demo notebooks are seeded on first start.

The CUDA Composite Workspace is the build-your-own option: build or pull a composite image for your site, then edit that disabled template to point to your tag and enable it.

Users can export their own templates as a bundle (TAR with manifest + image digest references) and share them with other deployments. Admins can export global templates the same way.

From the template detail page → Export. To import from the UI: TemplatesImport → upload a bundle or provide a bundle URL → preview → commit.

Admins can also import a host-local bundle from the CLI:

Terminal window
sudo labpod admin template import ./template.tar --global
sudo labpod admin template import ./template.tar --owner alice
Terminal window
# Run these as root
labpod admin template import ./template.tar --global
labpod admin template import ./template.tar --owner alice

CLI imports land disabled for review. Bundles that contain a Dockerfile must be imported from the web UI, because LabPod needs the image build service to build the imported image.

A shared mount is a host directory that LabPod bind-mounts into every workspace. Typically used for large read-only datasets or a shared writable directory.

From /admin/shared-mountsNew mount:

  • Name - the label shown in the UI (e.g. datasets).
  • Host path - the host directory to mount (e.g. /data/datasets).
  • Container path - where it appears inside workspaces (e.g. /data).
  • Read-only - checked by default; uncheck for writable sharing.

The mount applies to new workspaces. Existing running workspaces are not affected until they are stopped and restarted.

By default the admin can configure any host path. To restrict which roots are allowed:

Terminal window
# In /etc/labpod/labpod.env:
LABPOD_SHARED_MOUNT_ROOTS=/data,/datasets

This prevents accidental mounts of sensitive system directories.

The install script creates /shared as a root-owned directory. LabPod automatically creates /shared/<username> for each user (readable by other users). This enables lightweight cross-user data sharing: user Alice can read /shared/bob/ from inside her workspace.

Large CUDA images are copied into each user’s rootless image storage. When an administrator pulls or builds a global-template image, LabPod keeps a root-owned master copy and a user choosing Pull receives a private copy from that master without downloading it again. A workspace always runs from its owner’s image store; it never runs directly from the administrator’s store.

If the administrator has not built a Dockerfile-backed template yet, researchers must ask the administrator to prepare it. Freeing a private copy releases disk now, but that user needs Pull again before the next workspace start.

Root admins can also manage images from /admin/images: pull shared images, watch pull/build events, inspect shared and per-user image stores, prune dangling layers, delete specific tagged images, and maintain the registry terms allowlist used by compliance checks. The /admin/compliance page shows templates and registries that require EULA or terms acceptance.

Use StorageDelete images when a specific image tag should be removed from the shared store or a user’s rootless store. This is stronger than Prune, which only removes dangling untagged layers. LabPod blocks deletion while active containers use the image and warns if stopped workspaces still reference it, because those workspaces may fail on their next start until the image is pulled or rebuilt again.