怎么样通过github actions构建镜像并推送到dokploy
2025/10/16

怎么样通过github actions构建镜像并推送到dokploy

本文介绍怎么样通过github actions构建镜像并推送dokploy。

一.新建GitHub Token用于访问Docker Registry

1.打开 https://github.com/settings/tokens ,点击右上角 "Generate new token (classic)" 按钮

Generate new token (classic)

2.输入Token名称,选择权限,点击 "Generate token" 按钮

Generate new token (classic)

3.复制生成的Token,下一步会用到

二.在dokploy中配置Docker Registry

1.打开dokploy dashboard,点击左侧菜单 "Registry" 按钮

Settings

2.点击 "Docker Registry" 菜单,点击 "Add Registry" 按钮

Add Registry

  • Registry Name:随便填
  • Username:GitHub 用户名
  • Password:上一步生成的 Token
  • Registry URL:https://ghcr.io

三.在dokploy中新建项目

1.新建项目,如图,一定要选 Application

Create Application

2.修改 Cluster Settings

Cluster Settings

  • 打开新建的项目,点击 Advanced
  • 在Cluster Settings中,选择在第二步中配置的 Github Docker Registry

3.配置 Docker Image

Docker Image

  • Docker Image:ghcr.io/[Github账号名]/[Repository项目名]:[分支名],一般是main分支,比如:ghcr.io/robinwm/nano-ai-nextjs:main

四.配置Environment Secret

1.在github项目仓库下的 Settings的tab下设置环境变量

Environments

2.点击 Add environment secret,需要设置两个name分别为 ENV_PRODUCTION 和DOKPLOY_DEPLOY_URL的变量

Docker Image

  • ENV_PRODUCTION:直接把项目中的 .env文件的值复制进去
  • DOKPLOY_DEPLOY_URL:打开第三步中新建的项目,在 Deployments的tab下获取值 Deployments Webhook URL

五.创建 GitHub Actions 工作流

1.在项目根目录下创建 .github/workflows/deploy-push-dokploy.yml 文件,文件内容如下:

# https://docs.github.com/zh/actions/use-cases-and-examples/publishing-packages/publishing-docker-images
name: Deploy and push a Docker image to Dokploy

# Configures this workflow to run every time a change is pushed to the branch called `release`.
on:
  workflow_dispatch:
  push:
    branches: ["main"]

# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds.
env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu.
jobs:
  build-and-push-image:
    runs-on: ubuntu-latest
    environment: Production
    # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
    permissions:
      contents: read
      packages: write
      attestations: write
      id-token: write
    steps:
      # 1. Checkout the repository so the workflow can access the source code
      - name: Checkout code
        uses: actions/checkout@v4
      # 2. Configure Docker Buildx for efficient builds and multi-platform support
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      # 3. Authenticate to GitHub Container Registry (GHCR) using the GitHub token
      - name: Log in to GHCR
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      # 4. Derive image tags and labels from Git context (branch, SHA, etc.)
      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
      # 5. Create the .env.production file from repository secret for build-time env vars
      - name: Create env file
        run: |
          echo "${{ secrets.ENV_PRODUCTION }}" > .env.production
      # 6. Build the Docker image and push it to GHCR with computed tags and labels
      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
      # 7. Trigger Dokploy to redeploy the service using the newly pushed image
      - name: Trigger dokploy redeploy
        run: |
          curl -X POST "${{ secrets.DOKPLOY_DEPLOY_URL }}"

2.在项目根目录下创建 Dockerfile文件,文件内容如下:

# syntax=docker/dockerfile:1
FROM node:20-alpine AS base

# Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app

# Install dependencies
COPY package.json pnpm-lock.yaml* ./
# Copy config files needed for fumadocs-mdx postinstall
COPY source.config.ts ./
COPY content ./content
RUN npm install -g pnpm && pnpm i --frozen-lockfile

# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry during the build.
# ENV NEXT_TELEMETRY_DISABLED 1

RUN npm install -g pnpm \
  && DOCKER_BUILD=true pnpm build

RUN find . -name ".env*" -delete

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ENV NODE_ENV=production
# Uncomment the following line in case you want to disable telemetry during runtime.
# ENV NEXT_TELEMETRY_DISABLED 1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public

# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown nextjs:nodejs .next

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000

ENV PORT=3000
ENV HOSTNAME="0.0.0.0"

# server.js is created by next build from the standalone output
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
CMD ["node", "server.js"]

3.在dokploy的项目下配置运行时环境变量

Dokploy Project Runtime Environment

4.提交代码,github actions会自动运行

Github Actions

六.总结

  1. RUN find . -name ".env*" -delete,这条命令可以确保我们的key在最终的镜像不被暴漏
  2. 在dokploy的项目下配置运行时环境变量,这一步是必须的步骤,可以直接将 .env 文件的内容复制进去保存