From fbf788513108a72493c77fd2e9fbc43d42f89d2c Mon Sep 17 00:00:00 2001 From: xyzm Date: Tue, 10 Feb 2026 19:57:51 +0800 Subject: [PATCH] =?UTF-8?q?build:=20=E5=88=86=E7=A6=BB=E5=BC=80=E5=8F=91?= =?UTF-8?q?=E4=B8=8E=E5=8F=91=E5=B8=83=E7=8E=AF=E5=A2=83=E7=9A=84=20Docker?= =?UTF-8?q?=20=E6=9E=84=E5=BB=BA=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 Dockerfile.release 用于生产环境,仅包含运行所需的最小依赖 - 重构原 Dockerfile 为多阶段构建,集成前端构建与后端编译 - 更新 .goreleaser.yaml 以使用新的发布镜像配置 - 新增 GitHub Actions 工作流用于自动构建和推送 Docker 镜像 --- .github/workflows/docker-build.yml | 62 ++++++++++++++++++++++++++++ .goreleaser.yaml | 6 +-- Dockerfile | 66 ++++++++++++++++++++++++++---- Dockerfile.release | 16 ++++++++ 4 files changed, 138 insertions(+), 12 deletions(-) create mode 100644 .github/workflows/docker-build.yml create mode 100644 Dockerfile.release diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 0000000..155986e --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,62 @@ +name: Docker Build and Push + +on: + push: + branches: [ "main", "master" ] + paths-ignore: + - 'docs/**' + - '**.md' + pull_request: + branches: [ "main", "master" ] + paths-ignore: + - 'docs/**' + - '**.md' + +env: + REGISTRY: ghcr.io + # Use message-nest to match release workflow naming, or use ${{ github.repository }} for default + IMAGE_NAME: message-nest + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to the Container registry + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' }} + type=ref,event=branch + type=ref,event=pr + type=sha + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 2268922..81b41fa 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -37,7 +37,7 @@ dockers: - image_templates: - "docker.io/engigu/{{ .Env.DOCKER_IMAGE_NAME }}:{{ .Version }}-amd64" - "ghcr.io/engigu/{{ .Env.DOCKER_IMAGE_NAME }}:{{ .Version }}-amd64" - dockerfile: Dockerfile + dockerfile: Dockerfile.release extra_files: - LICENSE - README.md @@ -56,7 +56,7 @@ dockers: - "docker.io/engigu/{{ .Env.DOCKER_IMAGE_NAME }}:{{ .Version }}-arm64v8" - "ghcr.io/engigu/{{ .Env.DOCKER_IMAGE_NAME }}:{{ .Version }}-arm64v8" goarch: arm64 - dockerfile: Dockerfile + dockerfile: Dockerfile.release extra_files: - LICENSE - README.md @@ -76,7 +76,7 @@ dockers: - "ghcr.io/engigu/{{ .Env.DOCKER_IMAGE_NAME }}:{{ .Version }}-armv7" goarch: arm goarm: 7 - dockerfile: Dockerfile + dockerfile: Dockerfile.release extra_files: - LICENSE - README.md diff --git a/Dockerfile b/Dockerfile index 51f6fa3..c6165bd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,64 @@ -FROM debian:latest +# Stage 1: Build Frontend +FROM node:20-alpine AS frontend-builder + +WORKDIR /web + +# Copy package files first for caching +COPY web/package*.json ./ +COPY web/tsconfig*.json ./ +COPY web/vite.config.ts ./ +COPY web/index.html ./ + +# Install dependencies +RUN npm install + +# Copy source code +COPY web/ ./ + +# Build frontend +RUN npm run build + +# Stage 2: Build Backend +FROM golang:1.24 AS backend-builder + +WORKDIR /app + +# Copy Go module files +COPY go.mod go.sum ./ +RUN go mod download + +# Copy source code +COPY . . + +# Copy frontend build artifacts to the location expected by go:embed +# The embed directive in main.go is //go:embed web/dist/* +COPY --from=frontend-builder /web/dist ./web/dist + +# Build the binary +# CGO_ENABLED=0 for static binary +RUN CGO_ENABLED=0 GOOS=linux go build -o Message-Nest main.go + +# Stage 3: Runtime +FROM debian:stable-slim ENV TZ=Asia/Shanghai -RUN apt update \ - && apt install -y ca-certificates \ - && update-ca-certificates \ - && rm -rf /var/lib/apt/lists/* - -COPY ./ /app/ +RUN apt-get update \ + && apt-get install -y ca-certificates tzdata \ + && rm -rf /var/lib/apt/lists/* WORKDIR /app + +# Copy binary +COPY --from=backend-builder /app/Message-Nest . + +# Copy configuration directory (contains app.example.ini) +COPY --from=backend-builder /app/conf ./conf + +# Copy other necessary files +COPY --from=backend-builder /app/LICENSE . +COPY --from=backend-builder /app/README.md . + EXPOSE 8000 -CMD ["/app/Message-Nest"] - +CMD ["./Message-Nest"] diff --git a/Dockerfile.release b/Dockerfile.release new file mode 100644 index 0000000..51f6fa3 --- /dev/null +++ b/Dockerfile.release @@ -0,0 +1,16 @@ +FROM debian:latest + +ENV TZ=Asia/Shanghai + +RUN apt update \ + && apt install -y ca-certificates \ + && update-ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +COPY ./ /app/ + +WORKDIR /app +EXPOSE 8000 + +CMD ["/app/Message-Nest"] +