CodeBlanks Logo Icon CodeBlanks

Challenge - Dockerfile

Write a Dockerfile for a web application.

Challenge: a production-ready Dockerfile

In this challenge you'll combine all the good practices for a Node.js API in a single Dockerfile:

  • A small base image with a pinned version
  • Cache-friendly order (package*.json first)
  • Only production dependencies
  • A non-root user
  • A start command in exec form
FROM node:20-alpine
ENV NODE_ENV=production
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY --chown=node:node . .
USER node
EXPOSE 3000
CMD ["node", "server.js"]

Practice Write the Dockerfile

Write the Dockerfile from the card: node:20-alpine; ENV NODE_ENV=production; WORKDIR /app; copy package*.json and run npm ci --omit=dev; copy the code with --chown=node:node; USER node; EXPOSE 3000; node server.js in exec form.

Starter code

terminal
# buraya yaz

Sample solution

terminal
FROM node:20-alpine
ENV NODE_ENV=production
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY --chown=node:node . .
USER node
EXPOSE 3000
CMD ["node", "server.js"]

Expected output

[+] Building 7.1s (12/12) FINISHED
 => naming to docker.io/library/api:1.0 done

Practice Add a .dockerignore

Write a .dockerignore for the same project: exclude node_modules, .git, .env, npm-debug.log and Dockerfile.

Starter code

terminal
# buraya yaz

Sample solution

terminal
node_modules
.git
.env
npm-debug.log
Dockerfile

Expected output

 => [internal] load .dockerignore
 => => transferring context: 21.3kB

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 In the Dockerfile above, which step reruns if only server.js changes?

  • Only FROM
  • None
  • COPY --chown=node:node . . and after Correct answer
  • All of them including npm ci

Explanation: Since package*.json didn't change, npm ci comes from the cache.

2 Install only the production dependencies.

Question
RUN npm ci ____
Answer
RUN npm ci --omit=dev

Explanation: npm ci --omit=dev skips devDependencies.

3 Match the practices with their purposes.

Term Meaning
node:20-alpine Small, pinned base
package*.json first Cache
USER node Least privilege
["node", "server.js"] Signal handling

All lessons in Beginner