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

การทำแอปพลิเคชัน PHP ให้เป็นคอนเทนเนอร์

เขียน Dockerfile ของ PHP ที่พร้อมใช้งานจริง

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

เหตุใดจึงทำ PHP เป็นคอนเทนเนอร์

การส่งมอบ PHP ที่ทำซ้ำได้หมายถึงการตรึงเวอร์ชันตัวแปล ส่วนขยาย และไลบรารีของระบบปฏิบัติการให้เป็น เวอร์ชันที่แน่นอนไว้พร้อมกับโค้ดของคุณ อิมเมจ Docker ทำให้ทุกสภาพแวดล้อม ไม่ว่าจะเป็นแล็ปท็อป CI หรือระบบจริง ใช้ php -v และชุด ext-* เดียวกัน

ในบทเรียนนี้ เราจะสร้างอิมเมจที่ พร้อมใช้งานจริง ซึ่งประกอบด้วย PHP-FPM เฉพาะส่วนขยายที่จำเป็น การตั้งค่าที่ปรับแต่งแล้ว ผู้ใช้ที่ไม่ใช่ root และการตรวจสอบสุขภาพ

อิมเมจฐาน FPM เทียบกับ Apache

อิมเมจ PHP อย่างเป็นทางการมีหลายรูปแบบ สำหรับแอปเว็บที่ใช้งานจริงและอยู่หลัง nginx/traefik ควรเลือก php:8.3-fpm-alpine ซึ่งมีขนาดเล็ก หรือ php:8.3-fpm ซึ่งใช้ Debian และ glibc จึงมีปัญหาที่ไม่คาดคิดกับไลบรารีเนทีฟน้อยกว่า

  • cli — กระบวนการทำงาน คิว และงานตามกำหนดเวลา
  • fpm — ตัวจัดการกระบวนการ FastCGI ใช้คู่กับ nginx
  • apache — Apache ที่รวมมาให้ สะดวกแต่มีขนาดใหญ่กว่า

ล็อกเวอร์ชันย่อยให้แน่นอน อย่าใช้ :latest ในระบบจริง

# Base image choice in your Dockerfile
FROM php:8.3-fpm-alpine AS base

# Why alpine? ~30MB base vs ~140MB Debian.
# Tradeoff: musl libc, occasional native-extension friction.

ติดตั้งส่วนขยาย

อย่าใช้ apt install php-xxx ภายในอิมเมจเหล่านี้ ให้ใช้ตัวช่วยที่มีมาให้ ได้แก่ docker-php-ext-install docker-php-ext-configure และ pecl สคริปต์ install-php-extensions ของ mlocati เป็นทางลัดมาตรฐานโดยพฤตินัยที่ดึงส่วนหัวสำหรับการพัฒนาที่ถูกต้องมาให้คุณ

FROM php:8.3-fpm-alpine

# Grab the helper that resolves build deps automatically
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/

RUN chmod +x /usr/local/bin/install-php-extensions && \
    install-php-extensions \
        pdo_mysql \
        opcache \
        intl \
        zip \
        redis \
        bcmath

Composer ในอิมเมจ

คัดลอกไบนารี Composer จากอิมเมจอย่างเป็นทางการ แทนการดึงตัวติดตั้งผ่านเครือข่าย เรียกใช้ composer install พร้อม --no-dev และ --optimize-autoloader สำหรับระบบจริง และคัดลอกเฉพาะ composer.json/composer.lock ก่อน เพื่อให้ชั้นการพึ่งพาถูกแคชแยกจากการเปลี่ยนแปลงซอร์สโค้ด

COPY --from=composer:2 /usr/bin/composer /usr/bin/composer

WORKDIR /app

# Cache-friendly: deps layer invalidates only when lock changes
COPY composer.json composer.lock ./
RUN composer install \
        --no-dev \
        --no-scripts \
        --no-autoloader \
        --prefer-dist

COPY . .
RUN composer dump-autoload --optimize --classmap-authoritative

ปรับแต่ง php.ini

อิมเมจฐานมีแม่แบบ php.ini-production และ php.ini-development มาให้ เปิดใช้แม่แบบสำหรับระบบจริง แล้วใส่การตั้งค่าที่คุณกำหนดเองลงใน conf.d ไดเรกทอรีนี้จะถูกรวมเข้ามาเป็นลำดับสุดท้าย จึงมีผลทับการตั้งค่าก่อนหน้า

ค่าหลักสำหรับระบบจริงคือ opcache.enable=1 opcache.validate_timestamps=0 (โค้ดในอิมเมจไม่เปลี่ยนแปลง) และ memory_limit ที่กำหนดไว้อย่างเหมาะสม

# Activate production ini
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"

# Custom overrides win because conf.d loads last
COPY docker/php/zz-app.ini $PHP_INI_DIR/conf.d/zz-app.ini

ไฟล์การตั้งค่า OPcache ที่ทับค่าเดิม

นี่คือการปรับปรุงที่ให้ผลมากที่สุดอย่างหนึ่งในระบบจริง เมื่อใช้ validate_timestamps=0 PHP จะไม่ตรวจสอบข้อมูลไฟล์ในทุกคำขออีกต่อไป แต่หมายความว่าคุณ MUST สร้างอิมเมจใหม่เพื่อเผยแพร่การเปลี่ยนแปลง ซึ่งตรงกับสิ่งที่เราต้องการสำหรับคอนเทนเนอร์ที่ไม่เปลี่ยนแปลง

; docker/php/zz-app.ini
memory_limit = 256M
expose_php = Off

opcache.enable = 1
opcache.enable_cli = 0
opcache.memory_consumption = 256
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 20000
opcache.validate_timestamps = 0
opcache.preload = /app/preload.php
opcache.preload_user = www-data

ทำงานด้วยผู้ใช้ที่ไม่ใช่ Root

อิมเมจมี www-data กำหนดไว้แล้ว การเรียกใช้ FPM ด้วย root เป็นการเพิ่มพื้นที่โจมตีโดยไม่จำเป็น กำหนดเจ้าของให้เส้นทางที่เขียนได้ เช่น แคชและบันทึกการทำงาน แล้วสลับผู้ใช้ด้วย USER ก่อน CMD

มาสเตอร์ของ FPM ยังคงผูกกับพอร์ตที่สงวนไว้หรือไม่ ไม่ใช่ เพราะ FPM รับฟังที่พอร์ต 9000 ซึ่งไม่ต้องใช้สิทธิ์พิเศษ ดังนั้นการทำงานด้วยผู้ใช้ที่ไม่ใช่ root จึงทำได้โดยตรง

# Make runtime-writable dirs owned by the runtime user
RUN chown -R www-data:www-data /app/var /app/storage 2>/dev/null || true

USER www-data

EXPOSE 9000
CMD ["php-fpm"]

การตรวจสอบสุขภาพ

ระบบจัดการคอนเทนเนอร์ต้องการสัญญาณว่า FPM ยังทำงานอยู่จริง ไม่ใช่เพียงมีกระบวนการอยู่เท่านั้น cgi-fcgi สามารถส่งคำขอ ping ไปยังจุดปลายทาง /status หรือ /ping ของ FPM ได้ ก่อนอื่นให้เปิดใช้ pm.status_path และ ping.path ในกลุ่มการทำงานของ FPM

# In www.conf pool config:
;   ping.path = /ping
;   ping.response = pong

# Dockerfile HEALTHCHECK using cgi-fcgi
RUN install-php-extensions @composer >/dev/null 2>&1 || true

HEALTHCHECK --interval=10s --timeout=3s --retries=3 \
  CMD SCRIPT_NAME=/ping SCRIPT_FILENAME=/ping REQUEST_METHOD=GET \
      cgi-fcgi -bind -connect 127.0.0.1:9000 || exit 1

ประกอบ Dockerfile

นี่คือ Dockerfile สำหรับใช้งานจริงแบบขั้นตอนเดียวที่จัดโครงสร้างไว้อย่างเป็นระบบ ในบทเรียนถัดไป เราจะแยกเป็นหลายขั้นตอนเพื่อตัดเครื่องมือสำหรับการสร้างออก โปรดสังเกตลำดับ: การอ้างอิงแพ็กเกจ → การกำหนดค่า → ซอร์สโค้ด → การสร้างตัวโหลดอัตโนมัติ → การสลับผู้ใช้

FROM php:8.3-fpm-alpine

ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
RUN chmod +x /usr/local/bin/install-php-extensions && \
    install-php-extensions pdo_mysql opcache intl zip redis

COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
WORKDIR /app

RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
COPY docker/php/zz-app.ini $PHP_INI_DIR/conf.d/

COPY composer.json composer.lock ./
RUN composer install --no-dev --no-scripts --no-autoloader --prefer-dist
COPY . .
RUN composer dump-autoload --optimize --classmap-authoritative && \
    chown -R www-data:www-data /app/var

USER www-data
EXPOSE 9000
CMD ["php-fpm"]

ตรวจสอบการสร้าง

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

<?php
// Run inside the container: php verify.php
echo 'PHP ' . PHP_VERSION . PHP_EOL;

$required = ['pdo_mysql', 'opcache', 'intl', 'zip'];
foreach ($required as $ext) {
    printf("%-12s %s\n", $ext, extension_loaded($ext) ? 'OK' : 'MISSING');
}

var_dump((bool) ini_get('opcache.enable'));
?>

จัดระเบียบบริบทการสร้าง

.dockerignore ช่วยให้บริบทการสร้างมีขนาดเล็ก และป้องกันไม่ให้ข้อมูลลับหรือไฟล์จาก vendor ที่มีขนาดใหญ่รั่วไหลเข้าไปในอิมเมจจนทำให้แคชใช้ไม่ได้ ให้ยกเว้น vendor, VCS, ไฟล์ env และเครื่องมือในเครื่อง

# .dockerignore
.git
.gitignore
vendor/
node_modules/
.env
.env.*
tests/
*.md
docker-compose*.yml
storage/logs/*
var/cache/*

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

เหตุใดจึงควรกำหนด opcache.validate_timestamps=0 ในอิมเมจสำหรับใช้งานจริง

สรุปทบทวน

คุณสร้างอิมเมจ PHP-FPM สำหรับใช้งานจริง โดยใช้ฐาน 8.3-fpm-alpine ที่ระบุเวอร์ชันแน่นอน ติดตั้งเฉพาะส่วนขยายที่จำเป็นผ่านสคริปต์ติดตั้ง คัดลอก Composer และแคชของการอ้างอิงแพ็กเกจไว้ในเลเยอร์ของตัวเอง เปิดใช้ php.ini สำหรับใช้งานจริงพร้อมการตั้งค่า OPcache เพิ่มเติม สลับไปใช้ผู้ใช้ www-data และเพิ่มการตรวจสอบสุขภาพของ FPM

แนวปฏิบัติสำคัญ: ระบุเวอร์ชันให้แน่นอน แคชเลเยอร์ของการอ้างอิงแพ็กเกจ ทำงานโดยไม่ใช้สิทธิ์ผู้ใช้ราก ปิดการตรวจสอบประทับเวลา และรักษาบริบทการสร้างให้กระชับด้วย .dockerignore

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

บทเรียน “การทำแอปพลิเคชัน PHP ให้เป็นคอนเทนเนอร์” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “การทำแอปพลิเคชัน PHP ให้เป็นคอนเทนเนอร์”

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

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

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

บทเรียน “การทำแอปพลิเคชัน PHP ให้เป็นคอนเทนเนอร์” ใช้เวลานานแค่ไหน

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

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

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

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

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