Docker là một trong những công cụ phổ biến để triển khai ứng dụng, và MongoDB – một cơ sở dữ liệu NoSQL mạnh mẽ cũng không ngoại lệ với sự phổ biến nhờ tính linh hoạt và hiệu năng cao. Việc kết hợp Docker với MongoDB, hay nói cách khác là chạy MongoDB trong container không chỉ giúp việc thử nghiệm, phát triển trở nên dễ dàng mà còn giúp triển khai mà không lo về xung đột phần mềm hay môi trường.
Đọc bài viết này để hiểu rõ hơn về:
- Cách triển khai MongoDB bằng Docker
- Quản lý MongoDB với Docker
- Một số vấn đề thường gặp khi cài đặt MongoDB bằng Docker
Tổng quan về MongoDB
MongoDB là một cơ sở dữ liệu NoSQL dạng document (document-oriented database) và lưu trữ dữ liệu dưới dạng các document BSON (Binary JSON). BSON là phiên bản binary của JSON, được tối ưu hóa cho hiệu suất lưu trữ và truy vấn, đồng thời hỗ trợ các kiểu dữ liệu bổ sung như Date, ObjectId, và Binary data mà JSON thuần túy không có.
Khác với cơ sở dữ liệu quan hệ (RDBMS) truyền thống, MongoDB không yêu cầu schema cố định, giúp người dùng dễ dàng thay đổi cấu trúc dữ liệu mà không cần thực hiện các thao tác migrate phức tạp.
Một số tính năng nổi bật của MongoDB bao gồm:
- Lưu trữ dữ liệu linh hoạt: Dữ liệu được tổ chức theo dạng document, mỗi document tương đương một bản ghi JSON, cho phép lưu trữ thông tin phức tạp mà không cần quan hệ nhiều bảng.
- Aggregation Framework: Cung cấp khả năng truy vấn, phân tích và xử lý dữ liệu mạnh mẽ ngay trong cơ sở dữ liệu, thay thế các thao tác phức tạp trong ứng dụng.
- Replication (Sao chép dữ liệu): Hỗ trợ replica set để đảm bảo dữ liệu được sao lưu liên tục và duy trì tính sẵn sàng cao khi có sự cố phần cứng hay phần mềm.
- Sharding (Phân mảnh dữ liệu): Cho phép phân tán dữ liệu trên nhiều node, giúp hệ thống dễ dàng mở rộng theo chiều ngang khi khối lượng dữ liệu tăng lên.
- Indexing mạnh mẽ: Hỗ trợ nhiều loại index, bao gồm single-field, compound, geospatial và text indexes, giúp truy vấn dữ liệu nhanh chóng và tối ưu.
- Hỗ trợ ACID Transactions: Từ phiên bản 4.0 trở đi, MongoDB hỗ trợ hỗ trợ giao dịch ACID đa tài liệu (multi-document ACID transactions), đảm bảo tính nhất quán dữ liệu trong các thao tác phức tạp.
MongoDB phù hợp với nhiều ứng dụng từ các ứng dụng web, mobile, đến các hệ thống big data, phân tích thời gian thực hay các dự án yêu cầu mở rộng linh hoạt. MongoDB cũng cung cấp MongoDB Atlas – dịch vụ cloud database được quản lý hoàn toàn, giúp triển khai và vận hành dễ dàng hơn. Với khả năng kết hợp tốc độ, tính linh hoạt và khả năng mở rộng, MongoDB rất được ưa chuộng và là một trong những cơ sở dữ liệu NoSQL phổ biến nhất hiện nay.
Đọc chi tiết: MongoDB là gì? Định nghĩa và Hiểu rõ A-Z về MongoDB
Tổng quan về Docker
Docker là một nền tảng containerization (đóng gói ứng dụng vào container) cho phép triển khai và chạy ứng dụng một cách nhất quán và có thể di động giữa các môi trường khác nhau, từ máy tính cá nhân, server on-premises đến các môi trường đám mây.
Các khái niệm chính trong Docker:
- Container: Là môi trường cô lập để chạy ứng dụng, bao gồm ứng dụng, các thư viện, gói phần mềm hỗ trợ (dependencies) và các thiết lập cần thiết. Các container chạy độc lập nhau, không ảnh hưởng đến hệ điều hành chủ hoặc các container khác.
- Image: Là bản sao tĩnh của một container, chứa lightweight OS (hệ điều hành tối giản chỉ bao gồm những thành phần cốt lõi cần thiết), ứng dụng và các phần mềm hỗ trợ (dependencies). Người dùng có thể tạo nhiều container khác nhau từ cùng một image.
- Dockerfile: Là file text chứa các hướng dẫn để build Docker image tự động, định nghĩa các bước cài đặt, cấu hình môi trường và ứng dụng.
- Docker Hub: Là kho lưu trữ các Docker image, nơi người dùng có thể tải (pull) image từ cộng đồng hoặc từ nhà cung cấp chính thức.
- Volume (ổ lưu trữ): Là nơi lưu trữ dữ liệu bền vững – nghĩa là dữ liệu không bị mất khi container dừng hoặc bị xóa, giúp bảo vệ dữ liệu quan trọng của ứng dụng.
Đọc chi tiết: Docker là gì? Hãy để Senior DevOps Engineer trả lời cho bạn!
MongoDB Docker Container là gì?
MongoDB Docker Container là một container Docker đã cài sẵn MongoDB, giúp:
- Triển khai MongoDB nhanh chóng mà không cần cài trực tiếp trên máy.
- Chạy nhiều bản MongoDB độc lập trên cùng một máy mà không xung đột.
- Cô lập môi trường MongoDB, tránh ảnh hưởng đến hệ thống chủ.
- Dễ dàng mở rộng hoặc quản lý MongoDB nhờ Docker.
- Kết hợp với volume để lưu dữ liệu MongoDB lâu dài, ngay cả khi container bị dừng hoặc xóa.
- Triển khai nhất quán giữa các môi trường development, testing và production.
Ví dụ khi chạy lệnh:
docker run -d --name my-mongodb -p 27017:27017 mongo
- Trong đó:
docker run
: Tạo và chạy một container mới.-d
: Chạy container ở chế độ detached (tách nền, không chiếm terminal).--name my-mongodb
: Đặt tên container là “my-mongodb“.-p 27017:27017
: Map cổng port 27017 của container sang máy chủ.mongo
: Image chính thức của MongoDB từ Docker Hub.
Lệnh với volume để lưu trữ dữ liệu:
docker run -d --name my-mongodb -p 27017:27017 -v mongo-data:/data/db mongo
Trong đó -v mongo-data:/data/db tạo volume có tên mongo-data để lưu trữ dữ liệu MongoDB bền vững.
Triển khai và chạy MongoDB bằng Docker
Để có thể triển khai và sử dụng MongoDB bằng docker ta cần chuẩn bị sẵn docker trên máy. Bạn có thể tham khảo trang web chính thức của Docker để tải phiên bản phù hợp với hệ điều hành của mình tại đây.
1. Chạy MongoDB trong Docker
Cách 1: Sử dụng image chính thức mongo (Được khuyên dùng)
# Tải và chạy MongoDB phiên bản mới nhất
docker run --name mongodb -d mongo
# Hoặc chỉ định phiên bản cụ thể
docker run --name mongodb -d mongo:7.0
Cách 2: Sử dụng MongoDB Community Server
export MONGODB_VERSION=6.0-ubi8
docker run --name mongodb -d mongodb/mongodb-community-server:$MONGODB_VERSION
- Trong đó:
-d
(detached mode): chạy container ở chế độ nền, không chiếm cửa sổ terminal.--name mongodb
: đặt tên container để dễ quản lý.mongodb/mongodb-community-server:$MONGODB_VERSION
: là image MongoDB chính thức, với phiên bản 6.0 dựa trên hệ điều hành Red Hat UBI.
Nếu muốn kết nối MongoDB từ các ứng dụng khác trên máy tính, ta ánh xạ cổng 27017:
docker run --name mongodb -d -p 27017:27017 mongodb/mongodb-community-server:$MONGODB_VERSION
=> Bây giờ, bạn đã có thể truy cập MongoDB qua mongodb://localhost:27017
bằng MongoDB Compass hoặc Mongo Shell.
2. Lưu trữ dữ liệu lâu dài
Dữ liệu trong container sẽ mất khi ta xóa container. Để giữ dữ liệu lâu dài, ta có thể dùng volume Docker:
docker run --name mongodb -d -p 27017:27017 -v $(pwd)/data:/data/db mongodb/mongodb-community-server:$MONGODB_VERSION
- Trong đó:
-v $(pwd)/data:/data/db
: ánh xạ thư mụcdata
trên máy vào/data/db
trong container. Dữ liệu MongoDB sẽ được lưu ở đây và không bị mất khi container bị xóa hoặc khởi động lại.
3. Chạy MongoDB cùng mạng với các container khác
Nếu ứng dụng của bạn cũng chạy trong container, bạn có thể để MongoDB tham gia cùng một Docker network như sau:
docker run --name mongodb -d --network mongodb mongodb/mongodb-community-server:$MONGODB_VERSION
=> Các container trong cùng mạng có thể kết nối MongoDB bằng mongodb://mongodb:27017
.
4. Tạo user với quyền root
Ta có thể khởi tạo MongoDB với tài khoản root bằng biến môi trường:
docker run --name mongodb -d -p 27017:27017 \
-e MONGO_INITDB_ROOT_USERNAME=user \
-e MONGO_INITDB_ROOT_PASSWORD=pass \
mongodb/mongodb-community-server:$MONGODB_VERSION
- Trong đó:
MONGO_INITDB_ROOT_USERNAME
vàMONGO_INITDB_ROOT_PASSWORD
giúp tạo user với quyền quản trị (root).
5. Quản lý dữ liệu từ container khác
Ta có thể sử dụng các công cụ đi kèm MongoDB như mongosh
, mongoimport
hoặc mongoexport
từ một container khác. Ví dụ, để xuất dữ liệu từ một collection ra file JSON:
docker run -it -v $(pwd):/tmp mongodb/mongodb-community-server:$MONGODB_VERSION \
mongoexport --collection=users --out=/tmp/users.json "mongodb://user:pass@localhost:27017/mydb"
- Trong đó:
-v $(pwd):/tmp
: ánh xạ thư mục hiện tại trên máy host vào /tmp trong container để lưu file JSON.
Một số thao tác quản lý MongoDB trên Docker
1. Truy cập MongoDB từ container khác
Để quản lý dữ liệu hoặc chạy các lệnh MongoDB, ta có thể sử dụng một container khác chứa công cụ Mongo Shell (mongosh) để thao tác trực tiếp với cơ sở dữ liệu:
docker run -it --network mongodb \
mongodb/mongodb-community-server:$MONGODB_VERSION \
mongosh --uri="mongodb://user:pass@mongodb:27017/mydb"
- Trong đó:
--network mongodb
cho phép container mới kết nối trực tiếp với container MongoDB trong cùng mạng.mongosh
là công cụ dòng lệnh để tương tác với MongoDB, như tạo cơ sở dữ liệu, collection hoặc truy vấn dữ liệu. Sử dụng tham số –uri để chỉ định chuỗi kết nối, đảm bảo tương thích với các phiên bản MongoDB mới hơn.
2. Nhập và xuất dữ liệu
Ta có thể sử dụng các công cụ đi kèm MongoDB để nhập (mongoimport) hoặc xuất (mongoexport) dữ liệu như sau:
- Xuất dữ liệu ra file JSON:
docker run -it -v $(pwd):/tmp \
mongodb/mongodb-community-server:$MONGODB_VERSION \
mongoexport --collection=users --out=/tmp/users.json --uri="mongodb://user:pass@mongodb:27017/mydb"
- Nhập dữ liệu từ file JSON:
docker run -it -v $(pwd):/tmp \
mongodb/mongodb-community-server:$MONGODB_VERSION \
mongoimport --drop --collection=users --uri="mongodb://user:pass@mongodb:27017/mydb" /tmp/users.json
- Trong đó:
-v $(pwd):/tmp
ánh xạ thư mục hiện tại trên máy host vào container để truy cập file.- –uri: Chỉ định chuỗi kết nối MongoDB, thay vì tách riêng host, port, và database, để đảm bảo tương thích.
--drop
xóa collection hiện tại trước khi nhập dữ liệu mới.
3. Sử dụng Docker Compose để quản lý nhiều container
Nếu ứng dụng của bạn và MongoDB cùng chạy trong container thì Docker Compose sẽ giúp khởi động, dừng và quản lý chúng cùng lúc như sau:
- Ví dụ với file
docker-compose.yaml
:
version: '3'
services:
myapp:
image: myapp:1.0
environment:
- MONGODB_CONNSTRING=mongodb://user:pass@mongodb:27017/mydb
# truyền chuỗi kết nối MongoDB cho ứng dụng thông qua biến môi trường
depends_on:
- mongodb
# đảm bảo container MongoDB chạy trước ứng dụng
mongodb:
image: mongodb/mongodb-community-server:6.0-ubi8
environment:
- MONGO_INITDB_ROOT_USERNAME=user
- MONGO_INITDB_ROOT_PASSWORD=pass
# tạo tài khoản root khi khởi tạo MongoDB
volumes:
- ./data:/data/db
# lưu dữ liệu ra thư mục data trên máy host để không mất khi container bị xóa
- Và khởi động hệ thống với lệnh:
docker-compose up
# Docker Compose sẽ chạy đồng thời container ứng dụng và MongoDB
4. Dừng và xóa container
Ta cũng có thể dừng hoặc xóa container MongoDB khi cần:
docker stop mongodb # dừng container MongoDB
docker rm mongodb # xóa container MongoDB
# nếu dùng volume, dữ liệu vẫn được giữ an toàn
Một số vấn đề thường gặp khi cài đặt MongoDB bằng Docker
1. Container MongoDB không khởi động
Nếu container MongoDB không chạy được, hãy kiểm tra lại các lệnh Docker mà bạn dùng để khởi tạo container. Cụ thể:
- Đảm bảo tên image (Docker image) đúng. Ví dụ: mongodb/mongodb-community-server:6.0-ubi8. Kiểm tra danh sách image trên Docker Hub hoặc chạy docker images để xác nhận image đã được tải.
- Kiểm tra port ánh xạ (ví dụ mặc định MongoDB dùng 27017).
- Kiểm tra các biến môi trường (environment variables) như username và password. Nếu thiếu hoặc sai, container có thể không khởi tạo được cơ sở dữ liệu.
Ta có thể xem log của container để biết chi tiết lỗi như sau:
docker logs mongodb # kiểm tra thông báo lỗi từ container
2. Vấn đề kết nối
Nếu ứng dụng không kết nối được tới MongoDB trong Docker, bạn nên:
- Đảm bảo hostname và port đúng. Nếu MongoDB chạy trong container, sử dụng tên container (ví dụ: mongodb) thay vì localhost. Cổng mặc định là 27017.
- Kiểm tra mạng Docker (Docker network) để container ứng dụng và MongoDB có thể giao tiếp. Chạy lệnh docker network ls để xem danh sách mạng, và đảm bảo cả hai container cùng thuộc một mạng (ví dụ: –network mongodb-network).
- Xác nhận lại thông tin đăng nhập (username, password) trước khi bật tính năng xác thực. Nếu chưa bật xác thực, thử kết nối mà không cần thông tin đăng nhập (mongodb://mongodb:27017/mydb).
3. Dữ liệu bị mất khi container dừng
Theo mặc định, dữ liệu trong container không được lưu trữ lâu dài. Nếu container bị xóa, dữ liệu sẽ mất. Tuy nhiên ta có thể sử dụng Docker volumes hoặc host bind mounts để lưu dữ liệu ra bên ngoài container như sau:
docker run -d -v $(pwd)/data:/data/db --name mongodb mongo
# Dữ liệu MongoDB trong container được lưu tại thư mục ./data trên máy chủ
Câu hỏi thường gặp về MongoDB Docker
MongoDB Docker có phù hợp cho production không?
Câu trả lời là Có, nếu bạn áp dụng đúng các biện pháp triển khai và bảo mật sau:
- Lưu dữ liệu ra ngoài container bằng Docker volume hoặc bind mount (ví dụ:
-v mongodb-data:/data/db
) để đảm bảo dữ liệu không bị mất khi container dừng. - Cấp đủ tài nguyên (CPU, RAM, disk I/O) cho container để đảm bảo hiệu suất. Ví dụ: Sử dụng
docker run --cpus="2" --memory="4g"
để giới hạn tài nguyên. - Bật xác thực và sử dụng SSL/TLS để bảo mật kết nối. Đảm bảo giám sát hiệu suất (sử dụng công cụ như Prometheus hoặc MongoDB Atlas) và sao lưu định kỳ.
- Cấu hình mạng Docker (ví dụ: sử dụng
--network
) để đảm bảo ứng dụng và MongoDB giao tiếp an toàn. Với các biện pháp này, MongoDB trong Docker hoàn toàn phù hợp cho môi trường production, đặc biệt trong các hệ thống sử dụng microservices.
Làm thế nào để backup dữ liệu trong container?
Để backup dữ liệu MongoDB trong Docker, ta có thể dùng mongoexport hoặc mongodump. Ví dụ:
docker run -it -v $(pwd)/backup:/backup mongodb/mongodb-community-server:6.0-ubi8 \
mongodump --out /backup
# // Lệnh mongodump sao chép toàn bộ dữ liệu MongoDB vào thư mục /backup trên máy host
- Trong đó:
-v $(pwd)/backup:/backup
: gắn thư mục backup trên máy host vào container để dữ liệu được lưu ra ngoài.mongodump
: công cụ của MongoDB để xuất toàn bộ database.
Ngoài ra, nếu dùng Docker volume, ta có thể trực tiếp backup volume bằng các lệnh Docker mà không cần vào container.
MongoDB container có hỗ trợ replica set không?
MongoDB container có hỗ trợ replica set, cho phép tạo nhiều node MongoDB để:
- Tăng tính sẵn sàng (availability).
- Đảm bảo dữ liệu không mất khi một node gặp sự cố.
Ví dụ:
docker network create mongo-net
docker run -d --name mongo1 --network mongo-net -e MONGO_INITDB_REPLICA_SET_NAME=rs0 mongo
docker run -d --name mongo2 --network mongo-net -e MONGO_INITDB_REPLICA_SET_NAME=rs0 mongo
docker run -d --name mongo3 --network mongo-net -e MONGO_INITDB_REPLICA_SET_NAME=rs0 mongo
docker exec -it mongo1 mongosh
# Trong shell MongoDB, khởi tạo replica set:
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "mongo1:27017" },
{ _id: 1, host: "mongo2:27017" },
{ _id: 2, host: "mongo3:27017" }
]
})
- Trong đó:
MONGO_INITDB_REPLICA_SET_NAME=rs0
: xác định tên replica set.docker network create mongo-net
: các container trong cùng network có thể kết nối với nhau.
Tổng kết
Kết hợp MongoDB và Docker là một lựa chọn tối ưu giúp tiết kiệm thời gian cài đặt nhưng vẫn đảm bảo hiệu suất và tính ổn định. Từ việc khởi tạo container, kết nối ứng dụng, cho đến quản lý và khắc phục sự cố, tất cả đều có thể thực hiện chỉ với vài dòng lệnh.
ITViec hy vọng bài viết trên đã cung cấp cho bạn những thông tin hữu ích về “cặp đôi” MongoDB và Docker.