Workspace Configuration

A Workspace's behavior is determined by its spec, the spec of its parent Template, the runtime configuration of its Space, and user-level configuration from UserConfig. These four levels are merged at initialization time in a defined precedence order.

This page covers every configuration option available in the Workspace and Template spec, with real-world examples demonstrating common development and automation patterns.

Configuration Sources and Merging

Precedence Order

Workspace configuration is resolved from the most specific resource to the least specific resource:

Workspace spec Template spec Space runtime spec Cluster defaults and caps

YAML File Format

All Workspace and Template configurations share the same top-level structure:

spec: image: ... repository: ... additionalRepositories: ... runtime: ... applications: ... limit: ... vars: ... gitProvider: ... # Template only

Image Configuration

The spec.image field defines the container image used as the Workspace filesystem. If omitted, Cordium uses a default base image with common development tools.

Registry Image

spec: image: registry: url: ubuntu:24.04

For images requiring authentication:

spec: image: registry: url: registry.mycompany.com/dev/base:latest authentication: username: robot-user password: fromSecret: registry-password

The fromSecret value is the name of a Secret in the same Space. The value is resolved server-side and never stored in the Workspace spec or visible in API responses.

Inline Dockerfile

spec: image: dockerfile: inline: | FROM debian:bookworm-slim RUN apt-get update && apt-get install -y \ build-essential git curl wget \ python3 python3-pip python3-venv \ && rm -rf /var/lib/apt/lists/* RUN pip3 install --break-system-packages poetry

Dockerfile from URL

spec: image: dockerfile: url: https://raw.githubusercontent.com/myorg/dockerfiles/main/dev/Dockerfile

Git Repository

Clone a git repository and build from a Dockerfile or devcontainer spec found within it:

spec: image: git: url: https://github.com/myorg/dev-images cloneOptions: checkout: main dockerfile: images/backend/Dockerfile context: images/backend

If dockerfile is omitted, Cordium looks for .devcontainer/devcontainer.json in the repository root.

Repository Devcontainer

Build from the devcontainer spec found in the Workspace's primary repository:

spec: image: repository: devcontainer: dirPath: .devcontainer

Or build from a specific Dockerfile within the repository:

spec: image: repository: dockerfile: path: docker/Dockerfile.dev context: .

Repository Cloning

Primary Repository

The spec.repository field defines the primary repository cloned into /workspace/repo:

spec: repository: url: https://github.com/myorg/my-project cloneOptions: branch: main depth: 1 # shallow clone depth (0 = full history) singleBranch: true # only fetch the specified branch checkout: abc1234 # specific commit or tag to checkout shallowSubmodules: true disableLazyUnshallow: false # if true, skips async full-history fetch

By default, Cordium performs a shallow clone at Workspace initialization for fast startup, then fetches full history asynchronously in the background. Set disableLazyUnshallow: true to skip the background fetch if full history is not needed (e.g. for CI/CD runs).

Repository Authentication

For private repositories using HTTP basic auth with a Secret:

spec: repository: url: https://github.com/myorg/private-repo authentication: http: username: oauth2 password: fromSecret: github-pat

For repositories where a GitProvider OAuth2 token should be used, configure a GitProvider on the Template instead of inline authentication. The token is injected automatically without any spec changes.

Additional Repositories

Clone one or more repositories alongside the primary. Additional repositories are cloned in parallel and land at their configured clonePath:

spec: additionalRepositories: - name: shared-libs clonePath: /workspace/additional-repos/shared-libs repository: url: https://github.com/myorg/shared-libs cloneOptions: branch: main - name: config-repo clonePath: /workspace/additional-repos/config repository: url: https://github.com/myorg/k8s-config authentication: http: username: deploy-token password: fromSecret: config-repo-token

Runtime Configuration

The spec.runtime field controls environment variables, lifecycle tasks, and container behavior.

Environment Variables

Environment variables are injected into the Workspace container and all lifecycle tasks. Values can be static strings or resolved from Secrets:

spec: runtime: envVars: - key: NODE_ENV value: development - key: LOG_LEVEL value: debug - key: DATABASE_URL fromSecret: staging-database-url - key: STRIPE_SECRET_KEY fromSecret: stripe-secret-key

Environment variables are merged across all configuration levels. If the same key appears at multiple levels, the more specific level wins (Workspace > Template > Space > UserConfig).

Lifecycle Tasks

Tasks run at defined points in the Workspace lifecycle. Every task supports the following fields:

FieldTypeDescription
namestringA unique name for the task, used in logs and failure reporting.
runstringShell command to execute.
typeenumON_CREATE, POST_START, or PRE_STOP.
workingDirstringWorking directory for the task. Defaults to the user's home directory.
isBackgroundboolIf true, the task starts and Workspace initialization proceeds without waiting for it to complete.
runAsRootboolIf true, the task runs as root inside the Workspace. Default is the Workspace user.
onFailureenumON_FAILURE_ABORT stops Workspace initialization on failure. ON_FAILURE_CONTINUE logs the error and continues.
envVarslistPer-task environment variable overrides, merged with the Workspace-level env vars.

Task Types

ON_CREATE runs on the first start of a Workspace (fresh run) only. It does not run on subsequent starts of a persistent Workspace. Use it for one-time setup: installing dependencies, running database migrations, compiling assets, seeding initial data.

POST_START runs on every Workspace start, including subsequent starts of a persistent Workspace. Use it for starting background services, running dev servers, establishing tunnels, or any service that must be running for the Workspace to be usable.

PRE_STOP runs before the Workspace container stops. Use it for graceful shutdown of services, flushing write buffers, or cleanup before the filesystem is snapshotted.

spec: runtime: tasks: - name: install-deps run: npm ci type: ON_CREATE workingDir: /workspace/repo onFailure: ON_FAILURE_ABORT - name: run-migrations run: npm run db:migrate type: ON_CREATE workingDir: /workspace/repo onFailure: ON_FAILURE_ABORT envVars: - key: NODE_ENV value: development - name: seed-data run: npm run db:seed type: ON_CREATE workingDir: /workspace/repo onFailure: ON_FAILURE_CONTINUE - name: start-redis run: redis-server --daemonize yes type: POST_START runAsRoot: true - name: dev-server run: npm run dev type: POST_START workingDir: /workspace/repo isBackground: true - name: graceful-shutdown run: npm run shutdown type: PRE_STOP workingDir: /workspace/repo onFailure: ON_FAILURE_CONTINUE

Container Command and Entrypoint

Override the container's default command and entrypoint:

spec: runtime: cmd: "sleep infinity" entrypoint: "/usr/bin/tini --" disableInit: false

disableInit: false (the default) adds a minimal init process as PID 1 for zombie process reaping. Set to true only if the container image already includes its own init system.

Applications and Port Sharing

Named applications expose Workspace ports through the portal's reverse proxy:

spec: applications: - name: web port: 3000 isDefault: true # accessible at <workspace>.cordium.<domain> - name: api port: 8080 # accessible at api_<workspace>.cordium.<domain> - name: storybook port: 6006 - name: docs port: 4000

Only one application can be marked isDefault. Specific ports not defined in the spec are accessible via port_<number>_<workspace>.cordium.<domain>.

Resource Limits

spec: limit: cpu: millicores: 4000 # 4 CPU cores (1 core = 1000 millicores) memory: megabytes: 8192 # 8 GB RAM storage: megabytes: 30000 # 30 GB disk

If omitted, limits are resolved from the Template, Space default, or Cluster default, in that order, and then capped by the Space maximum and Cluster maximum.

Variables

Variables are referenced using ${{ vars.NAME }} syntax in string fields:

spec: vars: - name: BRANCH value: main - name: SERVICE value: svc - name: RUN_TESTS value: "true" repository: url: https://github.com/myorg/monorepo cloneOptions: branch: ${{ vars.BRANCH }} runtime: tasks: - name: build run: | cd ${{ vars.SERVICE }} go build ./cmd/... type: ON_CREATE workingDir: /workspace/repo onFailure: ON_FAILURE_ABORT - name: test run: | if [ "${{ vars.RUN_TESTS }}" = "true" ]; then cd ${{ vars.SERVICE }} && go test ./... -race fi type: ON_CREATE workingDir: /workspace/repo onFailure: ON_FAILURE_ABORT

Variable substitution is applied after all configuration levels are merged, against the final spec. Substitution is supported in task run scripts, repository URLs, image URLs, working directories, and environment variable values. It is not applied to Secret names or structural fields like task types and failure modes.

Auto-Stop

Setting autoStop: true causes the Workspace to stop automatically once all non-background lifecycle tasks complete. Background tasks (those with isBackground: true) are not counted. This is most useful for CI/CD runs and automated workloads where no human interaction is expected after initialization completes.

spec: runtime: autoStop: true tasks: - name: build run: make build type: ON_CREATE workingDir: /workspace/repo onFailure: ON_FAILURE_ABORT - name: test run: make test type: ON_CREATE workingDir: /workspace/repo onFailure: ON_FAILURE_ABORT

Capabilities

Linux capabilities can be added and dropped as follows:

spec: runtime: capabilities: add: - NET_ADMIN - NET_RAW drop: - SYS_PTRACE - AUDIT_WRITE

Such capabilities are merged with the Space-level and ClusterConfig-level configurations.

Template-Only Fields

The following fields are available in Template specs but not in Workspace specs.

GitProvider

Associate a GitProvider with a Template to enable automatic OAuth2 token injection for authenticated git operations:

spec: gitProvider: github # name of a GitProvider in the same Space repository: url: https://github.com/myorg/backend-service

Inline Repository Configuration

A .cordium.yaml or .cordium/workspace.yaml file placed at the root of a cloned repository is automatically detected and merged with the Template spec at initialization time. This lets repository-specific configuration live in version control alongside the code:

my-project/ ├── .cordium/ │ └── workspace.yaml ← merged with Template spec at Workspace init ├── src/ └── ...

The repository config file is treated as more specific than the Template spec but still subject to Space and Cluster resource limit caps.

Devcontainer Support

Cordium implements the Development Container specification. If a Workspace's repository contains .devcontainer/devcontainer.json or .devcontainer.json, Cordium automatically builds or pulls the image defined in the devcontainer spec, it applies containerEnv values as Workspace environment variables, it downloads and installs devcontainer features from OCI registries, it appends onCreateCommand, updateContentCommand, postCreateCommand, and postStartCommand hooks to the appropriate task types and it installs VS Code extensions listed in customizations.vscode.extensions.

No Cordium-specific configuration is needed to activate devcontainer support. Set the image source to repository or git and ensure the repository contains a valid devcontainer spec.