Cordium documentation · Latest

Overview

A Workspace's behavior is determined by its spec. The same spec structure is used by Workspaces, Templates and the repository configuration files, and it is what you write in the YAML files that you pass to cordium run --file, cordium create workspace --file and cordium create template --file. This section covers every configuration option of the spec, while this page explains how the spec is structured, how its configuration levels are merged, and how variables work.

note

For exact fields, types, and enum values, you can always refer to the Workspace JSON Schema and the Template JSON Schema, or to the interactive schema viewers at the end of this page.

Spec Structure

Here is the top-level structure of a spec:

spec: image: ... # The container image (read more in "Images and Devcontainers") repository: ... # The primary repository (read more in "Repositories") additionalRepositories: ... # Secondary repositories runtime: # Read more in "Environment and Tasks" envVars: ... tasks: ... volumeMounts: ... # Read more in "Volumes" network: ... # Read more in "Network Policies" octelium: ... # Read more in "Secretless Access" filesystem: ... capabilities: ... timeout: ... autoStop: ... cmd: ... entrypoint: ... disableInit: ... devcontainers: ... applications: ... # Workspaces only (read more in "Applications and Ports") limit: ... # Read more in "Resources and Timeouts" vars: ... # Variables (read more below) isEphemeral: ... # Workspaces only gitProvider: ... # Templates only (read more in "Secrets and GitProviders")

Here is a complete example of a development Workspace for a Go service that uses most of these sections:

spec: image: registry: url: golang:1.26-bookworm repository: url: https://github.com/acme-corp/payments-api cloneOptions: branch: main vars: - name: LOG_LEVEL value: info runtime: envVars: - key: LOG_LEVEL value: ${{ vars.LOG_LEVEL }} - key: CGO_ENABLED value: "0" - key: STRIPE_API_KEY fromSecret: stripe-test-key.payments.cordium tasks: - name: deps type: ON_CREATE workingDir: /workspace/repo run: go mod download onFailure: ON_FAILURE_ABORT - name: dev-server type: POST_START workingDir: /workspace/repo run: go run ./cmd/server isBackground: true volumeMounts: - volumeRef: name: go-cache mountPath: /cache applications: - name: api port: 8080 isDefault: true limit: cpu: millicores: 4000 memory: megabytes: 8192 storage: megabytes: 30000

You can run it as follows:

cordium run --space payments.cordium --file workspace.yaml # Override a variable for this Workspace cordium run --space payments.cordium --file workspace.yaml --var LOG_LEVEL=debug

Configuration Levels

The effective configuration of a Workspace run is assembled at initialization time from several levels:

Repository configuration file (.cordium.yaml), if any (the most specific level) ↓ Workspace spec ↓ Template spec ↓ Space runtime configuration and limits ↓ UserConfig (personal environment variables, tasks and dotfiles) ↓ ClusterConfig defaults and caps (the least specific level)

Here is how each part of the spec is merged:

  • Image, repository and other single values of the Workspace spec override those of the Template spec, and those of the repository configuration file override both. Nested objects are merged field by field, which means that you can, for example, only override the cloneOptions.branch of the Template's repository.

  • Lists (e.g. environment variables, tasks, additional repositories, Volume mounts, egress rules and capabilities) are concatenated: the Template's entries first, followed by the Workspace's and then the repository configuration file's.

  • Environment variables with the same key are resolved by precedence: the Workspace wins over the Template, which wins over the Space, which wins over the UserConfig.

  • Lifecycle tasks run in the following order: the Template's tasks, then the Workspace's, then the UserConfig's, and finally the Space's, within each task type (read more here).

  • Resource limits are resolved by precedence (Workspace > Template > Space default > Cluster default), where the most specific limit is taken as a whole, and then capped by the Space and Cluster maximums. For example, if a Workspace requests 16 CPU cores while its Space's maximum is 8 cores, it gets 8 cores (read more here).

  • Variables are resolved by precedence (run-specific variables > Workspace > Template) and substituted after all the levels are merged (read more below).

  • Applications and ephemerality are only defined by the Workspace itself, while the GitProvider is only defined by its Template.

note

Workspace specs can be updated at any time (e.g. via the web portal or the UpdateWorkspace API), and Template specs can be updated by the Space admins. Changes take effect the next time the Workspace starts. Note that ON_CREATE tasks and image changes only take effect on fresh runs (i.e. the first run of a persistent Workspace and every run of an ephemeral one).

Variables

Variables let you parameterize Templates and Workspaces. They are declared in the vars list and referenced from string fields via the ${{ vars.NAME }} syntax (${{vars.NAME}} also works). Here is an example of a parameterized Template for running a test suite of a monorepo:

spec: vars: - name: REF value: main - name: SERVICE value: services/payments - name: RACE value: "true" image: registry: url: golang:1.26-bookworm repository: url: https://github.com/acme-corp/monorepo runtime: autoStop: true tasks: - name: checkout type: ON_CREATE workingDir: /workspace/repo onFailure: ON_FAILURE_ABORT run: git fetch -q origin "${{ vars.REF }}" && git checkout -q FETCH_HEAD - name: test type: ON_CREATE workingDir: /workspace/repo/${{ vars.SERVICE }} onFailure: ON_FAILURE_ABORT run: | if [ "${{ vars.RACE }}" = "true" ]; then go test -race ./... else go test ./... fi

Variables can be set or overridden at three levels:

# 1. In the Template spec (the defaults above) cordium create template monorepo-test.payments.cordium --file template.yaml # 2. In the Workspace spec, at creation time cordium create ws --template monorepo-test.payments.cordium --ephemeral \ --var SERVICE=services/ledger --var REF=feat/ledger-v2 # 3. For a single run, without modifying the Workspace's spec cordium start abc --var REF=fix/rounding

Variables are substituted after all the configuration levels are merged, in the following fields:

  • The registry image URL, the Dockerfile URL, and the URL, checkout, Dockerfile path and context of a git-based image.

  • The URL, branch and checkout of the primary and additional repositories.

  • The values of the environment variables (but not the names of the referenced Secrets).

  • The run script, the workingDir and the environment variable values of the lifecycle tasks.

note

Variables are not substituted inside inline Dockerfiles. References to variables that are not declared at any level are replaced by an empty string.

warning

The repository and Dockerfile URLs and the git branches and checkouts are validated when a Workspace or a Template is created or updated, i.e. before the variables are substituted. Currently, this means that variables cannot be used in the branch and checkout fields, and that variables used in URLs must be written without spaces (e.g. https://github.com/${{vars.REPO}}). To parameterize the branch or the commit, check it out in an ON_CREATE task as shown above.

Repository Configuration Files

A repository can carry its own Cordium configuration in a file at its root, so that the configuration lives in version control alongside the code. Cordium looks for the first of the following files in the primary repository after cloning it:

.cordium/workspace.yaml .cordium/workspace.yml .cordium.yaml .cordium.yml

The file contains a spec in the same format as above, and it is merged on top of the Workspace and Template specs as described above. Here is an example .cordium/workspace.yaml:

spec: runtime: envVars: - key: NODE_ENV value: development tasks: - name: install type: ON_CREATE workingDir: /workspace/repo run: npm ci onFailure: ON_FAILURE_ABORT - name: dev type: POST_START workingDir: /workspace/repo run: npm run dev -- --host 0.0.0.0 isBackground: true

Applications are not read from the repository configuration file since they belong to the Workspace itself. The image defined in the file is only used when neither the Workspace nor its Template sets an image, or when they explicitly build the image from the repository (read more here). The file is validated like any other spec, which means that, for example, the Secrets it references must exist in the Workspace's Space.

The Workspace Environment

Every Workspace provides the following environment regardless of its image:

ItemDescription
/workspaceThe Workspace's persistent working directory, owned by the Workspace user.
/workspace/repoThe primary repository, if any.
/workspace/additional-repos/<NAME>The additional repositories, if any.
$HOMEThe Workspace user's home directory, which is persisted along with the rest of the container's filesystem for persistent Workspaces.
CORDIUM_NAMEThe Workspace's name (e.g. x7k2).
CORDIUM_HOSTNAMEThe Workspace's public hostname (e.g. x7k2.cordium.example.com).
OCTELIUM_DOMAINThe Cluster domain.
OCTELIUM_AUTH_PROXY_SOCKETThe Unix socket of the Workspace's authentication proxy, used by the cordium, octelium and octeliumctl CLIs.
SSH_AUTH_SOCKThe SSH agent holding the private keys of your SSH_KEY UserSecrets (read more here).

The Workspace user is chosen as follows: the octelium user if the image defines one, otherwise the image's existing user with the UID 1000 (e.g. ubuntu in Ubuntu images or node in the official Node.js images), otherwise Cordium creates an octelium user with the UID 1000. The Workspace user can always escalate to root via passwordless sudo, and lifecycle tasks and cordium exec commands can run as root via their runAsRoot and --root options respectively. The hostname of every Workspace is cordium.

API Reference