- Deploy เว็บ PHP บน Vercel ด้วย vercel-php
#Deploy เว็บ PHP บน Vercel ด้วย vercel-php
Vercel เหมาะกับการ Deploy Frontend และ Serverless Functions แต่ PHP ไม่ใช่ Official Runtime ของ Vercel หากต้องการนำเว็บ PHP ไปทำงานบน Vercel จึงต้องใช้ Community Runtime ชื่อ vercel-php
ณ วันที่ปรับปรุงบทความนี้ Community Runtime รุ่น vercel-php@0.9.0 รองรับ PHP 8.5 ส่วน Vercel อนุญาตให้กำหนด Runtime ที่ไม่ได้รองรับอย่างเป็นทางการผ่านพร็อพเพอร์ตี functions.runtime ในไฟล์ vercel.json
แนวทางนี้เหมาะกับเว็บ PHP ขนาดเล็ก API, Webhook, Prototype และระบบที่ออกแบบให้ทำงานแบบ Stateless หากเป็น Laravel หรือระบบขนาดใหญ่ที่ต้องใช้ Queue Worker, Scheduler, Local Session หรือเขียนไฟล์ถาวร ควรพิจารณาใช้บริการที่รองรับ PHP หรือ Container โดยตรง

#ภาพรวมสถาปัตยกรรม
ผู้ใช้ → Vercel CDN → PHP Serverless Function → ฐานข้อมูล/ที่เก็บไฟล์ภายนอก
ทุก Request ที่ต้องประมวลผลด้วย PHP จะถูกส่งไปยัง Vercel Function ส่วนฐานข้อมูล Session และไฟล์ที่ต้องเก็บถาวรควรใช้บริการภายนอก เช่น Managed MySQL/PostgreSQL, Redis หรือ Object Storage
#สิ่งที่ต้องเตรียม
- บัญชี Vercel
- Git และบัญชี GitHub, GitLab หรือ Bitbucket หากต้องการ Deploy ผ่าน Git
- Node.js และ npm สำหรับติดตั้ง Vercel CLI
- PHP ในเครื่องสำหรับทดสอบแบบ Local
ตรวจสอบเครื่องมือด้วยคำสั่งต่อไปนี้
php -v
node -v
npm -v
git --version
#1. สร้างโปรเจกต์ PHP
สร้างโครงสร้างโปรเจกต์ดังนี้
php-vercel-demo/
├── api/
│ └── index.php
├── .gitignore
└── vercel.json
Vercel ใช้ไดเรกทอรี api เป็นตำแหน่งของ Function ส่วน api/index.php จะเป็น Front Controller ของเว็บ
สร้างไฟล์ api/index.php
<?php
declare(strict_types=1);
$path = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?: '/';
$appName = getenv('APP_NAME') ?: 'PHP on Vercel';
if ($path === '/api/status') {
header('Content-Type: application/json; charset=utf-8');
echo json_encode([
'status' => 'ok',
'application' => $appName,
'php_version' => PHP_VERSION,
'time' => gmdate(DATE_ATOM),
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
exit;
}
http_response_code($path === '/' ? 200 : 404);
$title = $path === '/' ? $appName : '404 - Page Not Found';
$message = $path === '/'
? 'Deploy เว็บ PHP บน Vercel สำเร็จแล้ว'
: 'ไม่พบหน้าที่ต้องการ';
?>
<!doctype html>
<html lang="th">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?= htmlspecialchars($title, ENT_QUOTES, 'UTF-8') ?></title>
<style>
body {
min-height: 100vh;
margin: 0;
display: grid;
place-items: center;
font-family: system-ui, sans-serif;
color: #f8fafc;
background: linear-gradient(135deg, #111827, #4f46e5);
}
main {
width: min(680px, calc(100% - 48px));
padding: 48px;
border: 1px solid rgba(255, 255, 255, .18);
border-radius: 24px;
background: rgba(15, 23, 42, .72);
box-shadow: 0 24px 80px rgba(0, 0, 0, .3);
}
a { color: #c4b5fd; }
code { color: #93c5fd; }
</style>
</head>
<body>
<main>
<p>PHP <?= htmlspecialchars(PHP_VERSION, ENT_QUOTES, 'UTF-8') ?></p>
<h1><?= htmlspecialchars($message, ENT_QUOTES, 'UTF-8') ?></h1>
<p>ทดสอบ JSON API ได้ที่ <a href="/api/status"><code>/api/status</code></a></p>
</main>
</body>
</html>
ตัวอย่างนี้มีสองเส้นทาง
/แสดงหน้าเว็บ PHP/api/statusส่งผลลัพธ์รูปแบบ JSON
#2. ตั้งค่า vercel.json
สร้างไฟล์ vercel.json ที่ Root ของโปรเจกต์
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"functions": {
"api/index.php": {
"runtime": "vercel-php@0.9.0"
}
},
"rewrites": [
{
"source": "/(.*)",
"destination": "/api/index.php"
}
]
}
ส่วนประกอบสำคัญมีดังนี้
| การตั้งค่า | หน้าที่ |
|---|---|
functions |
ระบุไฟล์ PHP ที่จะถูกสร้างเป็น Vercel Function |
runtime |
กำหนด Community Runtime และตรึงเวอร์ชันที่ต้องการ |
rewrites |
ส่ง URL ของเว็บไปยัง api/index.php |
Vercel ตรวจสอบไฟล์ที่มีอยู่จริงก่อนใช้ Rewrite ดังนั้นสามารถสร้างโฟลเดอร์ assets ที่ Root เพื่อเก็บ CSS, JavaScript และรูปภาพแบบ Static ได้
#3. สร้าง .gitignore
.vercel
.env
.env.*
vendor/
ไม่ควร Commit Secret, รหัสผ่านฐานข้อมูล หรือ Token ลง Git Repository
#4. ทดสอบในเครื่อง
วิธีที่ง่ายที่สุดคือใช้ PHP Built-in Server
php -S localhost:8000 api/index.php
เปิดเว็บที่ http://localhost:8000 และทดสอบ API ที่ http://localhost:8000/api/status
หากติดตั้ง Vercel CLI แล้ว สามารถทดสอบสภาพแวดล้อมที่ใกล้เคียงกับ Vercel ด้วยคำสั่ง
vercel dev
เครื่องที่รัน vercel dev ต้องติดตั้ง PHP ไว้ด้วย
#5. Deploy ด้วย Vercel CLI
ติดตั้ง Vercel CLI
npm install --global vercel
เข้าสู่ระบบ
vercel login
เข้าไปในไดเรกทอรีโปรเจกต์และสร้าง Preview Deployment
cd php-vercel-demo
vercel
ในครั้งแรก CLI จะถามชื่อทีม ชื่อโปรเจกต์ และการเชื่อมต่อกับโปรเจกต์เดิม เมื่อ Deploy สำเร็จจะได้รับ URL สำหรับทดสอบ
Deploy เป็น Production ด้วยคำสั่ง
vercel --prod
#6. Deploy อัตโนมัติผ่าน Git
เริ่มต้น Git Repository และ Push ขึ้น GitHub
git init
git add .
git commit -m "Deploy PHP web to Vercel"
git branch -M main
git remote add origin https://github.com/USERNAME/php-vercel-demo.git
git push -u origin main
จากนั้นดำเนินการดังนี้
- เปิด Vercel Dashboard แล้วเลือก Add New → Project
- Import Repository ที่สร้างไว้
- ตรวจสอบ Root Directory ให้ตรงกับตำแหน่ง
vercel.json - เพิ่ม Environment Variables หากระบบต้องใช้
- กด Deploy
เมื่อเชื่อมต่อ Git แล้ว การ Push ครั้งต่อไปจะสร้าง Deployment ใหม่ให้อัตโนมัติ Branch หลักใช้สำหรับ Production ส่วน Branch หรือ Pull Request อื่นใช้สร้าง Preview Deployment ได้
#7. ใช้ Environment Variables
เพิ่มตัวแปรที่ Project → Settings → Environment Variables เช่น
APP_NAME=My PHP Application
DB_HOST=database.example.com
DB_PORT=3306
DB_NAME=app
DB_USER=app_user
DB_PASSWORD=change-me
อ่านค่าจาก PHP ด้วย getenv()
<?php
$appName = getenv('APP_NAME') ?: 'PHP on Vercel';
หากต้องเชื่อมต่อ MySQL สามารถใช้ PDO ได้ดังนี้
<?php
$host = getenv('DB_HOST');
$port = getenv('DB_PORT') ?: '3306';
$name = getenv('DB_NAME');
$user = getenv('DB_USER');
$password = getenv('DB_PASSWORD');
$pdo = new PDO(
"mysql:host={$host};port={$port};dbname={$name};charset=utf8mb4",
$user,
$password,
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
]
);
ควรเลือก Region ของ Function ให้ใกล้กับ Region ของฐานข้อมูลเพื่อลด Latency และควรใช้ฐานข้อมูลที่รองรับการเชื่อมต่อจาก Serverless พร้อมจำกัดจำนวน Connection อย่างเหมาะสม
#8. การจัดการไฟล์และ Session
Vercel Function ไม่ควรถูกมองว่าเป็น Web Server ที่มีดิสก์ถาวร ไฟล์ที่สร้างระหว่างการทำงานอาจไม่อยู่ในการเรียกครั้งถัดไป ดังนั้นควรออกแบบดังนี้
- เก็บข้อมูลถาวรใน MySQL, PostgreSQL หรือฐานข้อมูลภายนอก
- เก็บ Session ใน Redis หรือฐานข้อมูล แทน PHP File Session
- เก็บรูปภาพและเอกสารใน Object Storage
- อัปโหลดไฟล์ขนาดใหญ่จาก Browser ไปยัง Object Storage โดยตรง
- ไม่ใช้ Local Disk เป็นแหล่งข้อมูลหลักของระบบ
Vercel ระบุว่า Request หรือ Response ของ Function มี Payload สูงสุด 4.5 MB จึงไม่ควรส่งไฟล์ขนาดใหญ่ผ่าน PHP Function โดยตรง
#9. ตรวจสอบ Log และแก้ปัญหา
ดู Deployment และ Runtime Logs ผ่าน Vercel Dashboard หรือใช้ CLI
vercel logs YOUR_DEPLOYMENT_URL
ปัญหาที่พบบ่อยมีดังนี้
#พบข้อความว่า Runtime ไม่รองรับ
ตรวจสอบว่า Runtime ระบุเวอร์ชันครบถ้วน
"runtime": "vercel-php@0.9.0"
และตรวจสอบว่าไฟล์ PHP อยู่ภายใต้ api และตรงกับ Key ใน functions
#เปิดหน้าเว็บแล้วพบ 404
ตรวจสอบ Destination ใน rewrites
"destination": "/api/index.php"
#ระบบทำงานในเครื่องแต่เกิด 500 บน Vercel
- เปิด Runtime Logs เพื่อดู Exception จริง
- ตรวจสอบชื่อ Environment Variables
- ตรวจสอบ PHP Extension ที่ระบบต้องใช้
- อย่าแสดง Secret หรือค่าจาก Environment Variables ใน Log
- ตรวจสอบว่าขนาด Function รวม Dependency ไม่เกินข้อจำกัดของแพลตฟอร์ม
#Session หรือไฟล์หาย
ย้าย Session ไป Redis/Database และย้ายไฟล์ไป Object Storage เพราะ Function ไม่เหมาะกับการเก็บ State แบบถาวรใน Local Filesystem
#10. เหมาะกับงานประเภทใด
| เหมาะกับ Vercel + PHP | ควรใช้ PHP Hosting หรือ Container มากกว่า |
|---|---|
| เว็บ PHP ขนาดเล็ก | Laravel ขนาดใหญ่ที่มี Worker หลายตัว |
| REST API หรือ Webhook | Queue Worker ที่ต้องทำงานตลอดเวลา |
| Prototype และงานสาธิต | Scheduler หรือ Cron ที่ซับซ้อน |
| Form Handler | ระบบที่พึ่งพา Local File Session |
| Stateless Microservice | ระบบอัปโหลดไฟล์ขนาดใหญ่ผ่าน Backend |
สำหรับระบบขนาดใหญ่ แนวทางที่ดูแลได้ง่ายกว่าคือ Deploy Frontend บน Vercel และ Deploy PHP/Laravel API บนบริการที่รองรับ Container หรือ PHP โดยตรง จากนั้นเชื่อมต่อกันผ่าน HTTPS API
#สรุป
การ Deploy เว็บ PHP บน Vercel ทำได้ผ่าน Community Runtime vercel-php โดยมีขั้นตอนหลักดังนี้
- วาง Entry Point ไว้ที่
api/index.php - กำหนด
vercel-php@0.9.0ในvercel.json - ใช้
rewritesส่ง Request ไปยัง PHP Front Controller - ทดสอบด้วย PHP Built-in Server หรือ
vercel dev - Deploy ด้วย
vercel --prodหรือเชื่อมต่อ Git Repository - เก็บฐานข้อมูล Session และไฟล์ถาวรไว้ในบริการภายนอก
หัวใจสำคัญคือการออกแบบระบบให้เป็น Stateless และเข้าใจว่า PHP ทำงานในรูปแบบ Function ไม่ใช่ Web Server ที่ทำงานต่อเนื่อง หากระบบสอดคล้องกับรูปแบบนี้ Vercel จะช่วยให้ Deploy ได้รวดเร็ว มี Preview Deployment และเชื่อมต่อ CI/CD ผ่าน Git ได้สะดวก