How to Build Images and Push to Dokploy Using GitHub Actions
2025/10/16

How to Build Images and Push to Dokploy Using GitHub Actions

This article introduces how to build images and push to dokploy using GitHub Actions.

Create GitHub Token for Accessing Docker Registry

1. Open https://github.com/settings/tokens, click the "Generate new token (classic)" button in the top right corner

Generate new token (classic)

2. Enter Token name, select permissions, click the "Generate token" button

Generate new token (classic)

3. Copy the generated Token, it will be used in the next step

Configure Docker Registry in Dokploy

1. Open dokploy dashboard, click the "Registry" button in the left menu

Settings

2. Click the "Docker Registry" menu, click the "Add Registry" button

Add Registry

  • Registry Name: Fill in any name
  • Username: GitHub username
  • Password: Token generated in the previous step
  • Registry URL: https://ghcr.io

Create New Project in Dokploy

1. Create new project, as shown in the image, make sure to select Application

Create Application

2. Modify Cluster Settings

Cluster Settings

  • Open the newly created project, click Advanced
  • In Cluster Settings, select the Github Docker Registry configured in step 2

3. Configure Docker Image

Docker Image

  • Docker Image: ghcr.io/[Github account name]/[Repository project name]:[branch name], usually main branch, for example: ghcr.io/robinwm/nano-ai-nextjs:main

Configure Environment Secret

1. Set environment variables under the Settings tab of the github project repository

Environments

2. Click Add environment secret, need to set two variables with names ENV_PRODUCTION and DOKPLOY_DEPLOY_URL respectively

Docker Image

  • ENV_PRODUCTION: Copy the values from the .env file in the project directly
  • DOKPLOY_DEPLOY_URL: Open the project created in step 3, get the value under the Deployments tab Deployments Webhook URL

Create GitHub Actions Workflow

1. Create .github/workflows/deploy-push-dokploy.yml file in the project root directory, with the following content:

# 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. Create Dockerfile in the project root directory, with the following content:

# 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. Configure runtime environment variables in the dokploy project

Dokploy Project Runtime Environment

4. Commit the code, GitHub Actions will run automatically

Github Actions

Summary

  1. RUN find . -name ".env*" -delete, this command ensures that our keys are not exposed in the final image
  2. Configure runtime environment variables in the dokploy project, this is a necessary step, you can directly copy the content of the .env file and save it