Add Docker file to your Payload code

Self hosted PayloadCMS and PostgreSQL website on Docker

1 min read

Published Jun 17 2025, updated Jun 19 2025


10
0
0
0

CaddyDockerGitHub ActionsJavascriptNextJSPayloadCMSPortainerTailscaleUbuntuUFW

Now we need to add a docker file to the root of your Payload website code.


First we need to set the standalone flag in the next.config.mjs file at the route of the project:

/next.config.mjs

const nextConfig = {
  output: 'standalone',
}

If you have other config already then merge appropriately.


Then you need to add a new script line in the package.json file runs both database migrate and then build, call it ci as thats what we will reference in the docker file when building:

/package.json

"scripts": {
    ...
    "ci": "payload migrate && pnpm build",
    ...
  },


Next add a Dockerfile to the route of the project:

/Dockerfile

FROM node:22.12.0-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

ENV COREPACK_DEFAULT_TO_LATEST=0

# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
RUN \
  if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
  elif [ -f package-lock.json ]; then npm ci; \
  elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
  else echo "Lockfile not found." && exit 1; \
  fi


# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app

# Database and payload secret are required to build the application.
# They are passed as build arguments to ensure that the application can connect to the database during the build process.
# This is in an early stage so doesn't persist in the final image.
ARG DATABASE_URI
ARG PAYLOAD_SECRET
ENV DATABASE_URI=$DATABASE_URI
ENV PAYLOAD_SECRET=$PAYLOAD_SECRET

COPY --from=deps /app/node_modules ./node_modules
COPY . .

ENV COREPACK_DEFAULT_TO_LATEST=0

RUN \
  if [ -f yarn.lock ]; then yarn run ci; \
  elif [ -f package-lock.json ]; then npm run ci; \
  elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run ci; \
  else echo "Lockfile not found." && exit 1; \
  fi

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

ENV NODE_ENV production

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

# 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
COPY --from=builder --chown=nextjs:nodejs /app/public ./public

USER nextjs

EXPOSE 3000

ENV PORT 3000

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


This is a multi-stage build file that will create a small final image size, and will also run the data base migrations as part of the build process.

In order to build the project in the docker file, the payload secret and database connection string env values are both required, so we will pass them in from GitHub actions as build arguments, however they will not be present in the final image and will be set in Docker/Portainer with the other env values when deploying the service.


Products from our shop

Docker Cheat Sheet - Print at Home Designs

Docker Cheat Sheet - Print at Home Designs

Docker Cheat Sheet Mouse Mat

Docker Cheat Sheet Mouse Mat

Docker Cheat Sheet Travel Mug

Docker Cheat Sheet Travel Mug

Docker Cheat Sheet Mug

Docker Cheat Sheet Mug

Vim Cheat Sheet - Print at Home Designs

Vim Cheat Sheet - Print at Home Designs

Vim Cheat Sheet Mouse Mat

Vim Cheat Sheet Mouse Mat

Vim Cheat Sheet Travel Mug

Vim Cheat Sheet Travel Mug

Vim Cheat Sheet Mug

Vim Cheat Sheet Mug

SimpleSteps.guide branded Travel Mug

SimpleSteps.guide branded Travel Mug

Developer Excuse Javascript - Travel Mug

Developer Excuse Javascript - Travel Mug

Developer Excuse Javascript Embroidered T-Shirt - Dark

Developer Excuse Javascript Embroidered T-Shirt - Dark

Developer Excuse Javascript Embroidered T-Shirt - Light

Developer Excuse Javascript Embroidered T-Shirt - Light

Developer Excuse Javascript Mug - White

Developer Excuse Javascript Mug - White

Developer Excuse Javascript Mug - Black

Developer Excuse Javascript Mug - Black

SimpleSteps.guide branded stainless steel water bottle

SimpleSteps.guide branded stainless steel water bottle

Developer Excuse Javascript Hoodie - Light

Developer Excuse Javascript Hoodie - Light

Developer Excuse Javascript Hoodie - Dark

Developer Excuse Javascript Hoodie - Dark

© 2025 SimpleSteps.guide
AboutFAQPoliciesContact