Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 932e889ee8 | |||
| 48ca873fe2 |
@@ -0,0 +1,81 @@
|
|||||||
|
name: Rebuild Docker images
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: rebuild-docker-images
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
rebuild-and-push:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
REGISTRY: docker.dcglab.co.uk
|
||||||
|
IMAGE_BASE: docker.dcglab.co.uk/public/kb
|
||||||
|
REGISTRY_USERNAME: ${{ secrets.DOCKER_DCGLAB_CI_USERNAME }}
|
||||||
|
REGISTRY_PASSWORD: ${{ secrets.DOCKER_DCGLAB_CI_PASSWORD }}
|
||||||
|
steps:
|
||||||
|
- name: Check out repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Log in to registry
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
test -n "$REGISTRY_USERNAME" || { echo "DOCKER_DCGLAB_CI_USERNAME is not available" >&2; exit 1; }
|
||||||
|
test -n "$REGISTRY_PASSWORD" || { echo "DOCKER_DCGLAB_CI_PASSWORD is not available" >&2; exit 1; }
|
||||||
|
printf '%s' "$REGISTRY_PASSWORD" | docker login "$REGISTRY" --username "$REGISTRY_USERNAME" --password-stdin
|
||||||
|
|
||||||
|
- name: Build all images from scratch
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
version="$(tr -d '[:space:]' < engine/VERSION)"
|
||||||
|
|
||||||
|
docker build --pull --no-cache --provenance=false --sbom=false \
|
||||||
|
-t "$IMAGE_BASE/engine:v${version}-nvidia" \
|
||||||
|
-t "$IMAGE_BASE/engine:latest-nvidia" \
|
||||||
|
-f engine/Dockerfile.nvidia engine
|
||||||
|
|
||||||
|
docker build --pull --no-cache --provenance=false --sbom=false \
|
||||||
|
-t "$IMAGE_BASE/engine:v${version}-cpu" \
|
||||||
|
-t "$IMAGE_BASE/engine:latest-cpu" \
|
||||||
|
-f engine/Dockerfile.cpu engine
|
||||||
|
|
||||||
|
docker build --pull --no-cache --provenance=false --sbom=false \
|
||||||
|
-t "$IMAGE_BASE/mcp:v${version}" \
|
||||||
|
-t "$IMAGE_BASE/mcp:latest" \
|
||||||
|
-f mcp/Dockerfile mcp
|
||||||
|
|
||||||
|
- name: Push and verify all tags
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
version="$(tr -d '[:space:]' < engine/VERSION)"
|
||||||
|
images=(
|
||||||
|
"$IMAGE_BASE/engine:v${version}-nvidia"
|
||||||
|
"$IMAGE_BASE/engine:latest-nvidia"
|
||||||
|
"$IMAGE_BASE/engine:v${version}-cpu"
|
||||||
|
"$IMAGE_BASE/engine:latest-cpu"
|
||||||
|
"$IMAGE_BASE/mcp:v${version}"
|
||||||
|
"$IMAGE_BASE/mcp:latest"
|
||||||
|
)
|
||||||
|
|
||||||
|
push_image() {
|
||||||
|
local image="$1"
|
||||||
|
local attempt
|
||||||
|
for attempt in 1 2 3 4 5; do
|
||||||
|
docker push "$image" && return 0
|
||||||
|
if [[ "$attempt" -eq 5 ]]; then
|
||||||
|
echo "Failed to push $image after $attempt attempts" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
sleep 10
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
for image in "${images[@]}"; do
|
||||||
|
push_image "$image"
|
||||||
|
docker manifest inspect "$image" >/dev/null
|
||||||
|
done
|
||||||
+5
-1
@@ -90,11 +90,15 @@ curl http://localhost:8000/api/v1/status | jq .version
|
|||||||
|
|
||||||
### Docker images
|
### Docker images
|
||||||
|
|
||||||
Images are pushed to `docker.dcglab.co.uk/kb/engine` with tags:
|
Images are pushed to `docker.dcglab.co.uk/public/kb/engine` with tags:
|
||||||
|
|
||||||
- `engine-v2.0.6-nvidia` / `engine-v2.0.6-cpu` — versioned
|
- `engine-v2.0.6-nvidia` / `engine-v2.0.6-cpu` — versioned
|
||||||
- `latest-nvidia` / `latest-cpu` — latest release
|
- `latest-nvidia` / `latest-cpu` — latest release
|
||||||
|
|
||||||
|
The release script authenticates to the registry using the
|
||||||
|
`DOCKER_DCGLAB_CI_USERNAME` and `DOCKER_DCGLAB_CI_PASSWORD` environment
|
||||||
|
variables.
|
||||||
|
|
||||||
Override the registry and org via environment variables:
|
Override the registry and org via environment variables:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ docker run -d --name kb-mcp \
|
|||||||
-e KB_API_KEY=your-engine-key \
|
-e KB_API_KEY=your-engine-key \
|
||||||
-e KB_MCP_API_KEY=your-agent-key \
|
-e KB_MCP_API_KEY=your-agent-key \
|
||||||
--restart unless-stopped \
|
--restart unless-stopped \
|
||||||
docker.dcglab.co.uk/kb/mcp:latest
|
docker.dcglab.co.uk/public/kb/mcp:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
## MCP tools
|
## MCP tools
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ docker run -d --name kb-engine \
|
|||||||
-e KB_DEVICE=auto \
|
-e KB_DEVICE=auto \
|
||||||
-e KB_API_KEY=your-secret-key \
|
-e KB_API_KEY=your-secret-key \
|
||||||
--restart unless-stopped \
|
--restart unless-stopped \
|
||||||
docker.dcglab.co.uk/kb/engine:latest-nvidia
|
docker.dcglab.co.uk/public/kb/engine:latest-nvidia
|
||||||
|
|
||||||
# CPU only (no GPU required — smaller image)
|
# CPU only (no GPU required — smaller image)
|
||||||
docker run -d --name kb-engine \
|
docker run -d --name kb-engine \
|
||||||
@@ -42,7 +42,7 @@ docker run -d --name kb-engine \
|
|||||||
-e KB_MODEL=all-MiniLM-L6-v2 \
|
-e KB_MODEL=all-MiniLM-L6-v2 \
|
||||||
-e KB_API_KEY=your-secret-key \
|
-e KB_API_KEY=your-secret-key \
|
||||||
--restart unless-stopped \
|
--restart unless-stopped \
|
||||||
docker.dcglab.co.uk/kb/engine:latest-cpu
|
docker.dcglab.co.uk/public/kb/engine:latest-cpu
|
||||||
```
|
```
|
||||||
|
|
||||||
Or use a compose file from the repo:
|
Or use a compose file from the repo:
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ The project SHALL provide Docker Compose files for single-command deployment. Co
|
|||||||
|
|
||||||
#### Scenario: Pre-built image deployment
|
#### Scenario: Pre-built image deployment
|
||||||
- **WHEN** an admin wants to use a pre-built engine image without building from source
|
- **WHEN** an admin wants to use a pre-built engine image without building from source
|
||||||
- **THEN** the engine release notes SHALL include the exact `docker pull` command with the versioned tag (e.g. `docker.dcglab.co.uk/kb/engine:engine-v2.1.0-nvidia`)
|
- **THEN** the engine release notes SHALL include the exact `docker pull` command with the versioned tag (e.g. `docker.dcglab.co.uk/public/kb/engine:engine-v2.1.0-nvidia`)
|
||||||
|
|
||||||
#### Scenario: MCP allowed hosts in Compose
|
#### Scenario: MCP allowed hosts in Compose
|
||||||
- **WHEN** the kb-mcp service is defined in a Compose file
|
- **WHEN** the kb-mcp service is defined in a Compose file
|
||||||
|
|||||||
+22
-1
@@ -20,7 +20,7 @@ VERSION_FILE="$ENGINE_DIR/VERSION"
|
|||||||
# attestation manifests, making the image an OCI image index. The Registry v2
|
# attestation manifests, making the image an OCI image index. The Registry v2
|
||||||
# host at docker.dcglab.co.uk rejects those with a 500 on manifest PUT.
|
# host at docker.dcglab.co.uk rejects those with a 500 on manifest PUT.
|
||||||
REGISTRY="${REGISTRY:-docker.dcglab.co.uk}"
|
REGISTRY="${REGISTRY:-docker.dcglab.co.uk}"
|
||||||
IMAGE_ORG="${IMAGE_ORG:-}"
|
IMAGE_ORG="${IMAGE_ORG:-public}"
|
||||||
IMAGE_BASE="${REGISTRY}${IMAGE_ORG:+/${IMAGE_ORG}}/kb"
|
IMAGE_BASE="${REGISTRY}${IMAGE_ORG:+/${IMAGE_ORG}}/kb"
|
||||||
|
|
||||||
# Push retries — see push_image() below
|
# Push retries — see push_image() below
|
||||||
@@ -106,6 +106,16 @@ run() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registry_login() {
|
||||||
|
echo " $ docker login $REGISTRY --username \$DOCKER_DCGLAB_CI_USERNAME --password-stdin"
|
||||||
|
[[ "$DRY_RUN" == true ]] && return 0
|
||||||
|
|
||||||
|
printf '%s' "$DOCKER_DCGLAB_CI_PASSWORD" |
|
||||||
|
docker login "$REGISTRY" \
|
||||||
|
--username "$DOCKER_DCGLAB_CI_USERNAME" \
|
||||||
|
--password-stdin
|
||||||
|
}
|
||||||
|
|
||||||
# Push one image tag, retrying on transient registry failures.
|
# Push one image tag, retrying on transient registry failures.
|
||||||
#
|
#
|
||||||
# The engine images carry a ~5.6GB torch layer. Uploading it intermittently
|
# The engine images carry a ~5.6GB torch layer. Uploading it intermittently
|
||||||
@@ -165,6 +175,17 @@ echo ""
|
|||||||
echo "==> Pre-flight checks"
|
echo "==> Pre-flight checks"
|
||||||
|
|
||||||
if [[ "$DRY_RUN" == false ]]; then
|
if [[ "$DRY_RUN" == false ]]; then
|
||||||
|
if [[ -z "${DOCKER_DCGLAB_CI_USERNAME:-}" ]]; then
|
||||||
|
echo "Error: DOCKER_DCGLAB_CI_USERNAME is required" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ -z "${DOCKER_DCGLAB_CI_PASSWORD:-}" ]]; then
|
||||||
|
echo "Error: DOCKER_DCGLAB_CI_PASSWORD is required" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
registry_login
|
||||||
|
|
||||||
if git -C "$SCRIPT_DIR" rev-parse "$GIT_TAG" &>/dev/null; then
|
if git -C "$SCRIPT_DIR" rev-parse "$GIT_TAG" &>/dev/null; then
|
||||||
echo "Error: tag $GIT_TAG already exists"
|
echo "Error: tag $GIT_TAG already exists"
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
Reference in New Issue
Block a user