Skip to main content
Boost your DevOps efficiency! Dive into our latest white paper.Read Now

NextJS

This guide explains how to wrap your Next.js application into a Docker image and configure environment variables effectively. Whether you're managing client-side or server-side variables, this document covers the key concepts and provides practical examples to streamline your setup.

Key concepts

Build-time variables (client-side)

  • Prefix: Variables prefixed with NEXT_PUBLIC_ (e.g., NEXT_PUBLIC_API_URL).
  • Behavior: These variables are embedded into the client-side JavaScript bundle during the next build process.
  • Availability: They are accessible in client-side code (e.g., React components) via process.env.
  • Limitation: They cannot be provided at runtime—they must be defined at build time. If set only during the next start, they won’t be available in the client bundle.
  • Best Practice: Store these variables in your GitHub repository’s environment variables or define them in your GitHub Actions workflow to ensure they’re injected during the build.

Run-time variables (server-side)

  • Prefix: Variables without the NEXT_PUBLIC_ prefix (e.g., DATABASE_URL).
  • Behavior: These are only available in server-side contexts (e.g., API routes, getServerSideProps, or Server Components in the App Router).
  • Availability: They can be injected at runtime and accessed via process.env in server-side code.
info

For more information on the environment variables, you can check NextJS official documentation here.

Setting up environment variables

For server-side variables

  • Define your server-side variables (e.g., DATABASE_URL, API_SECRET) using the Kapstan UI.
  • Kapstan will securely inject these variables into your application at runtime.
  • Access them in your server-side code like this
// Example: API route
export default function handler(req, res) {
const dbUrl = process.env.DATABASE_URL; // Injected by Kapstan
res.status(200).json({ message: `Connected to ${dbUrl}` });
}

For client-side variables

  • Define NEXT_PUBLIC_ variables in your build environment (e.g., GitHub repository variables or GitHub Actions workflow).
  • These variables will be embedded into the client-side bundle during next build.
  • Example usage in a React component:
// pages/index.js
export default function Home() {
return (
<div>
<h1>{process.env.NEXT_PUBLIC_APP_NAME}</h1>
<p>API: {process.env.NEXT_PUBLIC_API_URL}</p>
</div>
);
}

Script to trigger this docker build in the GitHub action

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Build Docker image
run: |
docker build \
--build-arg NEXT_PUBLIC_APP_NAME=${{ vars.NEXT_PUBLIC_APP_NAME }} \
--build-arg NEXT_PUBLIC_API_URL=${{ vars.NEXT_PUBLIC_API_URL }} \
-t my-next-app .

Building a docker image

Below is a sample Dockerfile to containerize your Next.js application with environment variable support.

Sample Dockerfile

# Build stage
FROM node:18-alpine AS builder

# Set working directory
WORKDIR /app

# Copy package.json and lock the file
COPY package.json package-lock.json* ./

# Install dependencies
RUN npm ci

# Copy application code
COPY . .

# Define build-time arguments for NEXT_PUBLIC_ variables
ARG NEXT_PUBLIC_API_URL
ARG NEXT_PUBLIC_APP_NAME

# Set environment variables for the build
ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
ENV NEXT_PUBLIC_APP_NAME=$NEXT_PUBLIC_APP_NAME

# Build the Next.js app
RUN npm run build

# Production stage
FROM node:18-alpine AS runner

WORKDIR /app

# Copy only necessary files from the builder stage
COPY --from=builder /app/package.json ./
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public
COPY --from=builder /app/node_modules ./node_modules
# The below file can also be `next.config.mjs` depending on the project
COPY --from=builder /app/next.config.js ./

# Expose port
EXPOSE 3000

# Start the app
CMD ["npm", "start"]

Building the docker image

Run the following command to build your Docker image, passing NEXT_PUBLIC_ variables as build arguments:

docker build \
--build-arg NEXT_PUBLIC_API_URL=https://api.example.com \
--build-arg NEXT_PUBLIC_APP_NAME=MyApp \
-t my-next-app .

Summary

  • Client-Side (NEXT_PUBLIC_): Define at build time using GitHub variables or build arguments. Embedded in the client bundle.
  • Server-Side: Inject at runtime using Kapstan. Available only server-side.
  • Docker: Use the provided Dockerfile and build/run commands to containerize your app with variables.

This setup ensures a secure, scalable, and maintainable approach to managing environment variables in your Next.js application.

Can't find what you need?