feat(release): publish supported Docker image

This commit is contained in:
Hunter Bown
2026-05-07 15:16:23 -05:00
parent 3f3395e00e
commit 8f181c80f8
4 changed files with 76 additions and 19 deletions
+31 -7
View File
@@ -139,10 +139,6 @@ jobs:
docker:
needs: build
if: ${{ !cancelled() && needs.build.result == 'success' }}
# Docker/GHCR is experimental and not a supported release channel yet.
# Keep binary GitHub Releases publishable while the arm64 image build path
# is hardened separately.
continue-on-error: true
runs-on: ubuntu-latest
permissions:
contents: read
@@ -159,17 +155,24 @@ jobs:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Normalize image name
id: image
shell: bash
run: echo "name=ghcr.io/${GITHUB_REPOSITORY,,}" >> "$GITHUB_OUTPUT"
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: |
ghcr.io/${{ github.repository }}
${{ steps.image.outputs.name }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern=v{{major}}
type=ref,event=tag
type=raw,value=${{ inputs.version }},enable=${{ github.event_name == 'workflow_dispatch' }}
type=raw,value=v${{ inputs.version }},enable=${{ github.event_name == 'workflow_dispatch' }}
type=raw,value=latest
- name: Build and push
uses: docker/build-push-action@v6
with:
@@ -182,8 +185,8 @@ jobs:
cache-to: type=gha,mode=max
release:
needs: build
if: ${{ !cancelled() && needs.build.result == 'success' }}
needs: [build, docker]
if: ${{ !cancelled() && needs.build.result == 'success' && needs.docker.result == 'success' }}
runs-on: ubuntu-latest
permissions:
contents: write
@@ -205,8 +208,18 @@ jobs:
printf '%s %s\n' "${hash}" "${base}" >> "${manifest}"
done < <(find artifacts -type f ! -path 'artifacts/checksums/*' -print0 | sort -z)
cat "${manifest}"
- name: Resolve release tag
id: release_tag
shell: bash
run: |
if [ "${GITHUB_EVENT_NAME}" = "workflow_dispatch" ]; then
echo "tag=v${{ inputs.version }}" >> "$GITHUB_OUTPUT"
else
echo "tag=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT"
fi
- uses: softprops/action-gh-release@v1
with:
tag_name: ${{ steps.release_tag.outputs.tag }}
files: artifacts/*/*
prerelease: false
body: |
@@ -220,6 +233,17 @@ jobs:
The wrapper downloads both binaries from this Release and places them in the same directory.
### Docker / GHCR
```bash
docker run --rm -it \
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
-v ~/.deepseek:/home/deepseek/.deepseek \
ghcr.io/hmbown/deepseek-tui:${{ steps.release_tag.outputs.tag }}
```
The image ships the `deepseek` dispatcher and `deepseek-tui` runtime. The `latest` tag is also updated on release.
### Cargo (Linux / macOS)
```bash
+4 -2
View File
@@ -18,6 +18,7 @@ ARG RUST_VERSION=1.88
# ── Stage 1: Build ────────────────────────────────────────────────────
FROM --platform=$BUILDPLATFORM rust:${RUST_VERSION}-slim-bookworm AS builder
ARG TARGETPLATFORM
ARG TARGETARCH
ARG BUILDPLATFORM
RUN apt-get update && apt-get install -y --no-install-recommends \
@@ -40,8 +41,9 @@ COPY . .
# Build both binaries for the target platform. --locked ensures
# reproducible builds from the committed lockfile.
RUN --mount=type=cache,target=/build/target \
--mount=type=cache,target=/usr/local/cargo/registry \
RUN --mount=type=cache,id=deepseek-tui-target-${TARGETARCH},target=/build/target,sharing=locked \
--mount=type=cache,id=deepseek-tui-cargo-registry-${TARGETARCH},target=/usr/local/cargo/registry,sharing=locked \
--mount=type=cache,id=deepseek-tui-cargo-git-${TARGETARCH},target=/usr/local/cargo/git,sharing=locked \
cargo build --release --locked --target "$(cat /rust-target)" \
&& mkdir -p /out \
&& cp target/$(cat /rust-target)/release/deepseek /out/ \
+9
View File
@@ -274,6 +274,15 @@ deepseek mcp-server # run dispatcher MCP stdio serv
deepseek update # check for and apply binary updates
```
Docker images are published to GHCR for release builds:
```bash
docker run --rm -it \
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
-v ~/.deepseek:/home/deepseek/.deepseek \
ghcr.io/hmbown/deepseek-tui:latest
```
### Zed / ACP
DeepSeek can run as a custom Agent Client Protocol server for editors that
+32 -10
View File
@@ -1,11 +1,33 @@
# Docker
Docker support is currently a local-build/devcontainer path, not a supported
release channel. The release workflow may try an experimental GHCR publish, but
no public `ghcr.io/hmbown/deepseek-tui` image should be treated as available
until this page says so.
DeepSeek-TUI publishes a multi-arch Linux image to GitHub Container Registry
for each release.
## Local quick start
```bash
docker pull ghcr.io/hmbown/deepseek-tui:latest
```
## Quick start
Run the published image with your existing config directory mounted:
```bash
docker run --rm -it \
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
-v ~/.deepseek:/home/deepseek/.deepseek \
ghcr.io/hmbown/deepseek-tui:latest
```
Use a pinned release tag for reproducible installs:
```bash
docker run --rm -it \
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
-v ~/.deepseek:/home/deepseek/.deepseek \
ghcr.io/hmbown/deepseek-tui:v0.8.18
```
## Local build
Build the image locally from a checkout:
@@ -22,7 +44,8 @@ docker run --rm -it \
deepseek-tui
```
Docker Hub publishing is not configured.
Docker Hub publishing is not configured; GHCR is the supported prebuilt image
registry.
## Environment variables
@@ -50,7 +73,7 @@ When stdin is not a TTY, `deepseek` drops to the dispatcher's one-shot mode
```bash
echo "Explain the Cargo.toml in structured English." | \
docker run --rm -i -e DEEPSEEK_API_KEY deepseek-tui
docker run --rm -i -e DEEPSEEK_API_KEY ghcr.io/hmbown/deepseek-tui:latest
```
## Building locally
@@ -73,6 +96,5 @@ ready-to-use development environment.
## Release status
Docker image publishing is experimental and non-blocking for releases. The
supported distribution channels are npm, Cargo, Homebrew, GitHub Release
assets, and Scoop's independently maintained main-bucket manifest.
Docker image publishing is part of the release gate. The image is published to
GHCR for `linux/amd64` and `linux/arm64` with semver tags plus `latest`.