คู่มือ Deploy PHP Laravel บน DigitalOcean Droplet 2026
A step-by-step guide to deploying a Laravel application on a DigitalOcean Droplet, covering PHP/Composer setup, MySQL, Nginx/PHP-FPM, queue workers, and SSL.
การ deploy Laravel ขึ้น production ด้วยตัวเองบน DigitalOcean Droplet ให้ความยืดหยุ่นและควบคุมสภาพแวดล้อมได้เต็มที่ ต่างจากการใช้ PaaS อย่าง App Platform ที่จัดการ infrastructure ให้อัตโนมัติ บทความนี้ไล่ทีละขั้นตอนตั้งแต่เตรียมเซิร์ฟเวอร์ ติดตั้ง PHP และ Composer ไปจนถึงตั้งค่า Nginx, PHP-FPM, queue worker และ SSL ให้พร้อมใช้งานจริง พร้อมข้อผิดพลาดที่พบบ่อยและแนวทางปฏิบัติที่แนะนำสำหรับทีมที่ต้องดูแลเซิร์ฟเวอร์เอง
สารบัญ
เตรียม Droplet + ติดตั้ง PHP/Composer
การ deploy Laravel เริ่มต้นด้วยการเลือกขนาด Droplet ให้เหมาะกับโหลดจริงของแอป สำหรับโปรเจกต์ที่เพิ่งเริ่มทดสอบหรือมีผู้ใช้ไม่มาก แผน Basic ขนาด 1 GiB RAM / 1 vCPU / 25GB SSD ราคา $6/เดือน พอใช้งานได้ แต่ถ้าต้องรันเว็บจริงที่มีทราฟฟิกต่อเนื่องพร้อม queue worker แนะนำเริ่มที่ 2 GiB RAM / 1 vCPU / 50GB SSD ราคา $12/เดือน (transfer 2,000 GiB) ขึ้นไป เพราะ PHP-FPM กับ MySQL กินหน่วยความจำพร้อมกันได้ง่ายเมื่อ traffic เพิ่มขึ้น ถ้าต้องการประมวลผลหนักขึ้นให้พิจารณาแผน 4 GiB RAM / 2 vCPU ราคา $24/เดือน ผู้ใช้ในไทยควรเลือก region sgp1 (Singapore) ซึ่งเป็น datacenter ที่ latency ต่ำที่สุดในบรรดา 15 region ของ DigitalOcean รองลงมาคือ blr1 (Bangalore) สำหรับ OS แนะนำ Ubuntu 24.04 LTS เพราะมี package PHP เวอร์ชันใหม่รองรับผ่าน PPA ครบ
หลังสร้าง Droplet แล้ว ให้ SSH เข้าเซิร์ฟเวอร์และอัปเดตระบบก่อนด้วย apt update && apt upgrade -y จากนั้นเปิด Cloud Firewall (ฟรี ไม่มีค่าใช้จ่ายเพิ่ม) จำกัดให้เข้าได้เฉพาะ SSH (22), HTTP (80) และ HTTPS (443) เพื่อลดพื้นผิวโจมตี ต่อมาติดตั้ง PHP 8.3 พร้อม extension ที่ Laravel ต้องใช้ผ่าน PPA ของ ondrej ด้วยคำสั่ง add-apt-repository ppa:ondrej/php -y && apt update แล้วติดตั้งด้วย apt install php8.3 php8.3-fpm php8.3-mysql php8.3-mbstring php8.3-xml php8.3-bcmath php8.3-curl php8.3-zip php8.3-gd -y ตรวจสอบเวอร์ชันด้วย php -v ขั้นตอนสุดท้ายคือติดตั้ง Composer ผ่านตัวติดตั้งทางการ curl -sS https://getcomposer.org/installer | php แล้วย้ายไปไว้ใน PATH ด้วย mv composer.phar /usr/local/bin/composer จากนั้นตรวจสอบด้วย composer --version ก่อนไปขั้นตอนติดตั้ง Laravel ต่อไป
Deploying Laravel starts with choosing a Droplet size appropriate for your app's actual load. For projects just getting started or with minimal users, the Basic plan with 1 GiB RAM / 1 vCPU / 25GB SSD at $6/month works, but for a real production website with continuous traffic and queue workers, we recommend starting at 2 GiB RAM / 1 vCPU / 50GB SSD at $12/month (2,000 GiB transfer) and up, because PHP-FPM and MySQL can easily consume memory together under increasing traffic. For heavier processing, consider the 4 GiB RAM / 2 vCPU plan at $24/month. Thai users should select the sgp1 (Singapore) region, which has the lowest latency among DigitalOcean's 15 regions, followed by blr1 (Bangalore). For the OS, we recommend Ubuntu 24.04 LTS because it has newer PHP versions available through PPA.
After creating your Droplet, SSH in and update the system first with apt update && apt upgrade -y. Then enable Cloud Firewall (free, no additional cost) to restrict access to only SSH (22), HTTP (80), and HTTPS (443) to reduce the attack surface. Next, install PHP 8.3 with the Laravel extensions via ondrej's PPA using add-apt-repository ppa:ondrej/php -y && apt update, then install with apt install php8.3 php8.3-fpm php8.3-mysql php8.3-mbstring php8.3-xml php8.3-bcmath php8.3-curl php8.3-zip php8.3-gd -y. Verify the version with php -v. Finally, install Composer using the official installer curl -sS https://getcomposer.org/installer | php, then move it to PATH with mv composer.phar /usr/local/bin/composer, and verify with composer --version before proceeding to install Laravel.
- Droplet ขั้นต่ำสำหรับ production จริงคือ 2 GiB RAM / 1 vCPU ($12/เดือน) ขึ้นไป — แผน $6 เหมาะกับทดสอบเท่านั้น
- ผู้ใช้ไทยเลือก region sgp1 (Singapore) latency ต่ำสุด รองลงมา blr1 (Bangalore)
- เปิด Cloud Firewall ฟรีจำกัดพอร์ตเหลือ 22/80/443 ตั้งแต่ก่อนติดตั้งซอฟต์แวร์
- ติดตั้ง PHP 8.3 ผ่าน PPA ondrej/php พร้อม extension mbstring, xml, bcmath, curl, zip, gd, mysql
- Composer ติดตั้งผ่านตัวติดตั้งทางการแล้ว mv ไปไว้ที่ /usr/local/bin/composer
ติดตั้ง Laravel + ตั้งค่า .env
จากที่เราทดสอบจริง — เมื่อเซิร์ฟเวอร์พร้อมแล้ว มีสองแนวทางในการนำโค้ด Laravel ขึ้น Droplet คือสร้างโปรเจกต์ใหม่ด้วย composer create-project laravel/laravel myapp หรือถ้ามีโค้ดอยู่แล้วให้ clone จาก repository ด้วย git clone [email protected]:yourteam/myapp.git /var/www/myapp แล้วเข้าไปใน directory นั้นเพื่อติดตั้ง dependency แบบ production ด้วย composer install --no-dev --optimize-autoloader โดยแฟล็ก --no-dev จะไม่ติดตั้ง package สำหรับ dev เช่น phpunit และ --optimize-autoloader จะสร้าง classmap ที่โหลดเร็วขึ้นสำหรับ production
ขั้นต่อไปคือตั้งค่าไฟล์ environment ด้วย cp .env.example .env แล้วรัน php artisan key:generate เพื่อสร้าง APP_KEY ใหม่ ห้ามใช้ APP_KEY เดียวกับ local เด็ดขาดเพราะเป็นตัวเข้ารหัส session และ cookie จากนั้นแก้ไข .env ให้ตรงกับ production จริง เช่น APP_ENV=production, APP_DEBUG=false (สำคัญมาก เพราะถ้าเปิด debug ทิ้งไว้จะรั่วข้อมูล stack trace และ config ให้ผู้ใช้ทั่วไปเห็น) และ APP_URL=https://yourdomain.com ให้ตรงกับโดเมนจริงเพื่อให้ URL ที่ Laravel generate เช่นใน email หรือ asset ถูกต้อง ต่อมาให้สร้าง symbolic link สำหรับไฟล์ที่อัปโหลดด้วย php artisan storage:link และตั้งสิทธิ์ให้ web server เขียนไฟล์ log/cache ได้ด้วย chown -R www-data:www-data storage bootstrap/cache ตามด้วย chmod -R 775 storage bootstrap/cache ขั้นตอนนี้มักถูกมองข้ามแต่เป็นสาเหตุอันดับต้นของ error 500 ในภายหลัง หลังตั้งค่าครบให้ทดสอบด้วย php artisan about เพื่อตรวจสอบว่า environment ที่อ่านได้ตรงกับที่ตั้งใจไว้ก่อนเชื่อมต่อฐานข้อมูลในขั้นตอนถัดไป
- สร้างโปรเจกต์ใหม่ด้วย composer create-project หรือ git clone repo ที่มีอยู่แล้วเข้า /var/www/myapp
- composer install --no-dev --optimize-autoloader สำหรับ production เท่านั้น ไม่ใช้ dev dependency
- APP_KEY ต้อง generate ใหม่ทุกครั้งด้วย php artisan key:generate ห้ามใช้ key เดียวกับ local
- APP_ENV=production และ APP_DEBUG=false เสมอ ป้องกันข้อมูล error รั่วไหล
เชื่อมต่อ MySQL
Laravel รองรับทั้งการต่อฐานข้อมูล MySQL ที่ติดตั้งเองบน Droplet เดียวกัน (self-host) หรือใช้ DigitalOcean Managed Database แบบแยกเครื่อง ทั้งสองแบบมีข้อดีข้อเสียต่างกัน การ self-host ด้วย apt install mysql-server -y ไม่มีค่าใช้จ่ายเพิ่มแต่ผู้ดูแลต้องจัดการ backup, patching และ tuning เอง ส่วน Managed MySQL ของ DigitalOcean เริ่มต้นที่ tier Basic 1 vCPU / 1 GiB RAM พร้อม storage 10-30GiB ราคา $15.15/เดือน ซึ่งมี automated backup, failover และ metrics ให้พร้อมใช้ เหมาะกับโปรเจกต์ที่ต้องการความเสถียรสูงหรือทีมที่ไม่อยากดูแล database เอง และสามารถเชื่อมต่อผ่าน VPC (private networking) ซึ่งฟรีไม่มีค่าใช้จ่ายเพิ่ม ทำให้ทราฟฟิกระหว่าง Droplet กับฐานข้อมูลไม่ต้องออกอินเทอร์เน็ตสาธารณะ
ถ้าเลือก self-host หลังติดตั้งแล้วให้รัน mysql_secure_installation เพื่อตั้งรหัสผ่าน root และปิดช่องโหว่พื้นฐาน จากนั้นสร้างฐานข้อมูลและผู้ใช้เฉพาะสำหรับแอปด้วย CREATE DATABASE myapp; CREATE USER 'myapp'@'localhost' IDENTIFIED BY 'strong-password'; GRANT ALL PRIVILEGES ON myapp.* TO 'myapp'@'localhost'; FLUSH PRIVILEGES; ห้ามใช้ user root ในแอป production เด็ดขาด ต่อมาแก้ไข .env ให้ตรงกับข้อมูลจริง เช่น DB_CONNECTION=mysql, DB_HOST=127.0.0.1, DB_PORT=3306, DB_DATABASE=myapp, DB_USERNAME=myapp, DB_PASSWORD=strong-password ถ้าใช้ Managed Database ให้แทนที่ DB_HOST ด้วย private hostname ที่ได้จาก control panel แทน หลังตั้งค่าครบให้รัน migration จริงด้วย php artisan migrate --force โดยแฟล็ก --force จำเป็นสำหรับ production เพราะ Laravel จะไม่ยอมรัน migration แบบไม่ยืนยันถ้าตรวจพบ APP_ENV=production เพื่อป้องกันความผิดพลาด
- Self-host MySQL ฟรีแต่ต้องดูแล backup/patch เอง — Managed MySQL $15.15/เดือน (1 vCPU/1 GiB RAM, 10-30GiB) มี backup อัตโนมัติให้
- ต่อ Managed Database ผ่าน VPC (ฟรี) เพื่อความปลอดภัยและ latency ต่ำกว่าเชื่อมผ่านอินเทอร์เน็ตสาธารณะ
- สร้าง database user เฉพาะแอป ห้ามใช้ root ใน .env ของ production
ตั้งค่า Nginx + PHP-FPM
Nginx ทำหน้าที่เป็น web server ด้านหน้าที่รับ request แล้วส่งต่อไฟล์ PHP ให้ PHP-FPM ประมวลผลผ่าน socket เริ่มจากติดตั้งด้วย apt install nginx -y จากนั้นสร้างไฟล์ config ใหม่ที่ /etc/nginx/sites-available/myapp โดย root ต้องชี้ไปที่ directory public ของ Laravel เท่านั้น ไม่ใช่ root ของโปรเจกต์ เพราะไฟล์ .env และโค้ด application ต้องไม่เปิดให้เข้าถึงผ่าน URL ได้โดยตรง ตัวอย่าง config ขั้นต่ำคือ server { listen 80; server_name yourdomain.com; root /var/www/myapp/public; index index.php; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.3-fpm.sock; } location ~ /\.(?!well-known).* { deny all; } } จุดที่ผิดพลาดบ่อยคือ path ของ fastcgi_pass ไม่ตรงกับ socket จริงของ PHP-FPM เวอร์ชันที่ติดตั้ง ให้ตรวจสอบด้วย ls /run/php/ ก่อนเสมอ
หลังเขียน config แล้วให้เปิดใช้งานด้วยการสร้าง symbolic link ไปยัง sites-enabled ด้วย ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/ จากนั้นทดสอบ syntax ก่อน reload เสมอด้วย nginx -t ถ้าไม่มี error ให้ reload ด้วย systemctl reload nginx ฝั่ง PHP-FPM ควรตรวจสอบ pool config ที่ /etc/php/8.3/fpm/pool.d/www.conf โดยเฉพาะค่า pm.max_children ที่ควรปรับให้เหมาะกับ RAM ของ Droplet เช่นบนเครื่อง 2 GiB RAM ไม่ควรตั้งสูงเกินไปจนหน่วยความจำไม่พอ เพราะแต่ละ child process ของ PHP-FPM กิน RAM แยกกัน หลังแก้ pool config ให้ restart ด้วย systemctl restart php8.3-fpm แล้วเปิดเบราว์เซอร์ทดสอบเข้าโดเมนเพื่อยืนยันว่าเห็นหน้า Laravel welcome page หรือหน้าแอปจริงตามที่ตั้งใจ
- root ของ Nginx ต้องชี้ไปที่ /var/www/myapp/public เท่านั้น ห้ามชี้ที่ root โปรเจกต์
- ตรวจสอบ path socket จริงด้วย ls /run/php/ ก่อนตั้งค่า fastcgi_pass ให้ตรงกัน
- nginx -t ทดสอบ syntax ก่อน reload ทุกครั้งเพื่อกันเว็บล่ม
- block เข้าถึงไฟล์ dotfile เช่น .env ด้วย location ~ /\.(?!well-known).* { deny all; }
- ปรับ pm.max_children ใน PHP-FPM pool ให้เหมาะกับ RAM ของ Droplet ที่เลือกไว้
Queue Worker และ SSL
แอป Laravel ที่มีงานเบื้องหลังเช่นส่งอีเมลหรือประมวลผลไฟล์ ควรใช้ queue แทนการรันแบบ synchronous เพื่อไม่ให้ผู้ใช้รอ ทดสอบรัน worker ด้วย php artisan queue:work ก่อน แต่คำสั่งนี้จะหยุดทำงานทันทีที่ SSH session ปิดหรือเซิร์ฟเวอร์รีสตาร์ท จึงต้องใช้ Supervisor เพื่อคุมให้ worker ทำงานตลอดเวลาและ restart อัตโนมัติเมื่อ crash ติดตั้งด้วย apt install supervisor -y แล้วสร้างไฟล์ config ที่ /etc/supervisor/conf.d/myapp-worker.conf เนื้อหาโดยประมาณคือ [program:myapp-worker] process_name=%(program_name)s_%(process_num)02d command=php /var/www/myapp/artisan queue:work --sleep=3 --tries=3 --max-time=3600 autostart=true autorestart=true numprocs=2 user=www-data จากนั้นรัน supervisorctl reread && supervisorctl update && supervisorctl start myapp-worker:* ข้อสำคัญคือทุกครั้งที่ deploy โค้ดใหม่ต้องรัน php artisan queue:restart เพื่อสั่งให้ worker เก่าจบงานที่ทำอยู่แล้วโหลดโค้ดใหม่ ไม่เช่นนั้น worker จะยังรันโค้ดเวอร์ชันเก่าค้างอยู่ในหน่วยความจำ
สำหรับ SSL แนะนำใช้ Let's Encrypt ผ่าน Certbot ซึ่งออก certificate ฟรีและต่ออายุอัตโนมัติ ติดตั้งด้วย apt install certbot python3-certbot-nginx -y แล้วออก certificate พร้อมแก้ config Nginx ให้อัตโนมัติด้วยคำสั่งเดียว certbot --nginx -d yourdomain.com -d www.yourdomain.com Certbot จะตั้ง systemd timer ต่ออายุให้เองทุก 90 วัน ตรวจสอบได้ด้วย certbot renew --dry-run ก่อนใช้งานจริงให้แน่ใจว่า Cloud Firewall เปิดพอร์ต 443 ไว้แล้ว หลังติดตั้ง SSL เสร็จควรบังคับ redirect จาก http เป็น https ทั้งหมดเพื่อความปลอดภัยของ session และ cookie ของผู้ใช้
- php artisan queue:work รันตรงจะหยุดทันทีที่ session ปิด ต้องใช้ Supervisor คุมให้ทำงานถาวร
- ทุกครั้งที่ deploy โค้ดใหม่ต้องรัน php artisan queue:restart เสมอ ไม่งั้น worker ใช้โค้ดเก่าค้าง
- SSL ฟรีผ่าน Let's Encrypt/Certbot: certbot --nginx -d yourdomain.com ออกและติดตั้งให้อัตโนมัติ
เมื่อไหร่ควรใช้ฟีเจอร์นี้ (Use Case จริง)
การ deploy Laravel บน Droplet ด้วยตัวเองเหมาะกับทีมที่ต้องการควบคุมสภาพแวดล้อมเต็มรูปแบบ เช่นต้องการติดตั้ง extension PHP เฉพาะทาง ปรับ tuning MySQL เอง หรือรัน cron job และ queue worker หลายตัวพร้อมกันแบบกำหนดเองได้ นอกจากนี้ยังคุมต้นทุนได้ชัดเจนกว่าเพราะจ่ายตามขนาด Droplet คงที่ต่อเดือน ไม่ผันแปรตามการใช้งานเหมือนบริการ serverless ในทางกลับกัน ถ้าทีมไม่มีคนดูแลระบบ (sysadmin) โดยเฉพาะ หรือต้องการ deploy เร็วโดยไม่อยากจัดการ Nginx/PHP-FPM/SSL เอง DigitalOcean App Platform เป็นทางเลือกที่เหมาะกว่า เพราะเป็น PaaS ที่ build และ deploy จาก Git repository ให้อัตโนมัติ โดยราคาเริ่มต้นสำหรับ container instance แบบ shared คือ $5/เดือน (1 vCPU, 512MiB RAM, 50GiB transfer) ไปจนถึง $50/เดือน (2 vCPU, 4GiB RAM, 250GiB transfer) สำหรับงานที่ใหญ่ขึ้น ข้อควรพิจารณาอีกจุดคือฐานข้อมูล ถ้าโปรเจกต์เล็กหรืองบจำกัดและยอมรับความเสี่ยงดูแลเอง การรัน MySQL บน Droplet เดียวกับแอปก็เพียงพอ แต่ถ้าแอปเริ่มมีผู้ใช้จริงจังและต้องการ uptime สูงพร้อม backup อัตโนมัติ การย้ายไปใช้ Managed MySQL ราคาเริ่ม $15.15/เดือนคุ้มค่ากว่าต้นทุนเวลาที่ต้องเสียไปดูแลฐานข้อมูลเอง สำหรับโปรเจกต์ที่คาดว่าจะโตเร็วจนต้องรันหลาย instance พร้อม load balancer ให้พิจารณา DigitalOcean Kubernetes (DOKS) ซึ่ง control plane ฟรีและเริ่มจ่ายเฉพาะค่า node pool ตามราคา Droplet ปกติ (เริ่มที่ $12/เดือนต่อ node) โดยรวมแล้วแนวทาง Droplet เดี่ยวตามคู่มือนี้เหมาะที่สุดกับโปรเจกต์ขนาดเล็กถึงกลางที่ทีมพร้อมดูแลระบบเองและต้องการควบคุมทุกส่วนของ stack
- เหมาะกับทีมที่ต้องการควบคุม stack เต็มรูปแบบ ปรับ PHP-FPM/MySQL/cron เองได้ตามต้องการ
- ต้นทุนคงที่รายเดือนตามขนาด Droplet คำนวณงบประมาณล่วงหน้าได้ง่ายกว่า serverless
- ทีมที่ไม่มี sysadmin หรืออยากลด operational overhead ควรพิจารณา App Platform ($5-$50/เดือนสำหรับ container ขนาดเล็ก-กลาง) แทน
ข้อผิดพลาดที่พบบ่อยและวิธีแก้ไข
ข้อผิดพลาดที่เจอบ่อยที่สุดคือหน้า error 500 หลัง deploy ซึ่งส่วนใหญ่มาจากปัญหา permission ของ storage หรือ bootstrap/cache แก้ได้ด้วยการรัน chown -R www-data:www-data storage bootstrap/cache && chmod -R 775 storage bootstrap/cache อีกครั้ง และเปิดดู log จริงที่ storage/logs/laravel.log เพื่อดูสาเหตุที่แท้จริงแทนการเดา ปัญหาถัดมาคือแก้ .env แล้วแอปยังใช้ค่าเก่าอยู่ สาเหตุคือ Laravel cache ค่า config ไว้แล้วตั้งแต่ก่อนหน้า ต้องล้างด้วย php artisan config:clear ก่อน แล้วค่อย cache ใหม่ด้วย php artisan config:cache ถ้าลืมขั้นตอนนี้ config เก่าจะค้างอยู่แม้แก้ไฟล์ .env ไปแล้วก็ตาม
อีกจุดที่พลาดบ่อยคือ path ของ fastcgi_pass ใน Nginx ไม่ตรงกับ socket จริงของ PHP-FPM โดยเฉพาะหลังอัปเกรดเวอร์ชัน PHP เช่นจาก 8.2 เป็น 8.3 แล้วลืมแก้ path ใน config ทำให้ Nginx คืนค่า 502 Bad Gateway ให้ตรวจด้วย ls /run/php/ เทียบกับค่าที่ตั้งไว้เสมอ สำหรับ queue worker ปัญหาที่พบคือหลัง deploy โค้ดใหม่แล้ว worker ยังรันโค้ดเก่าอยู่ เพราะ Supervisor ไม่ได้สั่งให้โหลดโค้ดใหม่ ต้องรัน php artisan queue:restart ทุกครั้งหลัง deploy ฝั่งฐานข้อมูลปัญหาที่พบคือ SQLSTATE[HY000] [2002] Connection refused ซึ่งมักเกิดจาก MySQL bind-address ผูกกับ 127.0.0.1 แต่ DB_HOST ใน .env ตั้งเป็น localhost หรือ IP อื่นที่ไม่ตรงกัน หรือ user ที่สร้างไม่ได้ grant สิทธิ์จาก host ที่เชื่อมมาจริง สุดท้ายบน Droplet ขนาดเล็ก 512MiB-1GiB RAM คำสั่ง composer install อาจ crash เพราะหน่วยความจำไม่พอ แก้ได้ด้วยการเพิ่ม swap file ชั่วคราวด้วย fallocate -l 1G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile ก่อนรัน composer
- Error 500 หลัง deploy → เช็ค storage/logs/laravel.log และ permission ของ storage/bootstrap/cache ก่อนเสมอ
- แก้ .env แล้วไม่มีผล → ต้อง php artisan config:clear แล้ว config:cache ใหม่ทุกครั้ง
- 502 Bad Gateway → path fastcgi_pass ใน Nginx ไม่ตรงกับ socket จริงของ PHP-FPM โดยเฉพาะหลังอัปเกรดเวอร์ชัน PHP
แนวทางปฏิบัติที่ดีที่สุด (Best Practices)
เพื่อให้ deploy แต่ละครั้งไม่กระทบผู้ใช้ ควรใช้แนวทาง deploy แบบ zero-downtime โดย pull โค้ดใหม่ลง release folder แยกแล้วสลับ symbolic link ของ current มาชี้ที่ release ใหม่หลังทุกอย่างพร้อม (แนวทางเดียวกับที่เครื่องมืออย่าง Deployer หรือ Envoyer ใช้) แทนการ git pull ทับโค้ดเดิมตรงๆ ซึ่งอาจทำให้ผู้ใช้เจอหน้าเว็บครึ่งอัปเดตระหว่าง deploy ก่อน restart PHP-FPM ทุกครั้งควร cache config, route และ view ให้ครบด้วย php artisan config:cache && php artisan route:cache && php artisan view:cache เพื่อลดเวลาประมวลผลในทุก request และไฟล์ .env ต้องไม่ถูก commit เข้า git repository เด็ดขาด ใช้ .gitignore ป้องกันไว้ตั้งแต่ต้น
สำหรับงานที่ต้องรันตามเวลา ให้ตั้ง cron เพียงบรรทัดเดียวเรียก Laravel scheduler ด้วย * * * * * cd /var/www/myapp && php artisan schedule:run >> /dev/null 2>&1 แล้วกำหนด task ย่อยทั้งหมดในโค้ด Laravel เอง ส่วน queue worker ให้ Supervisor ดูแลตามที่กล่าวไปแล้วเพื่อให้ auto-restart เมื่อ crash หรือเซิร์ฟเวอร์รีบูต ด้านการสำรองข้อมูล ควรตั้ง Droplet snapshot เป็นประจำ ซึ่งคิดค่าใช้จ่ายเพียง $0.06/GiB/เดือน คุ้มค่ามากเมื่อเทียบกับความเสี่ยงข้อมูลหาย และควรเปิดใช้ DigitalOcean Monitoring ซึ่งฟรีพร้อม 1 Uptime Check ต่อบัญชี เพื่อรับแจ้งเตือนเมื่อเซิร์ฟเวอร์มีปัญหา ด้านความปลอดภัยให้ปิดการ login ด้วยรหัสผ่านผ่าน SSH แล้วใช้ SSH key เท่านั้น จำกัดพอร์ตผ่าน Cloud Firewall (ฟรี) และถ้าวางแผนจะย้ายหรือ rebuild Droplet ในอนาคต ควรผูก Reserved IP ไว้ตั้งแต่ต้น เพราะถ้าผูกกับ Droplet ที่ใช้งานอยู่จะไม่มีค่าใช้จ่ายเพิ่ม แต่จะช่วยให้ไม่ต้องแก้ DNS ทุกครั้งที่เปลี่ยนเซิร์ฟเวอร์
- Deploy แบบ zero-downtime ด้วย release folder + symbolic link แทนการ git pull ทับโค้ดเดิมตรงๆ
- cache config/route/view ทุกครั้งก่อน deploy เสร็จ (config:cache, route:cache, view:cache) และห้าม commit .env เข้า git
- ใช้ Laravel scheduler ผ่าน cron บรรทัดเดียว (php artisan schedule:run ทุกนาที) แทนตั้ง cron หลายรายการ
- ตั้ง Droplet snapshot สม่ำเสมอ ($0.06/GiB/เดือน) และเปิด Monitoring ฟรีพร้อม Uptime Check