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: 50000You 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