39 - Docker และ Docker Compose
เป้าหมายของบท
Section titled “เป้าหมายของบท”บทนี้จะเพิ่ม Dockerfile และ Docker Compose เพื่อรัน Backend API กับ PostgreSQL ใน environment ที่ทำซ้ำได้
หลังจบบทนี้ผู้อ่านควรเข้าใจ:
- Dockerfile ใช้ทำอะไร
- Docker Compose ใช้รันหลาย service อย่างไร
- ทำไมใน container ต้องใช้ host
postgresไม่ใช่localhost - ส่ง environment variables เข้า container อย่างไร
- ใช้ healthcheck และ depends_on อย่างไร
สร้าง Dockerfile
Section titled “สร้าง Dockerfile”สร้างไฟล์:
DockerfileFROM eclipse-temurin:25-jre
WORKDIR /app
COPY build/libs/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]ก่อน build image ต้อง build jar:
.\gradlew.bat clean buildสร้าง docker-compose.yml
Section titled “สร้าง docker-compose.yml”services: postgres: image: postgres:18 container_name: backend-postgres environment: POSTGRES_DB: secure_admin POSTGRES_USER: postgres POSTGRES_PASSWORD: admin123 ports: - "5432:5432" volumes: - postgres-data:/var/lib/postgresql healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres -d secure_admin"] interval: 5s timeout: 5s retries: 10
api: build: . container_name: backend-api environment: SPRING_PROFILES_ACTIVE: prod DB_URL: jdbc:postgresql://postgres:5432/secure_admin DB_USERNAME: postgres DB_PASSWORD: admin123 JWT_SECRET: 0123456789012345678901234567890123456789012345678901234567890123 ports: - "8080:8080" depends_on: postgres: condition: service_healthy
volumes: postgres-data:สำหรับ postgres:18 ขึ้นไป ให้ mount volume ที่ /var/lib/postgresql
ไม่ใช่ /var/lib/postgresql/data เพราะ image รุ่นใหม่จัดเก็บ data directory แบบแยกตาม major version ภายใน path นี้
ถ้าใช้ path เก่า container อาจ start ไม่ขึ้นและแจ้งว่า data อยู่ใน unused mount/volume
localhost ใน container
Section titled “localhost ใน container”ในเครื่องเรา PostgreSQL อาจอยู่ที่:
localhost:5432แต่ใน Docker Compose service api ต้องต่อไปที่:
postgres:5432เพราะ localhost ภายใน container หมายถึง container ตัวเอง ไม่ใช่ service PostgreSQL
คำสั่งใช้งาน
Section titled “คำสั่งใช้งาน”build jar:
.\gradlew.bat clean buildรัน compose:
docker compose up --buildหยุด:
docker compose downลบ volume database:
docker compose down -vใช้ -v ด้วยความระวัง เพราะข้อมูล PostgreSQL จะหาย
ไม่ควร commit secret จริง
Section titled “ไม่ควร commit secret จริง”ตัวอย่างนี้ใส่ password เพื่อการเรียน แต่ในงานจริงควรใช้ .env หรือ secret manager
ตัวอย่าง .env:
DB_PASSWORD=change-meJWT_SECRET=change-me-to-long-random-secretแล้ว compose อ่าน:
DB_PASSWORD: ${DB_PASSWORD}JWT_SECRET: ${JWT_SECRET}แบบฝึกหัดท้ายบท
Section titled “แบบฝึกหัดท้ายบท”- สร้าง
Dockerfile - สร้าง
docker-compose.yml - build jar
- รัน
docker compose up --build - เรียก
/swagger-ui/index.html - ลองเปลี่ยน
DB_URLเป็นlocalhostแล้วดู error จากนั้นเปลี่ยนกลับเป็นpostgres