Running Containers

Cordium Workspaces can run nested containers with Podman. This makes it possible to use a Workspace not only as a shell environment, but also as a complete development or automation environment capable of running databases, web servers, etc. Here is a rather detailed example:

spec: image: registry: url: golang:1.23-bookworm repository: url: https://github.com/example/data-platform cloneOptions: branch: main depth: 1 runtime: envVars: - key: POSTGRES_DSN value: postgres://postgres:password@localhost:5432/app?sslmode=disable - key: MYSQL_DSN value: root:password@tcp(localhost:3306)/app - key: REDIS_ADDR value: localhost:6379 - key: CLICKHOUSE_DSN value: clickhouse://octelium:octelium@localhost:9000/default tasks: - name: install-tools type: ON_CREATE runAsRoot: true run: | apt-get update apt-get install -y \ podman \ git \ curl \ jq \ postgresql-client \ default-mysql-client \ redis-tools \ build-essential \ && rm -rf /var/lib/apt/lists/* - name: download-go-dependencies type: ON_CREATE workingDir: /workspace/repo run: | go mod download onFailure: ON_FAILURE_ABORT - name: start-postgres type: POST_START run: | sudo podman rm -f cordium-postgres 2>/dev/null || true sudo podman run \ --name cordium-postgres \ --net host \ -e POSTGRES_PASSWORD=password \ -e POSTGRES_DB=app \ -d docker.io/postgres:16 until pg_isready -h localhost -p 5432 -U postgres; do sleep 1 done - name: start-mariadb type: POST_START run: | sudo podman rm -f cordium-mariadb 2>/dev/null || true sudo podman run \ --name cordium-mariadb \ --net host \ -e MARIADB_ROOT_PASSWORD=password \ -e MARIADB_DATABASE=app \ -d docker.io/mariadb:11 until mysqladmin ping -h 127.0.0.1 -P 3306 -uroot -ppassword --silent; do sleep 1 done - name: start-redis type: POST_START run: | sudo podman rm -f cordium-redis 2>/dev/null || true sudo podman run \ --name cordium-redis \ --net host \ -d docker.io/redis:7 until redis-cli -h localhost ping | grep -q PONG; do sleep 1 done - name: start-clickhouse type: POST_START run: | sudo podman rm -f cordium-clickhouse 2>/dev/null || true sudo podman run \ --name cordium-clickhouse \ --net host \ -e CLICKHOUSE_USER=octelium \ -e CLICKHOUSE_PASSWORD=octelium \ -d docker.io/clickhouse/clickhouse-server:latest until curl -fsS http://localhost:8123/ping | grep -q Ok; do sleep 1 done - name: run-integration-tests type: POST_START workingDir: /workspace/repo run: | go test ./... -count=1 onFailure: ON_FAILURE_ABORT - name: start-service type: POST_START workingDir: /workspace/repo isBackground: true run: | go run ./cmd/server - name: stop-containers type: PRE_STOP run: | sudo podman rm -f \ cordium-postgres \ cordium-mariadb \ cordium-redis \ cordium-clickhouse \ 2>/dev/null || true limit: cpu: millicores: 8000 memory: megabytes: 16384 storage: megabytes: 50000

You can also use Cordium to build Docker/OCI images and push them to registries (e.g. ghcr). Here is an example:

spec: vars: - name: REPO_URL value: https://github.com/myorg/my-service - name: BRANCH value: main - name: IMAGE value: ghcr.io/myorg/my-service - name: TAG value: latest - name: DOCKERFILE value: Dockerfile - name: CONTEXT value: . image: registry: url: ubuntu:24.04 repository: url: ${{ vars.REPO_URL }} cloneOptions: branch: ${{ vars.BRANCH }} depth: 1 singleBranch: true disableLazyUnshallow: true runtime: envVars: - key: REGISTRY value: ghcr.io - key: REGISTRY_USERNAME value: myorg - key: REGISTRY_TOKEN fromSecret: ghcr-token tasks: - name: install-podman type: ON_CREATE runAsRoot: true run: | apt-get update apt-get install -y \ ca-certificates \ curl \ git \ jq \ podman \ buildah \ skopeo \ && rm -rf /var/lib/apt/lists/* - name: registry-login type: ON_CREATE run: | echo "${REGISTRY_TOKEN}" | sudo podman login "${REGISTRY}" \ --username "${REGISTRY_USERNAME}" \ --password-stdin - name: build-image type: ON_CREATE workingDir: /workspace/repo run: | sudo podman build \ --pull=always \ --file "${{ vars.DOCKERFILE }}" \ --tag "${{ vars.IMAGE }}:${{ vars.TAG }}" \ "${{ vars.CONTEXT }}" - name: push-image type: ON_CREATE run: | sudo podman push "${{ vars.IMAGE }}:${{ vars.TAG }}" - name: inspect-pushed-image type: ON_CREATE run: | skopeo inspect "docker://${{ vars.IMAGE }}:${{ vars.TAG }}" | jq . autoStop: true limit: cpu: millicores: 4000 memory: megabytes: 8192 storage: megabytes: 30000