Docker đã trở thành một công cụ không thể thiếu giúp chuẩn hóa môi trường phát triển và triển khai ứng dụng. Đối với các lập trình viên Node.js, việc đưa ứng dụng vào container giúp tránh được lỗi "chạy được trên máy tôi nhưng lỗi trên server".
Trong bài viết này, chúng ta sẽ từng bước xây dựng một Dockerfile cơ bản, build image, chạy container và cấu hình các biến môi trường một cách an toàn.
1. Chuẩn bị ứng dụng Node.js đơn giản
Giả sử bạn có một ứng dụng Node.js cơ bản sử dụng Express.
File package.json:
{
"name": "node-docker-demo",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"express": "^4.18.2"
}
}
File index.js:
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;
app.get('/', (req, res) => {
res.send(`Hello World từ Docker! Môi trường: ${process.env.NODE_ENV || 'development'}`);
});
app.listen(PORT, () => {
console.log(`Ứng dụng đang chạy trên cổng ${PORT}`);
});
2. Tạo file .dockerignore
Trước khi viết Dockerfile, bạn cần tạo một file .dockerignore ở thư mục gốc của dự án. File này ngăn không cho các thư mục không cần thiết (như node_modules hoặc file log) bị copy vào trong Docker image, giúp giảm dung lượng image và tăng tốc độ build.
node_modules
npm-debug.log
Dockerfile
.dockerignore
.git
3. Viết Dockerfile cơ bản
Tạo một file tên là Dockerfile (không có phần mở rộng) tại thư mục gốc của dự án:
# Bước 1: Chọn base image chính thức của Node.js (sử dụng phiên bản LTS và bản rút gọn alpine để tối ưu dung lượng)
FROM node:18-alpine
# Bước 2: Thiết lập thư mục làm việc bên trong container
WORKDIR /usr/src/app
# Bước 3: Sao chép package.json và package-lock.json (nếu có) trước
# Điều này giúp tận dụng Docker layer cache khi không có thay đổi về dependency
COPY package*.json ./
# Bước 4: Cài đặt các dependencies
RUN npm install --only=production
# Bước 5: Sao chép toàn bộ mã nguồn vào container
COPY . .
# Bước 6: Khai báo port mà container sẽ lắng nghe khi chạy
EXPOSE 3000
# Bước 7: Lệnh để khởi chạy ứng dụng
CMD [ "npm", "start" ]
4. Build Docker Image
Mở terminal tại thư mục chứa Dockerfile và chạy lệnh sau để build image:
docker build -t node-docker-demo:1.0 .
Trong đó:
-
-t node-docker-demo:1.0: Đặt tên (tag) cho image lànode-docker-demovới phiên bản1.0. -
.: Chỉ định ngữ cảnh build (build context) là thư mục hiện tại.
5. Chạy Docker Container và Truyền Biến Môi Trường
Sau khi build thành công, bạn có thể khởi chạy container từ image vừa tạo:
docker run -d -p 8080:3000 --name my-node-app -e NODE_ENV=production node-docker-demo:1.0
Giải thích các tham số:
-
-d: Chạy container dưới nền (detached mode). -
-p 8080:3000: Ánh xạ cổng8080của máy host vào cổng3000bên trong container. -
--name my-node-app: Đặt tên cho container đang chạy để dễ quản lý. -
-e NODE_ENV=production: Truyền biến môi trường vào ứng dụng. -
node-docker-demo:1.0: Tên image và tag đã build ở bước trước.
Bây giờ, bạn có thể truy cập http://localhost:8080 trên trình duyệt để kiểm tra kết quả.
6. Các lưu ý quan trọng về bảo mật và tối ưu hóa
Khi triển khai thực tế, lập trình viên cần lưu ý các điểm sau để đảm bảo an toàn cho ứng dụng:
-
Không chạy container bằng quyền root:
Mặc định, các container Node.js chạy với quyền root. Điều này tiềm ẩn rủi ro bảo mật lớn. Image Node.js chính thức đã có sẵn một user bảo mật tên là
node. Hãy chuyển sang user này trước khi khởi chạy ứng dụng bằng cách thêm dòng sau vào trước lệnhCMD:
USER node
Sử dụng phiên bản Node.js cụ thể:
Tránh sử dụng taglatest(ví dụ:FROM node). Hãy luôn chỉ định rõ phiên bản ổn định (nhưnode:18-alpinehoặcnode:20-slim) để đảm bảo tính nhất quán trên mọi môi trường.Quản lý biến môi trường nhạy cảm:
Không bao giờ lưu các thông tin nhạy cảm như API key, mật khẩu cơ sở dữ liệu trực tiếp trongDockerfile. Hãy truyền chúng qua tham số-ekhi chạy container, hoặc sử dụng các file.envđể bảo mật thông tin tốt hơn.
Top comments (0)