build: containerize the server and publish to GHCR#22
Conversation
Ship the Spring Boot gateway (REST + MCP) as a container image so it can be run next to a user's data with no Java toolchain — the self-host distribution channel: `docker run -v <csvs>:/cuckoodb/data -p 8080:8080 ghcr.io/jinba1/cuckoodb` and point an MCP client at /mcp. - multi-stage Dockerfile: build the server fat jar (+ engine) on a JDK image with a BuildKit cache mount for the Maven repo, then run it on a slim JRE as a non-root user. data-dir defaults to /cuckoodb (CSVs mount at /cuckoodb/data); uploads, when enabled, persist under /cuckoodb/work - .dockerignore keeps the build context small and excludes internal/dev material - docker-publish workflow builds on every PR (validation, no push) and publishes to ghcr.io/<owner>/cuckoodb on pushes to main and version tags, tagged via docker/metadata-action (branch, tag, sha, latest-on-main) - README: a "Run the server as a container" section with the mount + REST/MCP endpoints Verify by building and running the image: GET /tables loads the mounted CSVs, POST /queries returns typed rows, /mcp registers the five tools, and the app runs as a non-root user on port 8080.
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
@claude review this PR |
|
Claude finished @JinBa1's task in 2m 46s —— View job PR Review: build: containerize the server and publish to GHCR
Overall this is a clean, well-thought-out PR. The multi-stage build, non-root runtime user, BuildKit cache mounts, and pinned workflow action versions are all correct. One actionable issue and a few minor suggestions below. Issues[Medium] GHCR login runs on fork PRs — will fail
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}For PRs opened from forks, GitHub restricts the - name: Log in to GHCR
if: github.event_name != 'pull_request' # ← add this
uses: docker/login-action@v3Since push is already gated with Suggestions[Minor] No HEALTHCHECK in Dockerfile Without a HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
CMD curl -sf http://localhost:8080/tables || exit 1Note: [Minor] JVM memory configuration undocumented Java 17 respects cgroup memory limits by default ( docker run -e JAVA_TOOL_OPTIONS="-Xmx512m" ... ghcr.io/jinba1/cuckoodb:latestNo Dockerfile change needed; it's a documentation gap. [Nitpick] Floating base image tags
FROM eclipse-temurin:17-jdk@sha256:<digest> AS build
FROM eclipse-temurin:17-jre@sha256:<digest> AS runtimeThis is a supply-chain hygiene point; the risk is low given the trusted upstream. The What looks good
|
Login is only needed to push; gate it on non-PR events so fork PRs (where GITHUB_TOKEN is read-only) run the build-validation path without it. Push is already gated the same way, so the build-only PR path needs no credentials.
|
Thanks for the review. Dispositions:
Everything else (multi-stage, non-root, cache mounts, env binding, minimal permissions) confirmed good. |
Ships the Spring Boot gateway (REST + MCP) as a container image — the self-host distribution channel: run the gateway next to your CSVs with no Java toolchain, and point an MCP client at it.
docker run --rm -p 8080:8080 -v /path/to/your/csvs:/cuckoodb/data ghcr.io/jinba1/cuckoodb:latest # REST: http://localhost:8080/queries · MCP: http://localhost:8080/mcpWhat's here
Dockerfile— build the server fat jar (+ engine) on a JDK image with a BuildKit cache mount for the Maven repo; run on a slim JRE as a non-root user.data-dirdefaults to/cuckoodb(CSVs mount at/cuckoodb/data); uploads (when enabled) persist under/cuckoodb/work..dockerignore— small build context; excludestarget/,.git, and internal/dev material.docker-publish.yml— builds on every PR (validation, no push) and publishes toghcr.io/<owner>/cuckoodbon pushes tomainandv*tags, tagged viadocker/metadata-action(branch, tag, sha,lateston main).Verification (built + ran locally)
docker buildsucceeds;docker runwith a mounted CSV folder:GET /tables→["People"](the env-bounddata-dirloads the mounted CSVs)POST /queries→ typed columns/rows/mcpmounted, "Registered tools: 5" in logsNotes
main; until then,docker build -t cuckoodb .builds locally.