documentation

.cycleswap/

cycle project init creates a .cycleswap/ directory at the root of your project. It holds the configuration files read during upload and used inside the container.

Manifest

manifest.toml is the TOML file that configures your project.

# Example .cycleswap/manifest.toml

[main]
name = "my-experiment"
volumes = ["training-data", "validation-data"]
build_files = ["pyproject.toml"]

[ubuntu]
version = "24.04"

[job]
cuda = "13.0"
env_vars = { MAX_EPOCHS = "1000", LEARNING_RATE = "3e-4" }
email_on_success = true
email_on_failure = true
artifact_upload_order = "LIFO"

[main]

FieldTypeRequiredDescription
namestringyesProject name. Must be unique within your organization.
volumesarray of stringsnoVolume names to link to uploaded versions. Defaults to [].
build_filesarray of stringsnoFiles (relative to the project root) whose content determines whether the build image is rebuilt. When any of these files change between uploads, the build image is rebuilt. They are also copied into the build context so the build script can reference them (e.g. pyproject.toml for dependency installation). Defaults to [].

Volumes listed here are mounted inside the container at /volumes/<name> when a job runs. See Volumes.

Image section

Exactly one image section must be present. It determines the base container environment.

[ubuntu]

FieldTypeRequiredDescription
versionstringyesUbuntu version. One of: "22.04", "24.04", "25.04", "25.10", "26.04"

[job]

Controls how the job runs.

FieldTypeRequiredDescription
cudastringnoMinimum CUDA version the host machine must have, e.g. "13.0" or "12.6". This does not install a driver inside the container; it tells the scheduler to assign the job only to machines whose GPU driver supports this CUDA version or newer. Omit this field if the job does not need a GPU.
env_varstablenoEnvironment variables to set inside the container. Defaults to {}.
email_on_successboolyesSend an email when the job completes successfully.
email_on_failureboolyesSend an email when the job fails.
artifact_upload_orderstringnoOrder in which artifact files upload to storage. "FIFO" (default) uploads files in the order they were written. "LIFO" uploads the most recent file first. Set to "LIFO" when saving periodic checkpoints so the latest checkpoint is always available first. See Job Outputs.

Built-in environment variables

These variables are set in every container automatically, on top of anything you define in env_vars:

VariableValueDescription
INSIDE_CYCLESWAP_CONTAINER1Detect whether your code is running inside a container or locally.

Run script

run.sh is the container's entry point. When a job starts, the container runs bash .cycleswap/run.sh from the /app working directory, where your project files are copied.

The default for Python projects:

export PATH="$HOME/.local/bin:$PATH"

uv run main.py

Edit this script to change what your job actually does. Any non-zero exit code marks the job as failed.

Build script

build.sh runs during the container image build, not at job time. Use it to install system packages, compile dependencies, or do any other setup that should be baked into the image rather than repeated on every job run.

Note

At build time, the only files accessible are .cycleswap/ itself and the files listed in build_files. Your project's source code is not copied in until run time. If the build script needs a file outside .cycleswap/ (like pyproject.toml), add it to build_files in the manifest.

Incremental caching

Build images are cached and layered incrementally. Each build runs on top of the previous build image for the same project, so repeated installs of the same packages are near-instant. The content of the build script and the files listed in build_files are hashed together, and the build only re-runs when that hash changes.

You can force a rebuild with --rebuild (re-runs the build script on top of the previous build image) or --clean (starts fresh from the base Ubuntu image). These flags work on both cycle project upload and cycle project test.

The default for Python projects installs uv and syncs dependencies from your pyproject.toml:

apt-get update -qq && apt-get install -y -qq curl && rm -rf /var/lib/apt/lists/*
curl -LsSf https://astral.sh/uv/install.sh | sh

export PATH="$HOME/.local/bin:$PATH"

uv sync