Still Soft
Trang chủ › Phần Mềm Ứng Dụng

Cách sử dụng Docker container hóa ứng dụng cho developer

Ban biên tập Still Soft · · Cập nhật
Cách sử dụng Docker container hóa ứng dụng cho developer

Docker giúp developer đóng gói ứng dụng cùng mọi thứ nó cần (runtime, thư viện, cấu hình) thành một image, rồi chạy image đó thành container giống hệt nhau trên máy dev, máy chủ thử nghiệm và production. Để container hóa một ứng dụng, bạn viết Dockerfile mô tả cách build image, dùng Docker Compose để chạy ứng dụng cùng database, cache trong môi trường dev, và áp dụng vài nguyên tắc để image nhỏ, build nhanh, an toàn. Bài hướng dẫn này đi từ khái niệm đến ví dụ thực tế cho một ứng dụng web Node.js, áp dụng tương tự cho Python, Java, Go.

Các khái niệm cần nắm

Khái niệmÝ nghĩa
ImageBản mẫu chỉ đọc gồm nhiều lớp (layer): hệ điều hành tối giản, runtime, code, cấu hình
ContainerMột tiến trình chạy từ image, có hệ thống file và mạng cô lập
DockerfileFile văn bản mô tả từng bước build image
RegistryKho lưu image, như Docker Hub, GitHub Container Registry, registry của các nhà cung cấp cloud
VolumeVùng lưu dữ liệu bền vững bên ngoài vòng đời container
NetworkMạng ảo để các container tìm và gọi nhau theo tên

Container khác máy ảo ở chỗ dùng chung nhân hệ điều hành của máy chủ, nên khởi động trong vài giây và tốn ít tài nguyên hơn nhiều. Trên Windows và macOS, Docker Desktop chạy một máy ảo Linux nhẹ phía sau.

Cài đặt

  • Windows, macOS: cài Docker Desktop (lưu ý điều khoản giấy phép với doanh nghiệp lớn); trên Windows nên bật WSL 2.
  • Linux: cài Docker Engine theo hướng dẫn chính thức cho bản phân phối, thêm người dùng vào nhóm docker để không phải dùng sudo. Nếu bạn mới dùng Linux, xem bài hướng dẫn cài đặt Ubuntu cho lập trình viên.

Kiểm tra bằng lệnh docker run hello-world. Một số lựa chọn thay thế như Podman, OrbStack, Colima cũng tương thích phần lớn lệnh Docker.

Viết Dockerfile đầu tiên

Với ứng dụng Node.js, một Dockerfile tốt thường theo thứ tự:

  1. Chọn image nền chính thức, ghim phiên bản: ví dụ node phiên bản LTS biến thể slim hoặc alpine, không dùng thẻ latest.
  2. Đặt thư mục làm việc bằng WORKDIR.
  3. Sao chép file khai báo phụ thuộc trước (package.json, lock file) rồi cài phụ thuộc. Vì Docker cache theo lớp, khi chỉ sửa code mà không đổi phụ thuộc, bước cài đặt sẽ không phải chạy lại.
  4. Sao chép mã nguồn rồi build.
  5. Chạy bằng người dùng không phải root với chỉ thị USER.
  6. Khai báo cổng (EXPOSE) và lệnh khởi động (CMD).

Luôn thêm file .dockerignore để loại node_modules, thư mục .git, file .env, log khỏi ngữ cảnh build: build nhanh hơn và tránh đưa bí mật vào image.

Multi-stage build

Dùng một giai đoạn có đủ công cụ để build (trình biên dịch, devDependencies), rồi giai đoạn cuối chỉ sao chép kết quả build sang image nền gọn nhẹ. Với Go, giai đoạn cuối có thể chỉ chứa một file nhị phân. Kỹ thuật này giảm đáng kể kích thước image và bề mặt tấn công.

Các lệnh dùng hằng ngày

  • docker build -t ten-app:1.0 . build image từ Dockerfile trong thư mục hiện tại.
  • docker run -d -p 3000:3000 --name app ten-app:1.0 chạy container ở nền, ánh xạ cổng.
  • docker ps, docker logs -f app, docker exec -it app sh xem container, log, vào shell bên trong.
  • docker stop, docker rm, docker image prune dừng, xóa container và dọn image không dùng.

Docker Compose cho môi trường dev

Ứng dụng thật hiếm khi chạy một mình. Docker Compose mô tả nhiều service trong một file compose.yaml:

  • Service app build từ Dockerfile, gắn thư mục code vào container để sửa code thấy ngay (bind mount), đọc biến môi trường từ file .env.
  • Service db dùng image PostgreSQL chính thức, dữ liệu lưu trên volume có tên để không mất khi xóa container.
  • Service cache dùng image Redis.
  • Khai báo healthcheck cho database và điều kiện để app chỉ khởi động khi database sẵn sàng.

Chỉ cần docker compose up là cả đội có môi trường giống nhau, người mới vào dự án không mất cả ngày cài database đúng phiên bản. Khi làm việc với PostgreSQL trong container, các mẹo tối ưu trong bài tối ưu hiệu năng PostgreSQL vẫn áp dụng. Trong VS Code, tiện ích Dev Containers còn cho phép mở cả dự án bên trong container để mọi công cụ dev chạy đồng nhất.

Nguyên tắc bảo mật

  • Dùng image nền chính thức hoặc từ nguồn tin cậy, cập nhật thường xuyên.
  • Không đưa mật khẩu, khóa API vào Dockerfile hay image; truyền qua biến môi trường lúc chạy hoặc secret của nền tảng. Với bí mật cần lúc build, dùng tính năng build secret.
  • Chạy bằng người dùng thường, hạn chế quyền (không dùng --privileged khi không cần).
  • Quét lỗ hổng image bằng công cụ như Trivy, Docker Scout trong pipeline; chi tiết trong bài xu hướng DevSecOps.
  • Không mở cổng database ra internet khi chạy trên máy chủ.

Lỗi thường gặp và cách xử lý

Hiện tượngNguyên nhân thường gặp
App trong container không kết nối được database bằng localhostlocalhost trong container là chính container đó; dùng tên service (ví dụ db) trong cùng mạng Compose
Build lại rất chậm dù chỉ sửa một dòng codeSao chép toàn bộ code trước khi cài phụ thuộc, làm mất cache
Mất dữ liệu database sau khi xóa containerKhông dùng volume
Image nặng hàng GBImage nền đầy đủ, thiếu multi-stage, thiếu .dockerignore
Lỗi quyền ghi file với bind mount trên LinuxUID người dùng trong container khác người dùng trên máy
Container chạy trên Mac chip Apple nhưng lỗi trên máy chủKhác kiến trúc CPU (arm64 và amd64); build đa nền tảng với buildx

Bước tiếp theo

Khi đã container hóa xong, bạn có thể đưa việc build và đẩy image vào pipeline tự động, như hướng dẫn trong bài thiết lập CI/CD pipeline, rồi triển khai lên VPS, dịch vụ container được quản lý hoặc Kubernetes khi hệ thống lớn dần. Với đội nhỏ, một VPS chạy Docker Compose cùng reverse proxy có HTTPS tự động đã đủ cho nhiều ứng dụng.

Câu hỏi thường gặp

Docker và máy ảo khác nhau thế nào?

Máy ảo giả lập cả phần cứng và chạy hệ điều hành riêng, nặng và khởi động chậm. Container dùng chung nhân hệ điều hành của máy chủ, chỉ cô lập tiến trình, nên nhẹ và khởi động nhanh hơn nhiều, đổi lại mức cô lập thấp hơn máy ảo.

Có nên chạy database trong Docker ở production không?

Được nếu có volume bền vững, sao lưu và giám sát tốt. Tuy vậy nhiều đội chọn dịch vụ database được quản lý cho production để giảm công vận hành, chỉ dùng container cho môi trường dev và test.

Docker Desktop có miễn phí không?

Docker Desktop miễn phí cho cá nhân, giáo dục, dự án mã nguồn mở và doanh nghiệp nhỏ theo điều kiện trong giấy phép; doanh nghiệp vượt ngưỡng quy mô cần gói trả phí. Docker Engine trên Linux là mã nguồn mở.

Image alpine có phải luôn là lựa chọn tốt nhất không?

Alpine rất nhỏ nhưng dùng thư viện musl thay vì glibc, đôi khi gây lỗi tương thích hoặc build chậm với một số thư viện Python, Node.js có phần biên dịch. Biến thể slim dựa trên Debian là lựa chọn cân bằng phổ biến.

Bài liên quan