This content originally appeared on DEV Community and was authored by Jayce Thai
Hi everyone!
Yesterday I dove deep into our infra to slim down and speed up our frontend apps (Next.js).
What I worked on
- Upgrade Node (v22 LTS) + Linux base image (Alpine OS)
- Multi-stage Docker build with smart caching
- Standalone build mode in Next.js (smaller runtime)
- Place app paths following FHS (Filesystem Hierarchy Standard) – Linux distro
- Ensure the container doesn’t run as root
Why it matters
- Smaller images → faster pulls/build & deploys
- Better cache hits → shorter CI times
- Non-root runtime → safer-by-default
Key wins
- Image size:
~60% reduction (before/after in comments)
- CI build time: noticeably faster
- Cleaner, standard file layout for easier ops
If you’re doing similar work, check out:
- Next.js Standalone output: https://nextjs.org/docs/14/pages/api-reference/next-config-js/output
- Linux FHS guide: https://refspecs.linuxfoundation.org/FHS_3.0/fhs-3.0.pdf
FROM public.ecr.aws/docker/library/node:22.20.0-alpine3.22 AS deps
WORKDIR /usr/src/app
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile --ignore-scripts
FROM public.ecr.aws/docker/library/node:22.20.0-alpine3.22 AS builder
WORKDIR /usr/src/app
COPY --from=deps /usr/src/app/node_modules ./node_modules
COPY . .
RUN if [ -f .env.template ]; then cp .env.template .env; fi
RUN yarn build
FROM public.ecr.aws/docker/library/node:22.20.0-alpine3.22 AS runner
WORKDIR /usr/src/app
ENV NODE_ENV=production
RUN addgroup -g 1001 -S nodejs && adduser -S nextjs -u 1001
COPY --from=builder --chown=nextjs:nodejs /usr/src/app/.env ./.env
COPY --from=builder --chown=nextjs:nodejs /usr/src/app/public ./public
COPY --from=builder --chown=nextjs:nodejs /usr/src/app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /usr/src/app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
CMD ["node", "server.js"]
This content originally appeared on DEV Community and was authored by Jayce Thai