diff --git a/.gitignore b/.gitignore index 3ff195fbf..38055e7e7 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,5 @@ tasks/ # Added by goreleaser init: dist/ + +vendor/ diff --git a/docker/Dockerfile b/docker/Dockerfile index 480244127..3755595f7 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,9 +1,13 @@ # ============================================================ # Stage 1: Build the picoclaw binary # ============================================================ -FROM golang:1.25-alpine AS builder +FROM golang:1.25.7-alpine3.23@sha256:f6751d823c26342f9506c03797d2527668d095b0a15f1862cddb4d927a7a4ced AS builder -RUN apk add --no-cache git make +RUN apk add --no-cache git make ca-certificates \ + && addgroup -S picoclaw \ + && adduser --uid 1000 --shell /bin/false -S picoclaw -G picoclaw \ + && grep picoclaw /etc/passwd > /etc/passwd_picoclaw \ + && grep picoclaw /etc/group > /etc/group_picoclaw WORKDIR /src @@ -18,26 +22,32 @@ RUN make build # ============================================================ # Stage 2: Minimal runtime image # ============================================================ -FROM alpine:3.23 +FROM alpine:3.23@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659 -RUN apk add --no-cache ca-certificates tzdata curl +RUN apk add --no-cache tzdata + +COPY --from=builder /etc/passwd_picoclaw /etc/passwd +COPY --from=builder /etc/group_picoclaw /etc/group +COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt + +RUN mkdir -p /home/picoclaw && chown picoclaw:picoclaw /home/picoclaw # Health check +# BusyBox (Alpine default) already provides wget, no extra package needed +# Consider replacing with application-level health command in the future. HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD wget -q --spider http://localhost:18790/health || exit 1 # Copy binary -COPY --from=builder /src/build/picoclaw /usr/local/bin/picoclaw - -# Create non-root user and group -RUN addgroup -g 1000 picoclaw && \ - adduser -D -u 1000 -G picoclaw picoclaw +COPY --from=builder --chown=picoclaw:picoclaw /src/build/picoclaw /usr/local/bin/picoclaw # Switch to non-root user USER picoclaw +ENV HOME=/home/picoclaw # Run onboard to create initial directories and config RUN /usr/local/bin/picoclaw onboard ENTRYPOINT ["picoclaw"] + CMD ["gateway"] diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 9ec71abab..937b8601b 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -12,7 +12,8 @@ services: #extra_hosts: # - "host.docker.internal:host-gateway" volumes: - - ./data:/root/.picoclaw + - "${PICOCLAW_CONFIG_FILE:-./config/config.json}:/home/picoclaw/.picoclaw/config.json:ro" + - picoclaw-workspace:/home/picoclaw/.picoclaw/workspace entrypoint: ["picoclaw", "agent"] stdin_open: true tty: true @@ -22,7 +23,7 @@ services: # docker compose -f docker/docker-compose.yml up picoclaw-gateway # ───────────────────────────────────────────── picoclaw-gateway: - image: docker.io/sipeed/picoclaw:latest + image: "docker.io/sipeed/picoclaw:${PICOCLAW_IMAGE_VERSION:-latest}" container_name: picoclaw-gateway restart: on-failure profiles: @@ -31,4 +32,11 @@ services: #extra_hosts: # - "host.docker.internal:host-gateway" volumes: - - ./data:/root/.picoclaw + # Configuration file + - "${PICOCLAW_CONFIG_FILE:-./config/config.json}:/home/picoclaw/.picoclaw/config.json:ro" + # Persistent workspace (sessions, memory, logs) + - picoclaw-workspace:/home/picoclaw/.picoclaw/workspace + command: ["gateway"] + +volumes: + picoclaw-workspace: