Dockerfile practices in production
June 02, 2024
Use official docker image as base image
// not do this
FROM ubuntu
RUN apt-get update && apt-get install -y \
node \
&& rm -rf /var/lib/apt/lists/*
...
// do this
FROM node
...
reason
- low risk of vulnerability
- high reliability
- high performance
- easy to maintain
- easy to use same environment
Fixate version
// not do this
FROM node
...
// do this
FROM node:20.14.0
...
reason
- 'FROM node' means 'FROM node:latest'. Latest tag is unpredictable and different version might be installed.
Use small sized official images(if no need to specific system utilities)
// not do this
FROM node:20.14.0
...
// do this
FROM node:20.14.0-alpine
...
reason
- low risk of vulnerability
- faster and less storage
Optimize caching image layers
// not do this
FROM node:20.14.0-alpine
WORKDIR /app
COPY . .
RUN npm ci --production
CMD ["node", "dist/app.js"]
...
// do this
FROM node:20.14.0-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
CMD ["node", "dist/app.js"]
Order Dockerfile commands from least to most frequestly changing like above.
reason
- faster image building and fetching
Use .dockerignore to explicitly exclude files and folders
reason
- reduce image size
- prevent secrets exposure unintentionally
Use multi-stage build
FROM node:20.14.0-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
RUN npm run build
FROM node:20.14.0-alpine AS production
WORKDIR /app
COPY /app/package*.json ./
COPY /app/node_modules ./node_modules
COPY /app/dist ./dist
CMD ["node", "dist/app.js"]
reason
- low risk of vulnerability
- smaller image size
Use the least privileged user
FROM node:20.14.0-alpine
RUN chown -R node:node /node
USER node
reason
- low risk of vulnerability
Scan images for vulnerabilities
reason
- low risk of vulnerability
Lint Dockerfile
reason
- high reliability
- speed up developping