Skip to content

Commit 36a9973

Browse files
JAORMXclaude
andcommitted
feat: add reference container images for waggle runtimes (#9)
Add minimal Alpine 3.21 OCI images for python, node, and shell runtimes with the required GNU coreutils and findutils. Includes CI workflow for multi-arch builds with cosign signing, Taskfile targets for local builds, and README documentation for runtime image requirements. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent d9122ab commit 36a9973

6 files changed

Lines changed: 154 additions & 3 deletions

File tree

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# SPDX-FileCopyrightText: Copyright 2025 Stacklok, Inc.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
name: Release Runtime Images
5+
6+
on:
7+
push:
8+
tags:
9+
- 'v*'
10+
11+
permissions: {}
12+
13+
jobs:
14+
build-and-push:
15+
name: Build ${{ matrix.image }} image
16+
runs-on: ubuntu-latest
17+
permissions:
18+
contents: read
19+
packages: write
20+
id-token: write
21+
strategy:
22+
matrix:
23+
image: [python, node, shell]
24+
steps:
25+
- name: Checkout code
26+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
27+
28+
- name: Set up QEMU
29+
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3
30+
31+
- name: Set up Docker Buildx
32+
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3
33+
34+
- name: Log in to GitHub Container Registry
35+
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3
36+
with:
37+
registry: ghcr.io
38+
username: ${{ github.actor }}
39+
password: ${{ secrets.GITHUB_TOKEN }}
40+
41+
- name: Extract tag version
42+
id: tag
43+
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
44+
45+
- name: Set repository owner lowercase
46+
id: repo_owner
47+
env:
48+
REPO_OWNER: ${{ github.repository_owner }}
49+
run: echo "OWNER=$(echo "$REPO_OWNER" | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT
50+
51+
- name: Build and push image
52+
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6
53+
with:
54+
context: images/${{ matrix.image }}
55+
platforms: linux/amd64,linux/arm64
56+
push: true
57+
tags: |
58+
ghcr.io/${{ steps.repo_owner.outputs.OWNER }}/waggle/${{ matrix.image }}:${{ steps.tag.outputs.VERSION }}
59+
ghcr.io/${{ steps.repo_owner.outputs.OWNER }}/waggle/${{ matrix.image }}:latest
60+
61+
- name: Install Cosign
62+
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
63+
64+
- name: Sign images with Cosign
65+
env:
66+
IMAGE: ghcr.io/${{ steps.repo_owner.outputs.OWNER }}/waggle/${{ matrix.image }}
67+
TAG_VERSION: ${{ steps.tag.outputs.VERSION }}
68+
run: |
69+
cosign sign -y "$IMAGE:$TAG_VERSION"
70+
cosign sign -y "$IMAGE:latest"

README.md

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,9 @@ cd waggle
111111
task build
112112

113113
# Configure runtime images and run
114-
export WAGGLE_IMAGE_PYTHON=ghcr.io/stacklok/waggle-python:latest
115-
export WAGGLE_IMAGE_NODE=ghcr.io/stacklok/waggle-node:latest
116-
export WAGGLE_IMAGE_SHELL=alpine:latest
114+
export WAGGLE_IMAGE_PYTHON=ghcr.io/stacklok/waggle/python:latest
115+
export WAGGLE_IMAGE_NODE=ghcr.io/stacklok/waggle/node:latest
116+
export WAGGLE_IMAGE_SHELL=ghcr.io/stacklok/waggle/shell:latest
117117
task run
118118
```
119119

@@ -157,6 +157,33 @@ Each environment is a separate microVM with its own kernel — not a container s
157157
- Background reaper auto-destroys idle environments
158158
- No host filesystem exposed to environments
159159

160+
## Runtime Images
161+
162+
Waggle provides reference OCI images for each supported runtime. These are minimal Alpine containers with just the language runtime and required utilities.
163+
164+
| Image | Contents |
165+
|-------|----------|
166+
| `ghcr.io/stacklok/waggle/python:latest` | Alpine 3.21 + Python 3, pip, coreutils, findutils |
167+
| `ghcr.io/stacklok/waggle/node:latest` | Alpine 3.21 + Node.js, npm, coreutils, findutils |
168+
| `ghcr.io/stacklok/waggle/shell:latest` | Alpine 3.21 + coreutils, findutils |
169+
170+
Build all images locally:
171+
172+
```bash
173+
task build-images # Build all three runtime images
174+
task build-image-python # Build only the Python image
175+
```
176+
177+
### Custom Images
178+
179+
You can use your own OCI images as long as they include:
180+
181+
- The language runtime for the target environment (`python3`, `node`, etc.)
182+
- GNU coreutils (waggle's SSH executor requires `base64 -d`)
183+
- GNU findutils (waggle's file listing requires `find -printf`)
184+
185+
No SSH server is needed — `waggle-init` is injected into the VM at boot time by propolis and handles all communication.
186+
160187
## Development
161188

162189
```bash

Taskfile.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ vars:
77
BINARY_NAME: waggle
88
BUILD_DIR: bin
99
MAIN_PACKAGE: ./cmd/waggle
10+
IMAGE_REGISTRY: ghcr.io/stacklok/waggle
11+
IMAGE_TAG:
12+
sh: git describe --tags --always --dirty 2>/dev/null || echo "dev"
1013
VERSION:
1114
sh: git describe --tags --always --dirty 2>/dev/null || echo "dev"
1215
COMMIT:
@@ -116,6 +119,39 @@ tasks:
116119
- rm -rf {{.BUILD_DIR}}/
117120
- rm -f coverage.out coverage.html
118121

122+
build-image-python:
123+
desc: Build Python runtime image
124+
cmds:
125+
- docker build -t {{.IMAGE_REGISTRY}}/python:{{.IMAGE_TAG}} images/python/
126+
sources:
127+
- images/python/Dockerfile
128+
129+
build-image-node:
130+
desc: Build Node.js runtime image
131+
cmds:
132+
- docker build -t {{.IMAGE_REGISTRY}}/node:{{.IMAGE_TAG}} images/node/
133+
sources:
134+
- images/node/Dockerfile
135+
136+
build-image-shell:
137+
desc: Build shell runtime image
138+
cmds:
139+
- docker build -t {{.IMAGE_REGISTRY}}/shell:{{.IMAGE_TAG}} images/shell/
140+
sources:
141+
- images/shell/Dockerfile
142+
143+
build-images:
144+
desc: Build all runtime images
145+
deps: [build-image-python, build-image-node, build-image-shell]
146+
147+
push-images:
148+
desc: Push all runtime images to registry
149+
deps: [build-images]
150+
cmds:
151+
- docker push {{.IMAGE_REGISTRY}}/python:{{.IMAGE_TAG}}
152+
- docker push {{.IMAGE_REGISTRY}}/node:{{.IMAGE_TAG}}
153+
- docker push {{.IMAGE_REGISTRY}}/shell:{{.IMAGE_TAG}}
154+
119155
run:
120156
desc: Build and run the server
121157
deps: [build]

images/node/Dockerfile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# SPDX-FileCopyrightText: Copyright 2025 Stacklok, Inc.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
FROM alpine:3.21
5+
6+
RUN apk add --no-cache nodejs npm coreutils findutils

images/python/Dockerfile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# SPDX-FileCopyrightText: Copyright 2025 Stacklok, Inc.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
FROM alpine:3.21
5+
6+
RUN apk add --no-cache python3 py3-pip coreutils findutils

images/shell/Dockerfile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# SPDX-FileCopyrightText: Copyright 2025 Stacklok, Inc.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
FROM alpine:3.21
5+
6+
RUN apk add --no-cache coreutils findutils

0 commit comments

Comments
 (0)