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:
- a well-defined runtime image,
- metadata that explains when to use it,
- a public landing page that can create a project from it,
- optional discovery actions such as browse, open, copy, external links, and app launchers.
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
- Open the project that has the software installed and tested.
- Open Settings.
- Go to Environment.
- In the Image card, choose Details.
- Under Publish current image, choose Publish. To update an existing entry's metadata, use Manage catalog entry instead.
- Fill in metadata, theme, discovery actions, and visibility.
- 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:
- External link: link to documentation or project websites.
- Browse: open a directory inside the RootFS.
- Open: open a specific file inside the RootFS.
- Copy to HOME: copy examples or starter files into
/home/userso edits persist if the runtime image changes. - Project app: restore a managed project app spec and launch it.
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:
- Configure the app in the publishing project.
- Test that it starts and opens correctly.
- Add that configured app to the RootFS discovery actions.
- 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:
- Open the public landing page at
/rootfs/<slug>. - Create a project from that page.
- Confirm the new project records the expected RootFS image id.
- Open the project RootFS panel.
- Test browse, open, copy, external link, and app actions.
- 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.