diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 8526801..6e6ccec 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -2,6 +2,9 @@ name: Docker on: push: + # `main` is the release branch: pushes here publish the released image and + # update `latest`; `v*` tags publish versioned images. develop does not + # publish — it is validated via the pull_request trigger below. branches: [main] tags: ["v*"] pull_request: @@ -21,6 +24,10 @@ jobs: steps: - uses: actions/checkout@v6 + # Needed for the emulated linux/arm64 build on real pushes. + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -40,22 +47,49 @@ jobs: uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - # latest -> default branch; semver tags -> released versions. + # latest -> main (the latest release); semver tags -> released versions. tags: | type=ref,event=branch type=ref,event=pr type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} - type=raw,value=latest,enable={{is_default_branch}} + type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }} - name: Build and push uses: docker/build-push-action@v6 with: context: . file: ./Dockerfile - platforms: linux/amd64 + # Publish multi-arch (amd64 + arm64 for Apple Silicon / ARM hosts) on + # real pushes; keep PRs amd64-only so the emulated arm64 build does not + # slow the PR check. + platforms: ${{ github.event_name != 'pull_request' && 'linux/amd64,linux/arm64' || 'linux/amd64' }} push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha - cache-to: type=gha,mode=max + # Fork PRs get a read-only Actions cache, so writing it just emits 403 + # noise — only export cache on in-repo events. + cache-to: ${{ github.event_name != 'pull_request' && 'type=gha,mode=max' || '' }} + + # Build-only validation for the CUDA image so it cannot silently rot (CUDA base + # tag drift, cross-stage interpreter/venv copy paths, the `gpu` extra). The + # runner has no GPU, so this only proves the image *compiles*; it is never + # published (users build it themselves, per the README). + build-gpu: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build GPU image (validation only — not published) + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile.gpu + platforms: linux/amd64 + push: false + cache-from: type=gha,scope=gpu + cache-to: ${{ github.event_name != 'pull_request' && 'type=gha,mode=max,scope=gpu' || '' }} diff --git a/Dockerfile b/Dockerfile index 7e61bbb..64013ea 100644 --- a/Dockerfile +++ b/Dockerfile @@ -73,9 +73,11 @@ LABEL org.opencontainers.image.title="MemPalace" \ org.opencontainers.image.licenses="MIT" # /data is the single persistence root: HOME points here, so the palace -# (~/.mempalace/palace), config (~/.mempalace), and the HuggingFace model -# cache (~/.cache/huggingface, ~300 MB, lazy-downloaded on first use) all -# land under one mountable volume. +# (~/.mempalace/palace), config (~/.mempalace), and the embedding-model cache +# all land under one mountable volume. The default `minilm` model caches under +# ~/.cache/chroma (~80 MB, from ChromaDB's S3); the optional `embeddinggemma` +# model caches under ~/.cache/huggingface (~300 MB). Both lazy-download on +# first use. ENV HOME=/data \ PATH="/app/.venv/bin:${PATH}" \ PYTHONUNBUFFERED=1 \ diff --git a/docker-compose.yml b/docker-compose.yml index cb6887f..1a9f53d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,9 +22,11 @@ services: volumes: - mempalace-data:/data environment: - # Override the palace location, embedding model, etc. here if needed. - # - MEMPALACE_EMBEDDING_MODEL=minilm - MEMPALACE_PALACE_PATH: /data/.mempalace/palace + # Everything defaults correctly from HOME=/data (palace -> + # /data/.mempalace/palace, config -> /data/.mempalace, model cache -> + # /data/.cache). Override here only for non-default locations, e.g.: + # - MEMPALACE_EMBEDDING_MODEL=embeddinggemma # multilingual (default: minilm) + # - MEMPALACE_PALACE_PATH=/data/custom/palace volumes: mempalace-data: