Dockerfile định nghĩa image theo từng layer — đặt COPY package.json + RUN npm install trước COPY source để tận dụng cache; dùng non-root USER và .dockerignore cho security và performance.
- Dockerfile là script định nghĩa cách build Docker image.
- Layer caching optimization: Docker cache mỗi instruction layer — nếu layer không thay đổi, dùng cache từ previous build.
- Đặt instructions ít thay đổi trước: FROM → COPY package*.json → RUN npm install → COPY . . — nếu source code thay đổi nhưng package.json không, Docker reuse cached npm install layer (tiết kiệm 1-2 phút). .dockerignore: exclude node_modules, .git, .env, build artifacts — tránh copy không cần thiết vào build context, giảm build time.
- Security — non-root user: mặc định container chạy root (risk nếu có vulnerability); thêm RUN addgroup -S appgroup && adduser -S appuser -G appgroup; USER appuser trước CMD — principle of least privilege.
- Health checks: HEALTHCHECK --interval=30s --timeout=3s CMD wget -q -O /dev/null http://localhost:3000/health || exit 1 — Docker/K8s biết container có healthy không để route traffic.
- CMD vs ENTRYPOINT: ENTRYPOINT định nghĩa executable không thể override (docker run image args — args được pass vào ENTRYPOINT); CMD là default args có thể override; dùng kết hợp ENTRYPOINT ['node'] CMD ['server.js'] — có thể đổi file chạy nhưng không đổi runtime.
- Multi-line RUN với && và cleanup: RUN apt-get update && apt-get install -y ... && rm -rf /var/lib/apt/lists/* — clean trong cùng layer tránh layer to.
A Dockerfile defines a Docker image layer by layer — place COPY package.json + RUN npm install before COPY source to leverage cache; use a non-root USER and .dockerignore for security and performance.
- A Dockerfile is a script that defines how to build a Docker image.
- Layer caching optimization: Docker caches each instruction layer — if a layer is unchanged, it reuses the cache from the previous build.
- Place rarely changing instructions first: FROM → COPY package*.json → RUN npm install → COPY . . — if source code changes but package.json does not, Docker reuses the cached npm install layer (saving 1-2 minutes). .dockerignore: exclude node_modules, .git, .env, and build artifacts — avoids copying unnecessary files into the build context, reducing build time.
- Security — non-root user: by default containers run as root (a risk if there is a vulnerability); add RUN addgroup -S appgroup && adduser -S appuser -G appgroup; USER appuser before CMD — principle of least privilege.
- Health checks: HEALTHCHECK --interval=30s --timeout=3s CMD wget -q -O /dev/null http://localhost:3000/health || exit 1 — lets Docker/K8s know whether the container is healthy before routing traffic.
- CMD vs ENTRYPOINT: ENTRYPOINT defines an executable that cannot be overridden (docker run image args — args are passed into ENTRYPOINT); CMD provides default args that can be overridden; combine them as ENTRYPOINT ['node'] CMD ['server.js'] — the file to run can change but not the runtime.
- Multi-line RUN with && and cleanup: RUN apt-get update && apt-get install -y ... && rm -rf /var/lib/apt/lists/* — clean up in the same layer to avoid bloated layers.