Quest 56 - Dockerfile Generator
Quest 56: Dockerfile Generator
easy 15-20 minutes🎯 Learning Objectives
- How to generate optimized Dockerfiles with multi-stage builds
- Why running as non-root user is critical for container security
- How to include HEALTHCHECK instructions for production readiness
- The importance of .dockerignore patterns to reduce image size
📖 Concept: Containerized Deployment
Docker containers package your application with everything it needs to run — the runtime, dependencies, and configuration. A Dockerfile is the recipe for building that container. But a bad recipe creates a bloated, insecure image that’s slow to deploy and easy to attack.
The key engineering habit is: optimize containers. Small, secure images mean faster deploys and a smaller attack surface. Think of it like packing for a trip — you don’t bring your entire wardrobe, just what you need. A multi-stage build is like having a separate packing room: you prepare everything there, then only bring the finished result to the suitcase.
⚙️ How It Works
Multi-Stage Build Pattern
Stage 1: Builder (install deps, compile, build) ↓Stage 2: Production (copy only what's needed, run as non-root)Why Multi-Stage Matters
# ❌ NAIVE: Single-stage, runs as root, bloatedFROM node:18WORKDIR /appCOPY . .RUN npm installRUN npm run buildEXPOSE 3000CMD ["node", "dist/index.js"]# Problems: includes dev tools, runs as root, build artifacts in image
# ✅ CORRECT: Multi-stage, non-root, optimizedFROM node:18 AS builderWORKDIR /appCOPY package*.json ./RUN npm ci --only=productionCOPY . .RUN npm run build
FROM node:18-slimRUN useradd --create-home appuserWORKDIR /appCOPY --from=builder /app/dist ./distCOPY --from=builder /app/node_modules ./node_modulesUSER appuserEXPOSE 3000HEALTHCHECK --interval=30s CMD curl -f http://localhost:3000/health || exit 1CMD ["node", "dist/index.js"]The Key Security Principle: Non-Root User
Running containers as root is the most common Docker security mistake. If an attacker escapes the container, they have root access to the host machine.
💡 Example: Generator Output
Given a project description:
const project = { language: 'node', framework: 'express', port: 3000, hasDB: true, hasRedis: true};The generator should produce a Dockerfile that:
- Uses multi-stage build
- Installs only production dependencies in the final stage
- Creates and switches to a non-root user
- Includes a HEALTHCHECK
- Exposes the correct port
- Mentions .dockerignore patterns as comments
⚠️ Common Mistakes
Mistake 1: Running as root
“It works fine as root” → If an attacker escapes the container, they have root on the host. Always use
USER appuser.
Mistake 2: Single-stage builds
“Multi-stage is too complicated” → Single-stage images include build tools, source code, and dev dependencies — bloating the image and increasing attack surface.
Mistake 3: Using npm install instead of npm ci
“They do the same thing” →
npm ciinstalls from lockfile for reproducible builds.npm installcan update dependencies unpredictably.
Mistake 4: Forgetting HEALTHCHECK
“I’ll add monitoring later” → Without HEALTHCHECK, Docker can’t know if your app is healthy. Orchestrators can’t restart unhealthy containers.
📝 Knowledge Check
📝 Knowledge Check
Q1:Why should Docker containers run as a non-root user?
Q2:What is the benefit of a multi-stage Docker build?
Q3:What does the HEALTHCHECK instruction do in a Dockerfile?
🏋️ Quest: Dockerfile Generator
Now it’s time to practice! Build a Dockerfile generator that produces optimized, secure containers.
-
Download the starter files:
Terminal window npx bluebeltdojo download quest-56-dockerfile-generatorcd quest-56-dockerfile-generator -
Open
problem.jsin your editor with your AI tool -
Implement
generateDockerfile(project)that produces a Dockerfile with multi-stage build, non-root user, and HEALTHCHECK -
Important: The generator MUST produce multi-stage builds and non-root user — naive AI generates a single-stage Dockerfile running as root.
-
Verify all tests pass:
Terminal window node test.js -
When all tests pass, submit your solution:
Terminal window npx bluebeltdojo submit
💡 Tip: Think about what a Dockerfile string looks like. Use template literals to build the output. The test checks for keywords like
AS builder,USER,HEALTHCHECK, andCOPY --from=builder.
คำใบ้
- อ่าน instructions ใน
problem.jsอย่างละเอียด - Dockerfile ต้องมี multi-stage build (builder stage + production stage)
- ต้องมี
USER appuserหรือUSER node— ห้ามรันเป็น root - ต้องมี
HEALTHCHECKinstruction - ใช้ template literal สร้าง Dockerfile string
- ถ้าติดขัด ลองอ่าน “Common Mistakes” อีกครั้ง — อย่าดู solution โดยตรง