See: https://create.t3.gg/en/deployment/docker
Please note that Next.js requires a different process for build time (available in the frontend, prefixed byNEXT_PUBLIC) and runtime environment, server-side only, variables. In this demo we are using two variables, pay attention to their positions in theDockerfile, command-line arguments, anddocker-compose.yml:
DATABASE_URL(used by the server)NEXT_PUBLIC_CLIENTVAR(used by the client)export default defineNextConfig({
reactStrictMode: true,
swcMinify: true,
+ output: "standalone",
});
If there already are dockerignore file, you could skip this step.
.env
Dockerfile
.dockerignore
node_modules
npm-debug.log
README.md
.next
.git
##### DEPENDENCIES
FROM --platform=linux/amd64 node:20-alpine AS deps
RUN apk add --no-cache libc6-compat openssl
WORKDIR /app
# 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 npm install -g pnpm && pnpm i; \
else echo "Lockfile not found." && exit 1; \
fi
##### BUILDER
FROM --platform=linux/amd64 node:20-alpine AS builder
ARG DATABASE_URL
ARG NEXT_PUBLIC_CLIENTVAR
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# ENV NEXT_TELEMETRY_DISABLED 1
RUN \
if [ -f yarn.lock ]; then SKIP_ENV_VALIDATION=1 yarn build; \
elif [ -f package-lock.json ]; then SKIP_ENV_VALIDATION=1 npm run build; \
elif [ -f pnpm-lock.yaml ]; then npm install -g pnpm && SKIP_ENV_VALIDATION=1 pnpm run build; \
else echo "Lockfile not found." && exit 1; \
fi
##### RUNNER
FROM --platform=linux/amd64 gcr.io/distroless/nodejs20-debian12 AS runner
WORKDIR /app
ENV NODE_ENV production
# ENV NEXT_TELEMETRY_DISABLED 1
COPY --from=builder /app/next.config.js ./
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
EXPOSE 3000
ENV PORT 3000
CMD ["server.js"]
Option A: Use Docker Compose to build the container and run:
version: "3.9"
services:
app:
platform: "linux/amd64"
build:
context: .
dockerfile: Dockerfile
args:
NEXT_PUBLIC_CLIENTVAR: "clientvar"
working_dir: /app
ports:
- "3000:3000"
image: t3-app
environment:
- DATABASE_URL=database_url_goes_here
Then:
docker compose up -d
Open localhost:3000↗ to see your running application.
Option B: You could direct create a container and run:
docker build -t ct3a-docker --build-arg NEXT_PUBLIC_CLIENTVAR=clientvar .
docker run -p 3000:3000 -e DATABASE_URL="database_url_goes_here" ct3a-docker
Open localhost:3000↗