ติดตั้งด้วย Docker
วิธีที่เร็วที่สุดในการได้ MongoDB จริง ๆ มาเล่นคือ Docker image mongo ทางการให้ server ที่สะอาดและแยกตัวแก่คุณในคำสั่งเดียว โดยไม่มีอะไรติดตั้งถาวรบนเครื่องของคุณและไม่มีอะไรต้องถอนการติดตั้งทีหลัง บทเรียนนี้พาคุณจาก “Docker กำลังทำงานอยู่” ไปสู่ “ฉันคุยกับ MongoDB ได้” — เริ่มด้วยคำสั่งบรรทัดเดียว แล้วตามด้วย docker-compose.yml เล็ก ๆ ที่คุณเก็บไว้ในโปรเจกต์ได้
คุณต้องการแค่ Docker Desktop (หรือ Docker engine) ที่ติดตั้งและทำงานอยู่ ทุกอย่างที่เหลือมาจาก image
docker run บรรทัดเดียว
หัวข้อที่มีชื่อว่า “docker run บรรทัดเดียว”คำสั่งนี้ดึง image ทางการ เริ่ม container ชื่อ mongo-dev เปิดเผยพอร์ต MongoDB เริ่มต้น 27017 ออกมายังเครื่องของคุณ เก็บข้อมูลไว้ใน named volume เพื่อให้ข้อมูลอยู่รอดข้าม restart และตั้ง username และ password ของ root:
docker run -d \ --name mongo-dev \ -p 27017:27017 \ -v mongo-data:/data/db \ -e MONGO_INITDB_ROOT_USERNAME=root \ -e MONGO_INITDB_ROOT_PASSWORD=secret \ mongo:7มีบางอย่างในคำสั่งนั้นที่ควรทำความเข้าใจ:
-dรัน container ในเบื้องหลัง (detached) จะได้ไม่ยึด terminal ของคุณไว้-p 27017:27017map พอร์ต27017ของ container เข้ากับพอร์ตเดียวกันบน host ของคุณ นั่นคือที่ที่ MongoDB รับฟังโดยค่าเริ่มต้น-v mongo-data:/data/dbmount named volume ที่/data/dbที่เป็นไดเรกทอรีที่ MongoDB เขียนไฟล์ลงไป volume อยู่นอก container ดังนั้นการลบและสร้าง container ใหม่จึงไม่ทำให้ข้อมูลของคุณหาย-e MONGO_INITDB_ROOT_USERNAME/-e MONGO_INITDB_ROOT_PASSWORDสร้าง user ระดับ administrator ในครั้งแรกที่ container เริ่มต้นไดเรกทอรีข้อมูลที่ว่างเปล่า
ไฟล์ docker-compose
หัวข้อที่มีชื่อว่า “ไฟล์ docker-compose”สำหรับอะไรก็ตามที่เกินกว่าการทดสอบเร็ว ๆ, docker-compose.yml ดีกว่า: การตั้งค่าอยู่ในไฟล์ที่คุณ commit ได้ และคำสั่งเดียวก็ยกทุกอย่างขึ้นมา เวอร์ชันนี้รัน MongoDB และเพิ่ม mongo-express ที่เป็น web UI น้ำหนักเบาสำหรับเขี่ยดูข้อมูลของคุณใน browser:
services: mongo: image: mongo:7 container_name: mongo-dev restart: unless-stopped ports: - "27017:27017" environment: MONGO_INITDB_ROOT_USERNAME: root MONGO_INITDB_ROOT_PASSWORD: secret volumes: - mongo-data:/data/db
mongo-express: image: mongo-express:latest container_name: mongo-express restart: unless-stopped ports: - "8081:8081" environment: ME_CONFIG_MONGODB_ADMINUSERNAME: root ME_CONFIG_MONGODB_ADMINPASSWORD: secret ME_CONFIG_MONGODB_URL: "mongodb://root:secret@mongo:27017/" depends_on: - mongo
volumes: mongo-data:ยก stack ทั้งหมดขึ้นมาจากไดเรกทอรีที่เก็บไฟล์นั้น:
docker compose up -dเมื่อ stack ทำงานอยู่ คุณเปิด mongo-express ที่ http://localhost:8081 เพื่อเรียกดู database และ collection ใน browser service mongo-express เป็น optional ถ้าอยากได้แค่ database ก็ลบทิ้งได้
ชิ้นส่วนต่าง ๆ ประกอบกันอย่างไร
หัวข้อที่มีชื่อว่า “ชิ้นส่วนต่าง ๆ ประกอบกันอย่างไร”container รัน MongoDB และรับฟังบนพอร์ต 27017 พอร์ตที่คุณเปิดเผยส่งต่อ localhost:27017 เข้าไปในนั้น, named volume เก็บข้อมูลให้ปลอดภัยอยู่นอก container, และอะไรก็ตามที่พูดโปรโตคอล MongoDB — mongosh, Compass, หรือแอปพลิเคชันของคุณ — เชื่อมต่อผ่านพอร์ตนั้น
flowchart LR App["Your app / mongosh / Compass"] -->|"mongodb://localhost:27017"| Port["Host port 27017"] Port --> Container["mongo container"] Container -->|"writes to /data/db"| Volume["named volume: mongo-data"]
ตรวจว่ารันอยู่จริง
หัวข้อที่มีชื่อว่า “ตรวจว่ารันอยู่จริง”ตรวจว่า container ขึ้นมาแล้วด้วย docker ps:
docker psคุณควรเห็น row สำหรับ image mongo ที่มีสถานะ Up และการ map พอร์ต 0.0.0.0:27017->27017/tcp ทีนี้เชื่อมต่อด้วย shell client mongosh ติดมากับ image อยู่แล้ว คุณจึงรันได้เลยโดยไม่ต้องติดตั้งอะไรเพิ่ม:
docker exec -it mongo-dev mongosh "mongodb://root:secret@localhost:27017"ถ้าคุณมี mongosh ติดตั้งบน host แทน ให้ชี้ไปที่พอร์ตที่เปิดไว้ตรง ๆ:
mongosh "mongodb://localhost:27017"การเชื่อมต่อที่สำเร็จจะพาคุณไปที่ prompt test> จากที่นั่นการพิมพ์ db.runCommand({ ping: 1 }) แล้วได้ { ok: 1 } กลับมา ยืนยันว่า server ยังมีชีวิตและกำลังตอบสนอง
เคล็ดลับและข้อควรระวัง
หัวข้อที่มีชื่อว่า “เคล็ดลับและข้อควรระวัง”- ความคงอยู่ของข้อมูลอยู่ใน volume ไม่ใช่ใน container ตราบใดที่คุณเก็บ volume
mongo-dataไว้ คุณสามารถหยุด ลบ และสร้าง container ใหม่ได้โดยไม่สูญเสียอะไร การรันdocker volume rm mongo-dataต่างหากที่ลบข้อมูลจริง ๆ - root user ถูกสร้างเฉพาะตอน init ครั้งแรก ตัวแปร
MONGO_INITDB_ROOT_*มีผลเมื่อไดเรกทอรีข้อมูลว่างเปล่า ถ้าไปแก้ทีหลังบน volume ที่มีข้อมูลอยู่แล้ว ค่าใหม่จะไม่มีผล user เดิมยังอยู่เหมือนเดิม - พอร์ต
27017เป็นค่าเริ่มต้นของ MongoDB ถ้ามีอย่างอื่นจองพอร์ตนี้อยู่ ให้เปลี่ยนฝั่ง host ของการ map เช่น-p 27018:27017และเชื่อมต่อไปที่27018 - ปักหมุดเวอร์ชันหลัก อย่าง
mongo:7แทนที่จะเป็นmongo:latestเพื่อให้การอัปเดต image ไม่ทำให้คุณตกใจด้วยเวอร์ชัน server ที่ต่างออกไป
ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
| รัน MongoDB ผ่าน Docker | ล้างและสร้างใหม่ได้เร็ว ไม่ทิ้งอะไรถาวรบนเครื่อง และ environment ใกล้เคียง production ที่มักรัน container เหมือนกันในทีม | ต้องมี Docker engine ทำงานอยู่ตลอด และมี overhead เล็กน้อยของ container เทียบกับการรันตรง ๆ บน host |
| ติดตั้ง MongoDB บนเครื่องโดยตรง | ไม่มี layer ของ container คั่นกลาง เชื่อมต่อผ่าน localhost ตรง ๆ | reset หรือปรับเวอร์ชันยากกว่า และแต่ละเครื่องในทีมอาจลง version หรือ config ไม่ตรงกัน |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”- ลืมปักหมุด image tag แล้วใช้
mongo:latest— เวลา pull image ใหม่ เวอร์ชัน server อาจเปลี่ยนแบบไม่ตั้งใจและพัง config หรือ behavior ที่เคยพึ่งพา ควรปักหมุดเวอร์ชันหลักอย่างmongo:7เสมอ - ลบ container ด้วย
docker rmแล้วคิดว่าข้อมูลหายไปด้วย — ถ้า data อยู่ใน named volume การลบ container ไม่กระทบข้อมูล; กลับกัน คนที่ไม่ mount volume เลยแล้วแปลกใจว่าทำไม data หายทุกครั้งที่ restart container - เปิดพอร์ต
27017แบบไม่ตั้ง password แล้วเข้าใจว่าเครื่อง dev “ไม่มีใครมาแตะอยู่แล้ว” — ถ้าเครื่องมีการ expose พอร์ตออก network ภายนอกโดยไม่ตั้งใจ (เช่น cloud VM) การไม่ตั้ง authentication เปิดช่องให้คนนอกต่อเข้ามาได้ตรง ๆ
💡 ตัวอย่างจากของจริง
CI pipeline ของหลายทีม — สร้างและทำลาย container
mongoใหม่ทุกครั้งที่รัน integration test แต่ละรอบ เพื่อให้ทุก test เริ่มจาก database ที่ว่างเปล่าเหมือนกันทุกครั้ง ไม่มี state ค้างข้ามรอบทีม backend ที่ทำงานข้ามเครื่อง — commit ไฟล์
docker-compose.ymlไว้ในโปรเจกต์ เพื่อให้ทุกคนในทีม (และ CI) ได้ MongoDB เวอร์ชันเดียวกันเป๊ะด้วยคำสั่งเดียว แทนที่จะให้แต่ละคนติดตั้งเองแล้วเวอร์ชันไม่ตรงกัน