Cordium documentation · Latest

Running Containers

Workspaces can run their own containers via rootless Podman, which turns a Workspace into a complete environment for applications that depend on databases, caches, message brokers and other services (read more here). Since the containers run inside the Workspace's own sandbox, they do not have any access to the host or to the Cluster, and they are stopped with the Workspace.

Development Dependencies

The following Template installs Podman and starts PostgreSQL and Redis containers on every start of the Workspace. The containers use the Workspace's network (i.e. --net host), which means that the application reaches them at localhost:

spec: image: registry: url: golang:1.26-bookworm repository: url: https://github.com/acme-corp/payments-api authentication: http: username: x-access-token password: fromSecret: github-read-token.payments.cordium runtime: envVars: - key: DATABASE_URL value: postgres://postgres:postgres@localhost:5432/payments?sslmode=disable - key: REDIS_URL value: redis://localhost:6379 tasks: - name: install-podman type: ON_CREATE runAsRoot: true onFailure: ON_FAILURE_ABORT run: | apt-get update apt-get install -y --no-install-recommends podman postgresql-client redis-tools - name: postgres type: POST_START onFailure: ON_FAILURE_ABORT run: | sudo podman rm -f postgres > /dev/null 2>&1 || true sudo podman run -d --name postgres --net host \ -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=payments \ -v payments-pgdata:/var/lib/postgresql \ docker.io/library/postgres:18 timeout 60 sh -c 'until pg_isready -q -h localhost; do sleep 1; done' - name: redis type: POST_START onFailure: ON_FAILURE_ABORT run: | sudo podman rm -f redis > /dev/null 2>&1 || true sudo podman run -d --name redis --net host docker.io/library/redis:8-alpine timeout 30 sh -c 'until redis-cli ping > /dev/null 2>&1; do sleep 1; done' - name: migrate type: POST_START workingDir: /workspace/repo run: go run ./cmd/migrate up - name: stop-containers type: PRE_STOP run: sudo podman stop --time 20 postgres redis limit: cpu: millicores: 4000 memory: megabytes: 8192 storage: megabytes: 40000
cordium create template payments-deps.payments.cordium --file payments-deps.yaml

Here are a few notes about this Template:

  • The container images are only downloaded on the first start of a persistent Workspace, since the Podman storage is part of the Workspace's storage.

  • The PostgreSQL data lives in the payments-pgdata Podman volume, which also persists across restarts of a persistent Workspace. The PRE_STOP task stops the database gracefully before the Workspace stops.

  • The containers count towards the Workspace's CPU, memory and storage limits.

Compose Files

If your repository already has a Compose file for its dependencies, you can run it via podman-compose. Here is the relevant part of a Template for a repository that has a compose.dev.yaml file at its root:

spec: runtime: tasks: - name: install-podman type: ON_CREATE runAsRoot: true onFailure: ON_FAILURE_ABORT run: | apt-get update apt-get install -y --no-install-recommends podman podman-compose - name: services type: POST_START workingDir: /workspace/repo onFailure: ON_FAILURE_ABORT run: sudo podman-compose -f compose.dev.yaml up -d - name: stop-services type: PRE_STOP workingDir: /workspace/repo run: sudo podman-compose -f compose.dev.yaml stop

Ports published by the Compose services (e.g. 5432:5432) are reachable at localhost inside the Workspace.

Integration Tests in CI

The same approach works for ephemeral CI Workspaces that run integration tests against real dependencies instead of mocks. With autoStop, the Workspace stops as soon as the tests complete, and the run fails if they fail:

spec: runtime: autoStop: true tasks: - name: integration-tests type: POST_START workingDir: /workspace/repo onFailure: ON_FAILURE_ABORT run: go test -tags integration -count 1 ./...

Added to a Workspace of the Template above, the integration-tests task runs after the postgres, redis and migrate tasks, since the Workspace's tasks run after the Template's (read more here):

cordium create ws --template payments-deps.payments.cordium --ephemeral --start --file integration.yaml

To build and push container images from Workspaces, read this example.