mkdir(): Permission denied

จาก Log ที่คุณส่งมา ปัญหาหลักคือ mkdir(): Permission denied ครับ

สาเหตุ: ระบบ (Queue Worker) กำลังพยายามสร้างโฟลเดอร์ใหม่ (คาดว่าเพื่อเก็บไฟล์วิดีโอที่กำลังจะแปลง) ที่บรรทัดที่ 56 ของไฟล์ app/Jobs/ProcessVideo.php แต่ User ที่รัน Queue Worker ไม่มีสิทธิ์ (Permission) ในการเขียนหรือสร้างโฟลเดอร์ ในตำแหน่งนั้นครับ

🛠️ วิธีแก้ไขปัญหา

คุณสามารถแก้ปัญหานี้ได้โดยการปรับสิทธิ์การเข้าถึงโฟลเดอร์ของโปรเจกต์ Laravel (โดยปกติมักจะเป็นโฟลเดอร์ storage หรือโฟลเดอร์ปลายทางที่คุณใช้เก็บวิดีโอ) ลองทำตามขั้นตอนเหล่านี้ครับ:

1. เช็คสิทธิ์ (Ownership) ของโฟลเดอร์ โดยปกติแล้วโปรเจกต์ Laravel ควรให้สิทธิ์การเขียนโฟลเดอร์ storage และ bootstrap/cache แก่ Web Server User (เช่น www-data สำหรับ Nginx/Apache บน Ubuntu) ให้รันคำสั่งนี้ที่ Terminal ใน Server:

Bash

sudo chown -R www-data:www-data /var/www/html/storage
sudo chown -R www-data:www-data /var/www/html/bootstrap/cache

(หมายเหตุ: ถ้าคุณใช้ User อื่นในการรัน Server ให้เปลี่ยน www-data เป็นชื่อ User นั้น)

2. เปลี่ยน Permission ให้สามารถเขียนได้ ตั้งค่า Permission เป็น 775 เพื่อให้ Owner และ Group สามารถอ่าน/เขียน/รัน ได้:

Bash

sudo chmod -R 775 /var/www/html/storage
sudo chmod -R 775 /var/www/html/bootstrap/cache

3. ตรวจสอบการรัน Queue Worker (สำคัญมาก) หากคุณรัน Queue ผ่าน Supervisor (หรือ Systemd) ให้เข้าไปเช็คไฟล์ Config ของ Supervisor (มักจะอยู่ที่ /etc/supervisor/conf.d/) ว่าคุณได้กำหนด user=www-data (หรือ user ที่มีสิทธิ์) ไว้หรือไม่ หากไม่ได้กำหนดไว้ Supervisor อาจจะรันด้วย user อื่นที่ไม่มีสิทธิ์เขียนไฟล์

ตัวอย่าง Config ที่ถูกต้อง:

Ini, TOML

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/artisan queue:work --sleep=3 --tries=3
autostart=true
autorestart=true
user=www-data  ; <--- ตรงนี้ต้องเป็น user ที่มีสิทธิ์เขียนโฟลเดอร์
numprocs=1
redirect_stderr=true

4. รีสตาร์ท Queue Worker หลังจากแก้ Permission หรือ Config เสร็จแล้ว อย่าลืมรีสตาร์ท Queue เสมอ เพื่อให้ระบบรับรู้การเปลี่ยนแปลงครับ:

Bash

php artisan queue:restart

💡 คำแนะนำเพิ่มเติม: ลองเปิดไฟล์ app/Jobs/ProcessVideo.php บรรทัดที่ 56 ดูครับว่าโค้ดกำลังพยายามสร้างโฟลเดอร์ไปที่ Path ไหน (เช่น กำลังสร้างโฟลเดอร์ไปที่ public/videos/ หรือเปล่า) ถ้าใช่ ก็ต้องไปทำ chown และ chmod ให้กับโฟลเดอร์เป้าหมายนั้นด้วยเช่นกันครับ

จากรายการ docker ps ที่ส่งมา เห็นชัดเจนเลยครับว่าคุณใช้ Laravel Sail (ดูจาก Image sail-8.5/app)

ปัญหาคือไฟล์ที่ถูก Mount เข้าไปใน Container อาจจะติดสิทธิ์ของ root หรือ User อื่น ทำให้ตัว Queue Worker (ซึ่งใน Sail จะรันด้วย user ชื่อ sail) ไม่มีสิทธิ์เขียนไฟล์ลงใน /var/www/html/storage ครับ

วิธีแก้คือเราต้องสั่งรันคำสั่งแก้ Permission ผ่านสิทธิ์ Root ใน Container ครับ สามารถทำตามสเตปด้านล่างนี้ได้เลย:

🛠️ วิธีแก้ Permission ใน Docker (Laravel Sail)

คุณสามารถรันคำสั่งแบบบรรทัดเดียวจากเครื่อง Host (เครื่องนอก Docker) เพื่อเข้าไปแก้สิทธิ์และรีสตาร์ท Worker ได้เลยครับ:

1. เปลี่ยนเจ้าของโฟลเดอร์ให้เป็นของ user sail (ใช้ container netflix-worker_laravel.test_1 เป็นตัวจัดการ เพราะแชร์ไฟล์ชุดเดียวกันกับ worker)

Bash

docker exec -u root netflix-worker_laravel.test_1 chown -R sail:sail /var/www/html/storage

2. ปรับสิทธิ์ (Permission) ให้สามารถอ่าน/เขียนได้

Bash

docker exec -u root netflix-worker_laravel.test_1 chmod -R 775 /var/www/html/storage

ข้อควรระวัง: หากในโค้ดบรรทัดที่ 56 มีการสั่งสร้างโฟลเดอร์ไว้ที่ Path อื่นที่ ไม่ใช่ storage (เช่น /var/www/html/public/temp) ให้เปลี่ยนพาธในคำสั่งด้านบนเป็นพาธนั้นๆ ด้วยนะครับ

3. รีสตาร์ท Container ของ Queue Worker หลังจากแก้ Permission เสร็จแล้ว ให้ทำการ Restart ตัว Worker เพื่อให้เคลียร์สถานะการทำงานเก่าทิ้งครับ:

Bash

docker restart netflix-worker_laravel.worker_1

💡 (ทางเลือกเสริม) ถ้าอยากเข้าไปพิมพ์เองใน Container

หากคุณต้องการเข้าไปเดินดูใน Container ก่อนว่าโฟลเดอร์หน้าตาเป็นอย่างไร สามารถเข้าโหมด Bash ด้วยสิทธิ์ root ได้ด้วยคำสั่งนี้ครับ:

  1. เข้า Container:

Bash

docker exec -u root -it netflix-worker_laravel.test_1 bash
  1. เมื่อเข้ามาแล้ว (หน้าตา Terminal จะเปลี่ยนไป) ให้พิมพ์:

Bash

chown -R sail:sail /var/www/html/storage
chmod -R 775 /var/www/html/storage
exit
  1. จากนั้นก็สั่งรีสตาร์ท Worker เหมือนเดิมครับ:

Bash

docker restart netflix-worker_laravel.worker_1