2023 guide for Dockerzing Caddy + Nextjs app

Hello all I’ve begun, I hoping to get some up to date links on how to leverage the Docker Caddy image into a Next js app.

Essentially a node app.

There are a few, but not too many links out there. Hopefully get guidance from the community on an iOS to date resource / guide on this.

Thank you.

See the docs:

@francislavoie Thank you for such a prompt reply!

I plan to create an official example which I’ll add to the nextjs community.
The current official example (Next + Docker) has this dockerfile which works great.

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

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

# Rebuild the source code only when needed
FROM base AS builder
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.

RUN yarn build

# If using npm comment out above and use below instead
# RUN npm run build

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

ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.

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


# set hostname to localhost

# 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"]

in addition to the links your provided I came across the Caddy Article from Docker

Which has these few lines for a binary overlay

FROM caddy:builder AS builder
RUN xcaddy build \
--with github.com/caddyserver/nginx-adapter \
--with github.com/hairyhenderson/caddy-teapot-module@v0.0.3-0
FROM caddy:<version>
COPY --from=builder /usr/bin/caddy /usr/bin/caddy

I am trying to find solution with least amount of code to leverage the existing dockerfile (Nextsjs one).

It will be a great opportunity to add to the official next examples and show next leveraging Caddy’s http3 support.

Those are essentially example plugins. If you’re not using them, then don’t build with them.

If you’re not using plugins, you don’t need the builder image variant (and don’t need a Dockerfile at all). You can just use the normal Docker image.

As mentioned I do need the dockerfile for my nextapp.
As it’s the bare minimum for the needed to build my next app docker image.

I went to just add the caddy image to that.
Could you point to an example for that if you have one.

As most of what’s on online goes into just configuring caddy and not many examples of building the image with say a react app.

I do apologize for my lack of experience working with building Docker images. But I will assume this is a very simple task,

I’m talking about the Caddy Dockerfile, not the node/next one.

That’s not recommended. Containers usually have only one process.

If you wanted to run multiple processes in one container, you’d need to use a process manager of somekind. But that’s a lot of added complexity for very little benefit.

What you should do is run a Caddy container, and run your Node container beside it. Configure Caddy to proxy requests to your Node container as needed. You can make a volume to mount any static files to your Caddy container so it can serve them with file_server, if necessary (depends on your setup, whether you plan on using SSR, etc).

Thanks for that clarification.

It’s all done here with nginx.

Unfortunately there are no examples to do the same with caddy.

I’ll wait until there is something put together by caddy. Or the community,

I’ll use nginx for now.

From the README:

A second container with the NGINX web server is used as a reverse proxy, and to handle HTTP caching.

A second container.

That’s no different than what I just said.

Just replace nginx in the docker-compose.yml with this: Keep Caddy Running — Caddy Documentation

Really, there’s nothing special going on, and nothing extra to document. You already have all the information you need.