From 83bd830360e7065c744e3eabd2cda19e938d3c77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=BE=E6=96=87=E9=94=8B0668000834?= Date: Thu, 12 Mar 2026 20:55:26 +0800 Subject: [PATCH] fix(docker): add launcher image build configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add picoclaw-launcher Docker image build to .goreleaser.yaml - Create Dockerfile.launcher for standalone launcher builds - Create Dockerfile.launcher.goreleaser for GoReleaser builds - Create entrypoint-launcher.sh for launcher container entrypoint - Add picoclaw-launcher service to docker-compose.yml with launcher profile Fixes #1350: launcher docker镜像manifest不可用 --- .goreleaser.yaml | 17 ++++++++++ docker/Dockerfile.launcher | 47 +++++++++++++++++++++++++++ docker/Dockerfile.launcher.goreleaser | 14 ++++++++ docker/docker-compose.yml | 20 ++++++++++++ docker/entrypoint-launcher.sh | 15 +++++++++ 5 files changed, 113 insertions(+) create mode 100644 docker/Dockerfile.launcher create mode 100644 docker/Dockerfile.launcher.goreleaser create mode 100644 docker/entrypoint-launcher.sh diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 654ad6ae6..aa9c50407 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -125,6 +125,23 @@ dockers_v2: - linux/arm64 - linux/riscv64 + - id: picoclaw-launcher + dockerfile: docker/Dockerfile.launcher.goreleaser + extra_files: + - docker/entrypoint-launcher.sh + ids: + - picoclaw-launcher + images: + - "ghcr.io/{{ .Env.GITHUB_REPOSITORY_OWNER }}/picoclaw" + - '{{ if not (isEnvSet "NIGHTLY_BUILD") }}docker.io/{{ .Env.DOCKERHUB_IMAGE_NAME }}{{ end }}' + tags: + - "launcher-{{ .Tag }}" + - '{{ if isEnvSet "NIGHTLY_BUILD" }}launcher-nightly{{ else }}launcher{{ end }}' + platforms: + - linux/amd64 + - linux/arm64 + - linux/riscv64 + notarize: macos: - enabled: '{{ isEnvSet "MACOS_SIGN_P12" }}' diff --git a/docker/Dockerfile.launcher b/docker/Dockerfile.launcher new file mode 100644 index 000000000..46cb17618 --- /dev/null +++ b/docker/Dockerfile.launcher @@ -0,0 +1,47 @@ +# ============================================================ +# Stage 1: Build the picoclaw-launcher binary +# ============================================================ +FROM golang:1.25-alpine AS builder + +RUN apk add --no-cache git make + +WORKDIR /src + +# Cache dependencies +COPY go.mod go.sum ./ +RUN go mod download + +# Copy source and build +COPY . . +RUN make build-launcher + +# ============================================================ +# Stage 2: Minimal runtime image for launcher +# ============================================================ +FROM alpine:3.23 + +RUN apk add --no-cache ca-certificates tzdata curl + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD wget -q --spider http://localhost:8080/health || exit 1 + +# Copy binary +COPY --from=builder /src/build/picoclaw-launcher /usr/local/bin/picoclaw-launcher + +# Create non-root user and group +RUN addgroup -g 1000 picoclaw && \ + adduser -D -u 1000 -G picoclaw picoclaw + +# Create picoclaw home directory +RUN mkdir -p /home/picoclaw/.picoclaw && \ + chown -R picoclaw:picoclaw /home/picoclaw + +# Switch to non-root user +USER picoclaw + +ENV HOME=/home/picoclaw + +EXPOSE 8080 + +ENTRYPOINT ["picoclaw-launcher"] diff --git a/docker/Dockerfile.launcher.goreleaser b/docker/Dockerfile.launcher.goreleaser new file mode 100644 index 000000000..c43543193 --- /dev/null +++ b/docker/Dockerfile.launcher.goreleaser @@ -0,0 +1,14 @@ +FROM alpine:3.21 + +ARG TARGETPLATFORM + +RUN apk add --no-cache ca-certificates tzdata curl + +COPY $TARGETPLATFORM/picoclaw-launcher /usr/local/bin/picoclaw-launcher +COPY docker/entrypoint-launcher.sh /entrypoint.sh + +RUN chmod +x /entrypoint.sh + +EXPOSE 8080 + +ENTRYPOINT ["/entrypoint.sh"] diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 9ec71abab..33f5a9140 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -32,3 +32,23 @@ services: # - "host.docker.internal:host-gateway" volumes: - ./data:/root/.picoclaw + + # ───────────────────────────────────────────── + # PicoClaw Launcher (Web Console) + # docker compose -f docker/docker-compose.yml --profile launcher up picoclaw-launcher + # ───────────────────────────────────────────── + picoclaw-launcher: + image: docker.io/sipeed/picoclaw:launcher + container_name: picoclaw-launcher + restart: on-failure + profiles: + - launcher + ports: + - "8080:8080" + # Uncomment to access host network; leave commented unless needed. + #extra_hosts: + # - "host.docker.internal:host-gateway" + volumes: + - ./data:/home/picoclaw/.picoclaw + environment: + - PICOCLAW_HOME=/home/picoclaw/.picoclaw diff --git a/docker/entrypoint-launcher.sh b/docker/entrypoint-launcher.sh new file mode 100644 index 000000000..1c563f25e --- /dev/null +++ b/docker/entrypoint-launcher.sh @@ -0,0 +1,15 @@ +#!/bin/sh +set -e + +# First-run: neither config nor workspace exists. +# If config.json is already mounted but workspace is missing we skip onboard to +# avoid the interactive "Overwrite? (y/n)" prompt hanging in a non-TTY container. +if [ ! -d "${HOME}/.picoclaw/workspace" ] && [ ! -f "${HOME}/.picoclaw/config.json" ]; then + picoclaw-launcher onboard + echo "" + echo "First-run setup complete." + echo "Edit ${HOME}/.picoclaw/config.json (add your API key, etc.) then restart the container." + exit 0 +fi + +exec picoclaw-launcher "$@"