Hướng dẫn viết Dockerfile cho React. Một cho môi trường dev và một cho production.
Môi trường Dev
Thông thường khi ta làm việc với một source code React có sẵn. Ta cần phải cài NodeJS và dùng npm để install node_modules.
Để thuận tiện cho môi trường dev trên các máy tính khác nhau (ví dụ như có bạn cài NodeJS 18, có bạn thì xài NodeJS 20). Ta có thể dùng Docker và viết Dockerfile cho môi trường dev. Để khi có bạn mới vào ta chỉ cần chạy câu lệnh docker là xong, không cần làm gì phức tạp cho việc cấu hình môi trường dev.
Viết Dockerfile cho môi trường dev. Tạo một tệp tin tên là Dockerfile.dev
:
FROM node:20 WORKDIR /usr/src/app COPY package*.json ./ RUN npm install COPY . . EXPOSE 3000 CMD [ "npm", "start" ]
Tạo tệp tin tên là docker-compose-dev.yaml
:
version: '3.7' services: frontend: container_name: frontend build: context: . dockerfile: Dockerfile.dev volumes: - './:/app' - '/app/node_modules' ports: - 3000:3000
Tạo tệp tin .dockerignore
để bỏ các thư mục không cần thiết:
node_modules
npm-debug.log
build
.git
*.md
.gitignore
Khi có bạn mới vào làm dự án, các bạn chỉ cần clone source code về và chạy câu lệnh sau:
docker compose -f docker-compose-dev.yaml up -d
Nếu bạn có sửa gì lại Dockerfile.dev
thì chỉ cần chạy lại với --build
docker compose -f docker-compose-dev.yaml up -d --build
Môi trường Production
Dockerfile để build Docker Image cho môi trường Production.
FROM node:20-alpine as build WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build FROM nginx:stable-alpine
COPY /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Tại sao ta lại chạy lệnh COPY package*.json ./
rồi RUN npm install
, tiếp theo đó mới chạy lệnh COPY . .
rồi RUN npm run build
, sao không viết ngắn lại như bên dưới:
COPY . .
RUN npm install
RUN npm run build
Viết như trên phải gọn hơn không? Câu trả lời là để ta cận dụng Cache Layer khi build Docker Image:
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
Khi ta viết như trên thì chỉ khi nào ta thay đổi package.json
thì khi build Docker Image nó mới chạy lại câu lệnh npm install
, còn nếu ta không thay đổi gì trong package.json
thì khi build Docker Image nó sẽ bắt đầu từ câu lệnh:
COPY . .
RUN npm run build
Không cần chạy lại câu lệnh npm install
, giúp ta build nhanh hơn. Cấu hình của tệp tin nginx.conf
để COPY vào Dockerfile:
# auto detects a good number of processes to run
worker_processes auto; #Provides the configuration file context in which the directives that affect connection processing are specified.
events { # Sets the maximum number of simultaneous connections that can be opened by a worker process. worker_connections 8000; # Tells the worker to accept multiple connections at a time multi_accept on;
} http { # what times to include include /etc/nginx/mime.types; # what is the default one default_type application/octet-stream; # Sets the path, format, and configuration for a buffered log write log_format compression '$remote_addr - $remote_user [$time_local] ' '"$request" $status $upstream_addr ' '"$http_referer" "$http_user_agent"'; server { # listen on port 80 listen 80; # save logs here access_log /var/log/nginx/access.log compression; # where the root here root /usr/share/nginx/html; # what file to server as index index index.html index.htm; location / { # First attempt to serve request as file, then # as directory, then fall back to redirecting to index.html try_files $uri $uri/ /index.html; } # Media: images, icons, video, audio, HTC location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ { expires 1M; access_log off; add_header Cache-Control "public"; } # Javascript and CSS files location ~* \.(?:css|js)$ { try_files $uri =404; expires 1y; access_log off; add_header Cache-Control "public"; } # Any route containing a file extension (e.g. /devicesfile.js) location ~ ^.+\..+$ { try_files $uri =404; } }
}
Cấu trúc thư mục của ta như sau:
.
├── public
└── src
└── .dockerignore
└── Dockerfile
└── Dockerfile.dev
└── docker-compose-dev.yaml
└── nginx.conf
└── package.json
└── package-lock.json
Tham gia nhóm chat của DevOps VN tại Telegram hoặc Slack.
Kém tiếng Anh và cần nâng cao trình độ giao tiếp: Tại sao bạn học không hiệu quả?