diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..e43cd8f --- /dev/null +++ b/.dockerignore @@ -0,0 +1,44 @@ +# Version control +.git +.gitignore + +# Build artifacts +dist/ +bin/ +claws +claws-codegen +*.exe +*.test +*.out + +# IDE / editor +.idea/ +.vscode/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db + +# CI / config +.github/ +CLAUDE.md +AGENTS.md +.claude/ + +# Local env +.env +.env.local +.gtrconfig + +# Docs & scripts +docs/ +scripts/localstack-* +node_modules/ +.lsmcp/ + +# Docker +Dockerfile +.dockerignore diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..a375700 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,52 @@ +name: Docker + +on: + push: + branches: [main] + tags: ['v*'] + pull_request: + branches: [main] + +permissions: + contents: read + packages: write + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - uses: docker/setup-buildx-action@v3 + + - name: Log in to GHCR + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ github.repository }} + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=sha,prefix= + type=raw,value=latest,enable={{is_default_branch}} + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + push: ${{ github.event_name != 'pull_request' }} + platforms: linux/amd64,linux/arm64 + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + build-args: | + VERSION=${{ steps.meta.outputs.version }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..028e873 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,32 @@ +# syntax=docker/dockerfile:1 + +# ---- Build stage ---- +FROM --platform=$BUILDPLATFORM golang:1.25-alpine AS build + +WORKDIR /src + +COPY go.mod go.sum ./ +RUN go mod download + +COPY . . + +ARG VERSION=dev +ARG TARGETOS TARGETARCH + +RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build \ + -ldflags="-s -w -X main.version=${VERSION}" \ + -o /claws ./cmd/claws + +# ---- Runtime stage ---- +FROM alpine:3.21 + +# CA certs for AWS API TLS, and tzdata for time zone support +RUN apk add --no-cache ca-certificates tzdata + +COPY --from=build /claws /usr/local/bin/claws + +RUN adduser -D -h /home/claws claws +USER claws +WORKDIR /home/claws + +ENTRYPOINT ["claws"]