
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

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

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

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

- 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

2. Modify 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: 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

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

- 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

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

4. Commit the code, GitHub Actions will run automatically

Summary
- RUN find . -name ".env*" -delete, this command ensures that our keys are not exposed in the final image
- 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
Author
Categories
Create GitHub Token for Accessing Docker Registry1. Open https://github.com/settings/tokens, click the "Generate new token (classic)" button in the top right corner2. Enter Token name, select permissions, click the "Generate token" button3. Copy the generated Token, it will be used in the next stepConfigure Docker Registry in Dokploy1. Open dokploy dashboard, click the "Registry" button in the left menu2. Click the "Docker Registry" menu, click the "Add Registry" buttonCreate New Project in Dokploy1. Create new project, as shown in the image, make sure to select Application2. Modify Cluster Settings3. Configure Docker ImageConfigure Environment Secret1. Set environment variables under the Settings tab of the github project repository2. Click Add environment secret, need to set two variables with names ENV_PRODUCTION and DOKPLOY_DEPLOY_URL respectivelyCreate GitHub Actions Workflow1. Create .github/workflows/deploy-push-dokploy.yml file in the project root directory, with the following content:2. Create Dockerfile in the project root directory, with the following content:3. Configure runtime environment variables in the dokploy project4. Commit the code, GitHub Actions will run automaticallySummary

