Docker là gì? Hướng dẫn cơ bản cho người mới bắt đầu
Docker là một công cụ rất phổ biến trong phát triển phần mềm hiện nay. Nó giúp lập trình viên đóng gói ứng dụng cùng với các thư viện, cấu hình và môi trường cần thiết vào một container.
Nhờ đó, ứng dụng có thể chạy ổn định trên máy cá nhân, server hoặc cloud mà không gặp tình trạng:
“Trên máy tôi chạy được, nhưng lên server lại lỗi.”
Docker đặc biệt hữu ích khi làm việc với các ứng dụng như Angular, NestJS, Node.js, MySQL, Redis hoặc khi triển khai hệ thống lên AWS.
1. Docker là gì?
Hiểu đơn giản, Docker cho phép chúng ta đóng gói một ứng dụng thành một container độc lập.
Một container có thể chứa:
Source code của ứng dụng
Runtime như Node.js
Thư viện cần thiết
Các dependency
Một số cấu hình cần thiết để ứng dụng hoạt động
Container chạy trong một môi trường tương đối độc lập với hệ điều hành của máy chủ. Docker mô tả container là các process được cô lập, có filesystem và network riêng. (Docker Documentation)
Nhờ Docker, cùng một container có thể được sử dụng trong nhiều môi trường khác nhau như:
Developer → Testing → Staging → Production
Điều này giúp giảm đáng kể sự khác biệt giữa môi trường phát triển và môi trường thật.
2. Image và Container khác nhau như thế nào?
Khi mới học Docker, hai khái niệm dễ gây nhầm lẫn nhất là Image và Container.
Có thể hiểu đơn giản:
Docker Image giống như một bản mẫu để tạo ứng dụng.
Ví dụ:
node:22
nginx:latest
mysql:8
redis:latestCòn Container là phiên bản đang chạy được tạo ra từ Image.
Có thể hình dung như sau:
Docker Image
↓
Create / Run
↓
Docker Container
↓
Application RunningMột Image có thể tạo ra nhiều Container khác nhau.
Ví dụ:
nginx image
↓
container-1
container-2
container-3Docker Image còn được xây dựng theo nhiều layer và các layer có thể được tái sử dụng giữa nhiều image khác nhau. (Docker Documentation)
3. Vì sao nên sử dụng Docker?
Chạy giống nhau trên nhiều môi trường
Nếu ứng dụng chạy được trong Docker trên máy của developer thì chúng ta có thể sử dụng cùng Docker Image đó để triển khai lên server.
Điều này giúp hạn chế lỗi liên quan đến:
Node version khác nhau
Package version khác nhau
OS khác nhau
Configuration khác nhauDeploy dễ dàng hơn
Thay vì phải SSH vào server rồi cài Node.js, npm và nhiều package khác, chúng ta chỉ cần cài Docker.
Sau đó pull image:
docker pull my-applicationvà chạy:
docker run my-applicationDễ rollback
Ví dụ production đang chạy:
my-app:v1.0Sau khi deploy:
my-app:v1.1nếu phiên bản mới gặp lỗi, chúng ta có thể quay lại:
my-app:v1.0nhanh hơn so với việc build lại toàn bộ hệ thống.
Phù hợp với CI/CD
Docker thường được kết hợp với:
GitHub Actions
GitLab CI
AWS
Azure
Google Cloud
KubernetesQuy trình thường có dạng:
Developer push code
↓
GitHub
↓
GitHub Actions
↓
Build Docker Image
↓
Push Docker Image
↓
Server pull Image
↓
Run Container4. Ví dụ đơn giản với Nginx
Giả sử máy đã cài Docker.
Bạn có thể chạy một web server Nginx chỉ bằng một câu lệnh:
docker run -d -p 8080:80 --name my-nginx nginxTrong đó:
docker rundùng để tạo và chạy container.
-dcho container chạy ở background.
-p 8080:80có nghĩa là:
Port máy tính → Port Container
8080 → 80Và:
--name my-nginxđặt tên container là:
my-nginxCuối cùng:
nginxlà Docker Image được sử dụng.
Sau khi chạy xong, mở trình duyệt và truy cập:
http://localhost:8080Nếu thấy trang Welcome to nginx! nghĩa là container đã chạy thành công.
5. Một số lệnh Docker thường dùng
Kiểm tra những container đang chạy:
docker psKiểm tra tất cả container:
docker ps -aXem Docker Image:
docker imagesDừng container:
docker stop my-nginxKhởi động lại:
docker start my-nginxXóa container:
docker rm my-nginxXem log:
docker logs my-nginxTheo dõi log realtime:
docker logs -f my-nginxĐây là những câu lệnh cơ bản nhưng được sử dụng rất thường xuyên khi quản lý ứng dụng chạy bằng Docker.
6. Docker trong một dự án thực tế
Ví dụ một website có kiến trúc:
Angular
↓
NestJS
↓
MySQL
↓
RedisChúng ta có thể chia thành nhiều container:
┌───────────────────┐
│ Angular Container │
└─────────┬─────────┘
│
↓
┌───────────────────┐
│ NestJS Container │
└─────────┬─────────┘
│
┌────┴────┐
↓ ↓
┌─────────┐ ┌─────────┐
│ MySQL │ │ Redis │
└─────────┘ └─────────┘Mỗi thành phần chạy độc lập nhưng vẫn có thể giao tiếp với nhau thông qua Docker Network.
Với ứng dụng có nhiều container, Docker Compose thường được sử dụng để quản lý toàn bộ hệ thống thay vì chạy từng container thủ công. Docker cũng hướng dẫn Compose như một cách đơn giản hóa việc chạy các ứng dụng nhiều container. (Docker Documentation)
Ví dụ:
services:
backend:
image: my-backend
ports:
- "3000:3000"
database:
image: mysql:8
redis:
image: redis:latestSau đó có thể chạy toàn bộ hệ thống bằng:
docker compose up -d7. Docker có thay thế máy ảo không?
Docker và Virtual Machine có mục đích tương tự ở một số khía cạnh nhưng cách hoạt động khác nhau.
Virtual Machine thường chạy cả một hệ điều hành riêng.
Server
├── Ubuntu VM
├── Windows VM
└── Ubuntu VMTrong khi Docker Container sử dụng chung kernel của hệ điều hành host:
Server
↓
Operating System
↓
Docker
├── Container A
├── Container B
└── Container CDo đó container thường nhẹ hơn và khởi động nhanh hơn máy ảo. Docker cũng mô tả container là lớp ảo hóa ở mức application, trong khi VM ảo hóa ở mức phần cứng. (Docker)
Kết luận
Docker là một công cụ rất hữu ích đối với lập trình viên, đặc biệt khi ứng dụng bắt đầu được triển khai lên server hoặc cloud.
Bạn chỉ cần nhớ ba khái niệm cơ bản:
Dockerfile
↓
Docker Image
↓
Docker ContainerDockerfile mô tả cách build ứng dụng.
Image là bản đóng gói của ứng dụng.
Container là ứng dụng đang chạy từ Image đó.
Khi đã hiểu ba khái niệm này, việc tiếp tục học Docker Compose, Docker Network, Volume và CI/CD với Docker sẽ dễ dàng hơn rất nhiều.