Skip to content

Commit f648178

Browse files
authored
feat: slim docker distro (#314)
* feat: slim docker distro * feat: slim docker distro * push
1 parent fa4cbf7 commit f648178

File tree

7 files changed

+371
-26
lines changed

7 files changed

+371
-26
lines changed

.github/workflows/release.yml

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ jobs:
340340
retention-days: 1
341341

342342
release-docker-images:
343+
name: Release Docker (${{ matrix.image_name }}${{ matrix.tag_suffix }})
343344
runs-on: ubuntu-latest
344345
permissions:
345346
contents: read
@@ -349,10 +350,28 @@ jobs:
349350
include:
350351
- target: api-only
351352
image_name: hindsight-api
353+
tag_suffix: ""
354+
build_args: ""
355+
- target: api-only
356+
image_name: hindsight-api
357+
tag_suffix: "-slim"
358+
build_args: |
359+
INCLUDE_LOCAL_MODELS=false
360+
PRELOAD_ML_MODELS=false
352361
- target: cp-only
353362
image_name: hindsight-control-plane
363+
tag_suffix: ""
364+
build_args: ""
365+
- target: standalone
366+
image_name: hindsight
367+
tag_suffix: ""
368+
build_args: ""
354369
- target: standalone
355370
image_name: hindsight
371+
tag_suffix: "-slim"
372+
build_args: |
373+
INCLUDE_LOCAL_MODELS=false
374+
PRELOAD_ML_MODELS=false
356375
357376
steps:
358377
- uses: actions/checkout@v4
@@ -390,6 +409,9 @@ jobs:
390409
uses: docker/metadata-action@v5
391410
with:
392411
images: ghcr.io/${{ github.repository_owner }}/${{ matrix.image_name }}
412+
flavor: |
413+
latest=auto
414+
suffix=${{ matrix.tag_suffix }}
393415
tags: |
394416
type=semver,pattern={{version}},value=${{ steps.get_version.outputs.VERSION }}
395417
type=semver,pattern={{major}}.{{minor}},value=${{ steps.get_version.outputs.VERSION }}
@@ -415,7 +437,7 @@ jobs:
415437
# - name: Smoke test - verify container starts
416438
# env:
417439
# GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
418-
# run: ./scripts/docker-smoke-test.sh "${{ matrix.image_name }}:test" "${{ matrix.target }}"
440+
# run: ./docker/test-image.sh "${{ matrix.image_name }}:test" "${{ matrix.target }}"
419441

420442
# Build multi-platform and push to release tags
421443
- name: Build and push release images
@@ -424,6 +446,7 @@ jobs:
424446
context: .
425447
file: docker/standalone/Dockerfile
426448
target: ${{ matrix.target }}
449+
build-args: ${{ matrix.build_args }}
427450
push: true
428451
platforms: linux/amd64,linux/arm64
429452
tags: ${{ steps.meta.outputs.tags }}

.github/workflows/test.yml

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -277,16 +277,35 @@ jobs:
277277
run: helm lint helm/hindsight
278278

279279
build-docker-images:
280+
name: Build Docker (${{ matrix.name }})
280281
runs-on: ubuntu-latest
281282
strategy:
282283
matrix:
283284
include:
284285
- target: api-only
285286
name: api
287+
variant: full
288+
build_args: ""
289+
- target: api-only
290+
name: api-slim
291+
variant: slim
292+
build_args: |
293+
INCLUDE_LOCAL_MODELS=false
294+
PRELOAD_ML_MODELS=false
286295
- target: cp-only
287296
name: control-plane
297+
variant: full
298+
build_args: ""
288299
- target: standalone
289300
name: standalone
301+
variant: full
302+
build_args: ""
303+
- target: standalone
304+
name: standalone-slim
305+
variant: slim
306+
build_args: |
307+
INCLUDE_LOCAL_MODELS=false
308+
PRELOAD_ML_MODELS=false
290309
291310
steps:
292311
- uses: actions/checkout@v4
@@ -305,20 +324,30 @@ jobs:
305324
- name: Set up Docker Buildx
306325
uses: docker/setup-buildx-action@v3
307326

308-
- name: Build ${{ matrix.name }} image
327+
- name: Build ${{ matrix.name }} image (${{ matrix.variant }})
309328
uses: docker/build-push-action@v6
310329
with:
311330
context: .
312331
file: docker/standalone/Dockerfile
313332
target: ${{ matrix.target }}
333+
build-args: ${{ matrix.build_args }}
314334
push: false
315-
load: false
316-
317-
# TODO: Re-enable smoke test when disk space issue is resolved
318-
# - name: Smoke test - verify container starts
319-
# env:
320-
# GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
321-
# run: ./scripts/docker-smoke-test.sh "hindsight-${{ matrix.name }}:test" "${{ matrix.target }}"
335+
load: ${{ matrix.variant == 'slim' }}
336+
tags: hindsight-${{ matrix.name }}:test
337+
cache-from: type=gha,scope=${{ matrix.name }}
338+
cache-to: type=gha,mode=max,scope=${{ matrix.name }}
339+
340+
# Only test slim variants to save disk space (they're much smaller)
341+
# Slim variants require external embedding providers
342+
- name: Smoke test - verify container starts
343+
if: matrix.variant == 'slim'
344+
env:
345+
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
346+
HINDSIGHT_API_EMBEDDINGS_PROVIDER: openai
347+
HINDSIGHT_API_EMBEDDINGS_OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
348+
HINDSIGHT_API_RERANKER_PROVIDER: cohere
349+
HINDSIGHT_API_COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }}
350+
run: ./docker/test-image.sh "hindsight-${{ matrix.name }}:test" "${{ matrix.target }}"
322351

323352
test-api:
324353
runs-on: ubuntu-latest

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ docker run --rm -it --pull always -p 8888:8888 -p 9999:9999 \
5959

6060
You can modify the LLM provider by setting `HINDSIGHT_API_LLM_PROVIDER`. Valid options are `openai`, `anthropic`, `gemini`, `groq`, `ollama`, and `lmstudio`. The documentation provides more details on [supported models](https://hindsight.vectorize.io/developer/models).
6161

62-
API: http://localhost:8888
62+
API: http://localhost:8888
6363
UI: http://localhost:9999
6464

6565
Install client:

docker/README.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# Docker Testing
2+
3+
Scripts for testing Hindsight Docker images locally and in CI.
4+
5+
## Scripts
6+
7+
### `test-image.sh`
8+
9+
General-purpose Docker image test script. Starts a container and verifies it becomes healthy.
10+
11+
**Usage:**
12+
```bash
13+
./docker/test-image.sh <image> [target]
14+
```
15+
16+
**Arguments:**
17+
- `image` - Docker image to test (e.g., `hindsight:test`, `ghcr.io/vectorize-io/hindsight:latest`)
18+
- `target` - Optional: `cp-only` for control plane, `api-only` for API, or `standalone` (default)
19+
20+
**Environment Variables:**
21+
- `GROQ_API_KEY` - Required for API/standalone images
22+
- `HINDSIGHT_API_LLM_PROVIDER` - LLM provider (default: `groq`)
23+
- `HINDSIGHT_API_LLM_MODEL` - LLM model (default: `llama-3.3-70b-versatile`)
24+
- `HINDSIGHT_API_EMBEDDINGS_PROVIDER` - Embeddings provider (for slim images)
25+
- `HINDSIGHT_API_EMBEDDINGS_OPENAI_API_KEY` - OpenAI API key for embeddings
26+
- `HINDSIGHT_API_RERANKER_PROVIDER` - Reranker provider (for slim images)
27+
- `HINDSIGHT_API_COHERE_API_KEY` - Cohere API key for reranking
28+
- `SMOKE_TEST_TIMEOUT` - Timeout in seconds (default: 120)
29+
30+
**Examples:**
31+
32+
Test a full image (with local ML models):
33+
```bash
34+
export GROQ_API_KEY=gsk_xxx
35+
./docker/test-image.sh hindsight:test
36+
```
37+
38+
Test a slim image (with external providers):
39+
```bash
40+
export GROQ_API_KEY=gsk_xxx
41+
export HINDSIGHT_API_EMBEDDINGS_PROVIDER=openai
42+
export HINDSIGHT_API_EMBEDDINGS_OPENAI_API_KEY=sk-xxx
43+
export HINDSIGHT_API_RERANKER_PROVIDER=cohere
44+
export HINDSIGHT_API_COHERE_API_KEY=xxx
45+
./docker/test-image.sh hindsight-slim:test
46+
```
47+
48+
### `test-slim-local.sh`
49+
50+
Convenience wrapper for testing slim images locally. Automatically configures external providers.
51+
52+
**Usage:**
53+
```bash
54+
# Set API keys
55+
export GROQ_API_KEY=gsk_xxx
56+
export OPENAI_API_KEY=sk-xxx
57+
export COHERE_API_KEY=xxx
58+
59+
# Run test
60+
./docker/test-slim-local.sh [image]
61+
```
62+
63+
**Or inline:**
64+
```bash
65+
GROQ_API_KEY=gsk_xxx \
66+
OPENAI_API_KEY=sk-xxx \
67+
COHERE_API_KEY=xxx \
68+
./docker/test-slim-local.sh hindsight-slim:test
69+
```
70+
71+
This script:
72+
- ✅ Validates API keys are set
73+
- ✅ Configures OpenAI embeddings automatically
74+
- ✅ Configures Cohere reranking automatically
75+
- ✅ Calls `test-image.sh` with the right configuration
76+
77+
## Building and Testing Locally
78+
79+
### Build a slim image
80+
81+
```bash
82+
docker build \
83+
--build-arg INCLUDE_LOCAL_MODELS=false \
84+
--build-arg PRELOAD_ML_MODELS=false \
85+
--target standalone \
86+
-t hindsight-slim:test \
87+
-f docker/standalone/Dockerfile \
88+
.
89+
```
90+
91+
### Test the slim image
92+
93+
```bash
94+
# With API keys
95+
export GROQ_API_KEY=gsk_xxx
96+
export OPENAI_API_KEY=sk-xxx
97+
export COHERE_API_KEY=xxx
98+
99+
# Run test
100+
./docker/test-slim-local.sh hindsight-slim:test
101+
```
102+
103+
## Expected Output
104+
105+
**Successful test:**
106+
```
107+
Starting smoke test for: hindsight-slim:test
108+
Target: standalone
109+
Health endpoint: http://localhost:8888/health
110+
Timeout: 120s
111+
112+
Starting container...
113+
Waiting for health endpoint at http://localhost:8888/health...
114+
Still waiting... (10s)
115+
Still waiting... (20s)
116+
117+
Container is healthy after 25s
118+
119+
=== Health Response ===
120+
{
121+
"status": "healthy",
122+
"database": "connected"
123+
}
124+
125+
Smoke test PASSED
126+
```
127+
128+
## CI Integration
129+
130+
These scripts are used in CI to validate Docker images on every PR:
131+
132+
- `.github/workflows/test.yml` - Runs `test-image.sh` for slim variants with OpenAI/Cohere
133+
- `.github/workflows/release.yml` - Can optionally run smoke tests during release
134+
135+
See the workflows for the exact configuration.
Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,40 @@
66
# Can be run locally or in CI pipelines.
77
#
88
# Usage:
9-
# ./scripts/docker-smoke-test.sh <image> [target]
9+
# ./docker/test-image.sh <image> [target]
1010
#
1111
# Arguments:
1212
# image - Docker image to test (e.g., hindsight-api:test, ghcr.io/vectorize-io/hindsight:latest)
1313
# target - Optional: 'cp-only' for control plane, otherwise assumes API image (default: api)
1414
#
1515
# Environment variables:
16-
# GROQ_API_KEY - Required for API/standalone images (LLM verification)
17-
# HINDSIGHT_API_LLM_PROVIDER - LLM provider (default: groq)
18-
# HINDSIGHT_API_LLM_MODEL - LLM model (default: llama-3.3-70b-versatile)
19-
# SMOKE_TEST_TIMEOUT - Timeout in seconds (default: 120)
20-
# SMOKE_TEST_CONTAINER_NAME - Container name (default: hindsight-smoke-test)
16+
# GROQ_API_KEY - Required for API/standalone images (LLM verification)
17+
# HINDSIGHT_API_LLM_PROVIDER - LLM provider (default: groq)
18+
# HINDSIGHT_API_LLM_MODEL - LLM model (default: llama-3.3-70b-versatile)
19+
# HINDSIGHT_API_EMBEDDINGS_PROVIDER - Embeddings provider (optional, for slim images: openai, cohere, tei)
20+
# HINDSIGHT_API_EMBEDDINGS_OPENAI_API_KEY - OpenAI API key for embeddings (optional)
21+
# HINDSIGHT_API_RERANKER_PROVIDER - Reranker provider (optional, for slim images: cohere, tei)
22+
# HINDSIGHT_API_COHERE_API_KEY - Cohere API key for reranking (optional)
23+
# SMOKE_TEST_TIMEOUT - Timeout in seconds (default: 120)
24+
# SMOKE_TEST_CONTAINER_NAME - Container name (default: hindsight-smoke-test)
2125
#
2226
# Examples:
23-
# # Test a locally built image
24-
# ./scripts/docker-smoke-test.sh hindsight-api:test
27+
# # Test a locally built full image
28+
# ./docker/test-image.sh hindsight-api:test
2529
#
2630
# # Test a released image
27-
# ./scripts/docker-smoke-test.sh ghcr.io/vectorize-io/hindsight:latest
31+
# ./docker/test-image.sh ghcr.io/vectorize-io/hindsight:latest
2832
#
2933
# # Test control plane image
30-
# ./scripts/docker-smoke-test.sh hindsight-control-plane:test cp-only
34+
# ./docker/test-image.sh hindsight-control-plane:test cp-only
35+
#
36+
# # Test slim image with external providers
37+
# export GROQ_API_KEY=gsk_xxx
38+
# export HINDSIGHT_API_EMBEDDINGS_PROVIDER=openai
39+
# export HINDSIGHT_API_EMBEDDINGS_OPENAI_API_KEY=sk-xxx
40+
# export HINDSIGHT_API_RERANKER_PROVIDER=cohere
41+
# export HINDSIGHT_API_COHERE_API_KEY=xxx
42+
# ./docker/test-image.sh hindsight-slim:test
3143
#
3244
# Exit codes:
3345
# 0 - Success (container healthy)
@@ -108,12 +120,32 @@ if [ "$TARGET" = "cp-only" ]; then
108120
-p "${HEALTH_PORT}:${HEALTH_PORT}" \
109121
"$IMAGE"
110122
else
111-
docker run -d --name "$CONTAINER_NAME" \
112-
-e HINDSIGHT_API_LLM_PROVIDER="$LLM_PROVIDER" \
113-
-e HINDSIGHT_API_LLM_API_KEY="${GROQ_API_KEY}" \
114-
-e HINDSIGHT_API_LLM_MODEL="$LLM_MODEL" \
115-
-p "${HEALTH_PORT}:${HEALTH_PORT}" \
116-
"$IMAGE"
123+
# Build docker run command with required and optional env vars
124+
DOCKER_CMD="docker run -d --name $CONTAINER_NAME"
125+
DOCKER_CMD="$DOCKER_CMD -e HINDSIGHT_API_LLM_PROVIDER=$LLM_PROVIDER"
126+
DOCKER_CMD="$DOCKER_CMD -e HINDSIGHT_API_LLM_API_KEY=${GROQ_API_KEY}"
127+
DOCKER_CMD="$DOCKER_CMD -e HINDSIGHT_API_LLM_MODEL=$LLM_MODEL"
128+
129+
# Add optional embeddings provider config
130+
if [ -n "${HINDSIGHT_API_EMBEDDINGS_PROVIDER:-}" ]; then
131+
DOCKER_CMD="$DOCKER_CMD -e HINDSIGHT_API_EMBEDDINGS_PROVIDER=${HINDSIGHT_API_EMBEDDINGS_PROVIDER}"
132+
fi
133+
if [ -n "${HINDSIGHT_API_EMBEDDINGS_OPENAI_API_KEY:-}" ]; then
134+
DOCKER_CMD="$DOCKER_CMD -e HINDSIGHT_API_EMBEDDINGS_OPENAI_API_KEY=${HINDSIGHT_API_EMBEDDINGS_OPENAI_API_KEY}"
135+
fi
136+
137+
# Add optional reranker provider config
138+
if [ -n "${HINDSIGHT_API_RERANKER_PROVIDER:-}" ]; then
139+
DOCKER_CMD="$DOCKER_CMD -e HINDSIGHT_API_RERANKER_PROVIDER=${HINDSIGHT_API_RERANKER_PROVIDER}"
140+
fi
141+
if [ -n "${HINDSIGHT_API_COHERE_API_KEY:-}" ]; then
142+
DOCKER_CMD="$DOCKER_CMD -e HINDSIGHT_API_COHERE_API_KEY=${HINDSIGHT_API_COHERE_API_KEY}"
143+
fi
144+
145+
DOCKER_CMD="$DOCKER_CMD -p ${HEALTH_PORT}:${HEALTH_PORT}"
146+
DOCKER_CMD="$DOCKER_CMD $IMAGE"
147+
148+
eval $DOCKER_CMD
117149
fi
118150

119151
# Wait for health endpoint

0 commit comments

Comments
 (0)