Projects

Publish project images

Publish project images with metadata, public slugs, discovery actions, app launchers, and CLI automation.

What RootFS publishing is for

A RootFS image packages the Linux software environment for a project. Publishing a RootFS catalog entry makes that environment discoverable and reusable by other projects, courses, workshops, and agents.

Use RootFS publishing when you want to share all of these together:

The catalog metadata is the source of truth. Portable JSON export/import is for moving metadata between projects or authoring it with an agent; it is not a second live manifest inside the image.

Publish from a project

  1. Open the project that has the software installed and tested.
  2. Open Settings.
  3. Go to Environment.
  4. In the Image card, choose Details.
  5. Under Publish current image, choose Publish. To update an existing entry's metadata, use Manage catalog entry instead.
  6. Fill in metadata, theme, discovery actions, and visibility.
  7. Review the Publish Current Image dialog and choose Publish Image, or choose Update Catalog Entry when managing existing metadata.

Publishing the current project RootFS snapshots the visible software environment. It does not publish /home/user, /root, or /tmp. Files that users should copy or inspect should live in a stable non-HOME path such as /opt/<name>/examples.

Slugs and public landing pages

Every catalog entry gets a short public slug. The share URL is:

/rootfs/<slug>

The image-id fallback is:

/rootfs/id/<image_id>

Use the slug field in RootFS catalog management if you want a human-readable link such as /rootfs/pluto-julia-smoke. Leave it blank when you are fine with an automatically generated slug. Slugs are globally unique, URL-safe, and can contain lowercase letters, numbers, and hyphens.

The landing page should render from catalog metadata alone. Users can review the image, create a project using the image, and then see the same RootFS actions in the new project.

Discovery actions

Discovery actions explain what users can do after selecting a RootFS image. They appear in the public landing page and in the project RootFS panel.

Supported action types are:

Prefer actions that do not depend on files already in HOME. If an app needs example files, put those examples in the RootFS and add a copy action for users who want editable copies.

App launchers

An app action stores a normalized app spec in the RootFS catalog metadata. The recommended workflow is:

  1. Configure the app in the publishing project.
  2. Test that it starts and opens correctly.
  3. Add that configured app to the RootFS discovery actions.
  4. Publish or update the catalog entry.

When a user launches the action in another project, CoCalc creates or updates the app spec in that project, starts it, waits for readiness, and opens it.

Do not store only a template id in RootFS metadata. Store the full app spec so the RootFS catalog entry is self-contained and can be restored by humans, agents, and CLI automation.

CLI and agent workflow

Export a config JSON from the RootFS management UI when you want an editable, portable copy of the metadata. Agents can also author the same shape directly.

Save metadata for an existing runtime image:

cocalc rootfs save \
  --image cocalc.local/rootfs/<digest> \
  --config-file rootfs-config.json \
  --slug my-rootfs

Publish the current project RootFS:

cocalc rootfs publish \
  --project <project_id> \
  --config-file rootfs-config.json \
  --slug my-rootfs \
  --switch-project \
  --wait

CLI flags override values in the config file. This is useful when an agent starts with a reusable config and then sets the label, slug, visibility, or version for a specific publication.

RootFS recipes

RootFS recipes are a build-time authoring layer for recreating images across CoCalc sites. They are inspired by devcontainer features and GitHub Actions: a recipe has steps, each step can use a local module such as cocalc/apt, cocalc/julia, or cocalc/pluto, and modules can contribute RootFS catalog metadata such as tags, theme, content actions, and app launchers. The CLI supports YAML and JSON recipe files; YAML is the recommended authoring format.

Recipes are not the live source of truth for a published RootFS entry. The published catalog metadata remains authoritative. Recipes are for authors, admins, and agents who need to rebuild or adapt an image.

Explain a recipe without running it. You can pass a file path or the name of a bundled example recipe:

cocalc rootfs recipe ls
cocalc rootfs recipe explain src/packages/rootfs-recipes/examples/julia-pluto.yaml
cocalc rootfs recipe explain julia-pluto

Recipe modules such as cocalc/jupyter-python are composable steps, not full published builds. The CLI can still explain a module by treating it as a one-step recipe:

cocalc rootfs recipe explain cocalc/jupyter-python
cocalc rootfs recipe explain jupyter-python

Run a recipe in a clean builder project:

cocalc rootfs recipe run julia-pluto

Recipe steps stream command output while they run. Each step defaults to a 900-second command timeout; use --step-timeout <seconds> for larger builds such as SageMath, CUDA stacks, or source builds:

cocalc rootfs recipe run cocalc-base --step-timeout 1800

Run and publish the result:

cocalc rootfs recipe run julia-pluto \
  --publish \
  --switch-project \
  --wait

Pass --project <project_id> to run in an existing project instead of creating a clean builder project. Pass --config-out rootfs-config.json to save the generated portable RootFS config JSON for inspection or reuse.

From inside a running CoCalc project, pass --here to apply a recipe directly to that project using local subprocesses instead of remote project-host exec:

cocalc rootfs recipe run cocalc/r --here

This is useful when a recipe is acting as a reusable software installer rather than as a clean image build. The command writes portable RootFS publish metadata into /home/user/.cocalc/rootfs-recipes/*.rootfs-config.json by default; the Runtime Image publish dialog can import that JSON directly from a project file.

The repository also includes a minimal CoCalc site base recipe with basic shell tools, LaTeX, Python, JupyterLab, scientific Python packages, uv, SFTP support, and both Python and bash Jupyter kernels:

cocalc rootfs recipe explain cocalc-base

GPU machine learning recipes are also included. They build on the same Jupyter/uv base and install NVIDIA GPU-enabled Python packages:

cocalc rootfs recipe explain ml-pytorch-gpu
cocalc rootfs recipe explain ml-tensorflow-gpu

The PyTorch recipe uses the official CUDA wheel index, defaulting to CUDA 12.8. The TensorFlow recipe installs tensorflow[and-cuda] and applies the recommended virtual-environment symlink fix for NVIDIA libraries. Both recipes can be verified on a non-GPU builder by checking that the GPU-enabled packages are installed; set the module input require_gpu: true when the builder project must also prove that an NVIDIA GPU is visible.

Test checklist

After publishing, test the full user path:

  1. Open the public landing page at /rootfs/<slug>.
  2. Create a project from that page.
  3. Confirm the new project records the expected RootFS image id.
  4. Open the project RootFS panel.
  5. Test browse, open, copy, external link, and app actions.
  6. If the RootFS includes app actions, verify the app reaches ready state and opens through the project proxy URL.

For app-heavy images, also test from a fresh project so stale app specs, cached processes, and files in HOME do not hide missing RootFS dependencies.