0Pricing
PHP Academy · บทเรียน

Docker Compose สำหรับชุดบริการภายในเครื่อง

เรียกใช้ PHP ฐานข้อมูล และแคชร่วมกันภายในเครื่อง

Docker Compose สำหรับชุดบริการภายในเครื่อง เป็นบทเรียน PHP Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน PHP Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส PHP Academy มีบทเรียนทั้งหมด 4 บทเรียน

สแตกในเครื่องด้วย Compose

แอป PHP จริงไม่เคยมีแค่ PHP เพราะต้องใช้ฐานข้อมูล แคช และบางครั้งยังต้องใช้คิวกับตัวดักอีเมลด้วย Docker Compose จะประกาศสิ่งเหล่านี้เป็นบริการต่าง ๆ ในไฟล์เดียว และเชื่อมบริการทั้งหมดเข้ากับเครือข่ายร่วม เพื่อให้บริการเหล่านั้นเข้าถึงกันได้ด้วยชื่อ

บทเรียนนี้จะสร้างสแตกในเครื่องแบบครบชุด ได้แก่ PHP-FPM + nginx + MySQL + Redis พร้อมโวลุม การตรวจสอบสุขภาพ และการจัดลำดับการพึ่งพา

โครงสร้างบริการ

ไฟล์ Compose จะแสดงรายการบริการไว้ภายใต้ services: แต่ละบริการสามารถ build จาก Dockerfile หรือดึง image มาใช้ได้ Compose จะสร้างเครือข่ายเริ่มต้นซึ่งทุกบริการเข้าถึงได้ด้วยคีย์ของบริการนั้น ๆ โดยแอป PHP ของคุณจะเชื่อมต่อกับ MySQL ที่โฮสต์ db ไม่ใช่ localhost

services:
  app:
    build:
      context: .
      target: dev          # multi-stage dev target
    volumes:
      - ./:/app            # live code mount
    depends_on:
      db:
        condition: service_healthy
  db:
    image: mysql:8.4
  redis:
    image: redis:7-alpine

วาง nginx ไว้ด้านหน้า FPM

FPM สื่อสารด้วย FastCGI ที่พอร์ต 9000 ไม่ใช่ HTTP nginx จะรับการเชื่อมต่อ HTTP และส่งคำขอ .php ต่อไปยัง app:9000 การกำหนดค่า nginx จะอ้างอิงบริการ PHP ด้วยชื่อ Compose ของบริการนั้น

# docker/nginx/default.conf
server {
  listen 80;
  root /app/public;
  index index.php;

  location / {
    try_files $uri /index.php?$query_string;
  }

  location ~ \.php$ {
    fastcgi_pass app:9000;       # service name from compose
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
  }
}

เชื่อมต่อบริการเว็บ

บริการ nginx จะเมานต์โค้ดชุดเดียวกันเพื่อแก้ค่า SCRIPT_FILENAME รวมถึงไฟล์การกำหนดค่า เปิดให้เข้าถึงพอร์ต 80 และกำหนดให้ขึ้นต่อกับแอป ทั้งสองบริการใช้ /app ร่วมกัน เพื่อให้เส้นทางตรงกันทั้งสองฝั่งของ FastCGI

services:
  web:
    image: nginx:1.27-alpine
    ports:
      - "8080:80"
    volumes:
      - ./:/app:ro
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      - app

โวลุมถาวร

ระบบไฟล์ของคอนเทนเนอร์เป็นแบบชั่วคราว โวลุมที่มีชื่อจะเก็บไฟล์ฐานข้อมูลไว้ต่อเนื่องแม้เรียกใช้ docker compose down ส่วนการเมานต์แบบผูก (./:/app) จะซิงค์โค้ดจากเครื่องให้เห็นการเปลี่ยนแปลงแบบสด ๆ ในระหว่างการพัฒนา ให้ใช้โวลุมที่มีชื่อสำหรับข้อมูลที่ต้องคงอยู่ และใช้การเมานต์แบบผูกสำหรับซอร์สโค้ด

services:
  db:
    image: mysql:8.4
    environment:
      MYSQL_DATABASE: app
      MYSQL_USER: app
      MYSQL_PASSWORD: secret
      MYSQL_ROOT_PASSWORD: rootsecret
    volumes:
      - dbdata:/var/lib/mysql

volumes:
  dbdata:        # survives `down`, removed only by `down -v`

การตรวจสอบสุขภาพและ depends_on

depends_on เพียงอย่างเดียวจะรอแค่ให้คอนเทนเนอร์ เริ่มทำงาน ไม่ได้รอให้ MySQL ยอมรับการเชื่อมต่อ ให้เพิ่ม healthcheck และใช้ condition: service_healthy เพื่อให้แอปของคุณรอจนกว่าฐานข้อมูลจะพร้อมใช้งานจริง

services:
  db:
    image: mysql:8.4
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-prootsecret"]
      interval: 5s
      timeout: 3s
      retries: 10
  app:
    build: .
    depends_on:
      db:
        condition: service_healthy   # waits for healthcheck pass

สภาพแวดล้อมและ .env

Compose จะโหลด .env ที่อยู่ในโฟลเดอร์เดียวกันโดยอัตโนมัติเพื่อแทนค่าตัวแปร และคุณสามารถส่งการกำหนดค่าแอปผ่าน environment หรือ env_file ได้ อย่าเก็บข้อมูลลับไว้ในไฟล์ Compose ที่คอมมิตแล้ว แต่ให้อ้างอิงตัวแปรแทน

services:
  app:
    build: .
    env_file:
      - .env
    environment:
      DATABASE_URL: "mysql://app:secret@db:3306/app"
      REDIS_URL: "redis://redis:6379"
# .env (gitignored) provides ${...} substitutions
#   MYSQL_PASSWORD=secret

เชื่อมต่อจาก PHP

ภายในเครือข่าย ชื่อโฮสต์จะเป็นชื่อบริการ โค้ด PHP ของคุณจึงเชื่อมต่อกับ db และ redis ได้โดยตรง ตัวอย่างนี้แยกวิเคราะห์ DSN ในลักษณะเดียวกับที่ชั้นการกำหนดค่าจะทำ เพื่อแสดงให้เห็นว่าชื่อบริการของ Compose ถูกส่งต่อเข้าไปในสตริงการเชื่อมต่ออย่างไร

<?php
$dsn = 'mysql://app:secret@db:3306/app';
$p = parse_url($dsn);

printf("driver: %s\n", $p['scheme']);
printf("host:   %s\n", $p['host']);   // 'db' resolves via compose DNS
printf("port:   %d\n", $p['port']);
printf("db:     %s\n", ltrim($p['path'], '/'));

$pdoDsn = sprintf('mysql:host=%s;port=%d;dbname=%s', $p['host'], $p['port'], ltrim($p['path'], '/'));
echo $pdoDsn . PHP_EOL;
?>

Xdebug สำหรับการพัฒนาในเครื่อง

ให้เมานต์การกำหนดค่า Xdebug เฉพาะในเครื่องผ่านเป้าหมายการสร้าง dev กำหนด client_host เป็น host.docker.internal เพื่อให้ตัวดีบักเชื่อมต่อไปยังเครื่องมือพัฒนาของคุณบนโฮสต์ได้ อย่าส่ง Xdebug ไปยังสภาพแวดล้อมจริง เพราะจะทำให้ประสิทธิภาพลดลงอย่างมาก

; docker/php/xdebug.ini  (mounted only in dev)
zend_extension=xdebug
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9003

เรียกใช้คำสั่งครั้งเดียว

docker compose run จะสร้างคอนเทนเนอร์ชั่วคราวสำหรับการย้ายข้อมูล การทดสอบ หรือการเรียกใช้ Composer ส่วน exec จะทำงานภายในบริการที่กำลังทำงานอยู่แล้ว ให้ใช้ run --rm สำหรับงานเหล่านี้ เพื่อให้คอนเทนเนอร์ชั่วคราวถูกล้างออก

# Run migrations against the running db
docker compose exec app php bin/console doctrine:migrations:migrate

# One-off: install deps without a long-lived container
docker compose run --rm app composer install

# Tail logs of just the web service
docker compose logs -f web

ไฟล์แทนที่

Compose จะผสาน docker-compose.yml กับ docker-compose.override.yml โดยอัตโนมัติ ให้เก็บค่าเริ่มต้นที่มีโครงสร้างเหมือนสภาพแวดล้อมจริงไว้ในไฟล์ฐาน และใส่โวลุม พอร์ต และ Xdebug ที่ใช้เฉพาะการพัฒนาไว้ในไฟล์แทนที่ เพื่อให้ CI ใช้ไฟล์ฐาน และนักพัฒนาได้รับส่วนเพิ่มเติมโดยไม่ต้องตั้งค่าเพิ่ม

# docker-compose.override.yml (auto-merged, dev only)
services:
  app:
    volumes:
      - ./docker/php/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini:ro
    environment:
      APP_ENV: dev
# CI runs: docker compose -f docker-compose.yml up  (no override)

ตรวจสอบอย่างรวดเร็ว

เหตุใด depends_on: [db] แบบธรรมดาจึงไม่เพียงพอก่อนเรียกใช้การย้ายข้อมูล

สรุปทบทวน

คุณประกอบสแตกในเครื่องด้วย Compose: PHP-FPM ที่อยู่หลัง nginx (FastCGI ไปยัง app:9000) MySQL และ Redis ที่เข้าถึงได้ด้วยชื่อบริการ โวลุมที่มีชื่อสำหรับเก็บข้อมูลถาวร การตรวจสอบสุขภาพเพื่อควบคุม depends_on การกำหนดค่าที่ขับเคลื่อนด้วย env, Xdebug ในไฟล์แทนที่ที่ใช้เฉพาะการพัฒนา และคำสั่งครั้งเดียวผ่าน run/exec

โปรดจำ: ชื่อบริการคือชื่อโฮสต์ DNS ไฟล์แทนที่ช่วยแยกส่วนเพิ่มเติมสำหรับการพัฒนาออกจาก CI และการตรวจสอบสุขภาพมีประสิทธิภาพกว่าการจัดลำดับการเริ่มทำงานแบบง่าย ๆ

คำถามที่พบบ่อย

บทเรียน “Docker Compose สำหรับชุดบริการภายในเครื่อง” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “Docker Compose สำหรับชุดบริการภายในเครื่อง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส PHP Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส PHP Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “Docker Compose สำหรับชุดบริการภายในเครื่อง”

เรียกใช้ PHP ฐานข้อมูล และแคชร่วมกันภายในเครื่อง คุณปฏิบัติ PHP Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน PHP Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน PHP Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “Docker Compose สำหรับชุดบริการภายในเครื่อง” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน PHP Academy นี้ได้ไหม

ได้ บทเรียน PHP Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การทำแอปพลิเคชัน PHP ให้เป็นคอนเทนเนอร์
  2. การสร้างหลายขั้นตอนและการปรับประสิทธิภาพ
  3. Docker Compose สำหรับชุดบริการภายในเครื่อง
  4. CI/CD ด้วย GitHub Actions
← กลับไปที่ PHP Academy