ติดตั้ง MongoDB บน Ubuntu VPS พร้อมตั้งค่าความปลอดภัย
MongoDB เป็น NoSQL database ที่เก็บข้อมูลในรูปแบบ JSON (BSON) เหมาะกับ application ที่ data structure ยืดหยุ่น หรือต้องการ horizontal scaling MongoDB ที่ expose ออกอินเทอร์เน็ตโดยไม่มี authentication เป็นหนึ่งใน attack vector ที่พบบ่อยที่สุด บทความนี้จะตั้งค่า security ให้ครบก่อนใช้งานจริง
ติดตั้ง MongoDB 7
sudo apt update
sudo apt install gnupg curl -y
# Import MongoDB GPG key
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | \
sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor
# เพิ่ม repository
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] \
https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | \
sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
sudo apt update
sudo apt install -y mongodb-org
# เริ่ม service
sudo systemctl enable --now mongod
ตั้ง Authentication (บังคับสำหรับ production)
# เข้า mongo shell
mongosh
# สร้าง admin user
use admin
db.createUser({
user: "admin",
pwd: passwordPrompt(), // ระบบจะถาม password
roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db: "admin" },
"dbAdminAnyDatabase"
]
})
exit
# เปิด authentication ใน config
sudo nano /etc/mongod.conf
# แก้ส่วน security:
security:
authorization: enabled
# ตั้ง bind IP ให้รับเฉพาะ localhost หรือ private IP
net:
bindIp: 127.0.0.1,192.168.1.10 # เพิ่ม private IP ของ app server
sudo systemctl restart mongod
สร้าง Database User สำหรับ Application
mongosh -u admin -p --authenticationDatabase admin
use myapp_db
db.createUser({
user: "appuser",
pwd: "SecurePassword123!",
roles: [{ role: "readWrite", db: "myapp_db" }]
})
exit
Backup ด้วย mongodump
# Backup database เดียว
mongodump --uri="mongodb://appuser:password@localhost/myapp_db" \
--out=/backup/mongodb/$(date +%Y%m%d)
# Restore จาก backup
mongorestore --uri="mongodb://appuser:password@localhost/myapp_db" \
--db myapp_db /backup/mongodb/20260612/myapp_db/
0 2 * * * mongodump --uri="..." --out=/backup/mongodb/$(date +\%Y\%m\%d) --gzip และลบ backup เก่ากว่า 30 วันด้วย find /backup/mongodb -mtime +30 -delete
ตรวจสอบว่า MongoDB ทำงานถูกต้อง
# ตรวจสถานะ service
systemctl status mongod
# ตรวจ authentication ทำงาน
mongosh --eval "db.adminCommand({ connectionStatus: 1 })"
# Connect ด้วย user ที่สร้าง
mongosh -u admin -p --authenticationDatabase admin --eval "show dbs"
# ตรวจ log errors
sudo tail -50 /var/log/mongodb/mongod.log | grep -i error
net.bindIp ให้แน่ใจว่าไม่ bind 0.0.0.0 ใน production ถ้า application อยู่คนละ server ให้ bind เฉพาะ private IP ระหว่างเครื่อง
แก้ปัญหาที่พบบ่อย
Error: "MongoServerError: Authentication failed"
ใส่ password ผิดหรือ authenticationDatabase ไม่ถูกต้อง admin user ต้อง authenticate กับ admin database:
# ต้องระบุ authenticationDatabase เสมอ
mongosh -u admin -p --authenticationDatabase admin
# ไม่ใช่
mongosh -u admin -p --authenticationDatabase myapp_db # ผิด
mongod ไม่ start ขึ้นมา
ตรวจ permission ของ data directory หรือ port 27017 ถูกใช้งานอยู่แล้ว:
# ตรวจ log
sudo journalctl -u mongod -n 50
# ตรวจ permission
ls -la /var/lib/mongodb /var/log/mongodb
sudo chown -R mongodb:mongodb /var/lib/mongodb /var/log/mongodb
# ตรวจ port
sudo ss -tlnp | grep 27017
MongoDB กิน RAM มากเกินไป
MongoDB ใช้ WiredTiger storage engine ที่ cache 50% ของ RAM เป็น default ปรับลงสำหรับ VPS RAM น้อย:
sudo nano /etc/mongod.conf
# เพิ่มใน storage:
storage:
wiredTiger:
engineConfig:
cacheSizeGB: 0.5 # ปรับตาม RAM ที่มี
Connection string ใน application ผิด
Connection string ที่ถูกต้องต้องระบุ authenticationDatabase ด้วย:
# ถูกต้อง
mongodb://appuser:password@localhost:27017/myapp_db?authSource=myapp_db
# ถ้า admin user
mongodb://admin:password@localhost:27017/admin?authSource=admin
คำถามที่พบบ่อย
MongoDB เหมาะกับ use case ไหน?
MongoDB เหมาะกับ: เก็บ JSON ที่ structure เปลี่ยนบ่อย (เช่น user preferences, product catalog), real-time analytics, content management ที่มี nested data, application ที่ต้องการ schema-less ไม่เหมาะกับ: transaction ที่ต้องการ ACID เต็มรูปแบบ, relational data ที่มี JOIN ซับซ้อน
MongoDB Atlas กับ self-hosted บน VPS ต่างกันอย่างไร?
MongoDB Atlas เป็น managed service ดูแลง่าย มี automatic backup, scaling, monitoring แต่ค่าใช้จ่ายสูงกว่า Self-hosted บน VPS ควบคุมได้มากกว่า ราคาถูกกว่า แต่ต้องดูแล security, backup, update เอง
จะรู้ได้อย่างไรว่า index ที่สร้างมีประสิทธิภาพดี?
ใช้ explain("executionStats") ดู query plan: db.collection.find({field: value}).explain("executionStats") ดูค่า totalDocsExamined ถ้าสูงกว่า nReturned มากแสดงว่า index ไม่ efficient หรือยังไม่มี index