การทำแอปพลิเคชัน 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 ใช้คู่กับ nginxapache— 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 \
bcmathComposer ในอิมเมจ
คัดลอกไบนารี 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การทำแอปพลิเคชัน PHP ให้เป็นคอนเทนเนอร์
- การสร้างหลายขั้นตอนและการปรับประสิทธิภาพ
- Docker Compose สำหรับชุดบริการภายในเครื่อง
- CI/CD ด้วย GitHub Actions