ใช้งาน DigitalOcean Spaces (s3 ในราคาที่ถูกกว่า) ร่วมกับ Laravel

ใช้งาน DigitalOcean Spaces (s3 ในราคาที่ถูกกว่า) ร่วมกับ Laravel

วันนี้เราจะมาทำความรู้จักกันกับ DigitalOcean Spaces กันครับว่ามันดียังไง? และ หากต้องการใช้งานร่วมกับ Laravel จะต้องทำอย่างไรกันบ้าง?

ข้อดี / ข้อเสียในการใช้งาน

ข้อดีของ DigitalOcean Spaces

  1. ราคาถูก… ด้วยราคาที่แค่ $5 ต่อเดือน กับสิ่งที่ได้มาคือ 250GB และ Data transfer ตอนดึงไฟล์อยู่ที่ 1TB ต่อเดือน — สำหรับโปรเจกต์งานที่มีขนาดเล็กค่อนไปทางกลางนับว่าค่อนข้างคุ้มค่าเลยครับ
  2. ในแง่ของการพัฒนาง่ายมาก ๆ เพราะ รองรับการใช้งานแบบ s3 ทำให้เราแทบไม่ต้องหา Plugin ใหม่เลย ถ้าเราใช้ s3 อยู่แล้วการย้ายมาใช้งานที่นี่ก็ง่ายมาก ๆ อาจจะต้องมีแก้ไขนิดนึงแต่ไม่เยอะแน่นอน — คิดอีกทางนึงก็คือถ้าในอนาคตโปรเจกต์ใหญ่ขึ้น เราก็สามารถย้ายไปใช้ s3 ได้แบบไม่เจ็บตัวเยอะ
  3. ใช้งานง่ายมวาก การสร้าง Space ไปจนถึงการตั้งค่าต่าง ๆ มีอยู่ไม่กี่ขั้นตอน โดยเมนูก็ไม่ได้มีความซับซ้อนอะไรเลยด้วย รวมทั้งมี Tutorial ของทาง DigitalOcean เองที่ทำไว้ค่อนข้างครบถ้วน
  4. มี CDN ในตัว สามารถใช้งานได้ไม่ยากจากการตั้งค่า

ข้อดีก็มาก… มันมีข้อเสียบ้างไหม?

  1. Region ยังมีให้เลือกไม่เยอะมาก แต่แน่นอนเราใกล้สุดก็เลือกสิงคโปร์ได้เลย

2. Lib ของ Spaces ในการใช้งานค่อนข้างน้อย อาจจะมองว่ามันใช้งานได้คล้ายกันกับ s3 จึงพบว่าแหล่งข้อมูลค่อนข้างน้อย เช่น ในตอนขั้นตอนการ Config ผมก็มีการตั้งค่าผิดทำให้มันเชื่อมต่อกับ Space ไม่ได้ ก็หาวิธีอยู่นาน ต้องไปศึกษาการ Config ของการเชื่อมต่อ s3 เพิ่มเติมเอง

3. ต้องจ่ายแบบ fixed rate นั่นคือมันไม่ได้จ่ายเงินตามที่ใช้งานจริง เสมือนเราจ่าย $5 ไปก็ได้ space เท่านี้ไปเลย จะใช้ไม่ถึงก็ราคานี้ แต่ก็อย่างที่ผมบอกด้วยราคาที่ถูกก็นับว่าคุ้มค่าในการใช้งานครับ แต่ถ้ามากกว่านั้นก็จะคิดราคาตามที่เราใช้จริง (อัพโหลดหลังจากนี้ $0.02 / GB, $0.01 / GB Transfer)

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

DigitalOcean Spaces: Pros/Cons and how to use it with Javascript
DigitalOcean is one of the last providers that decided to offer a Storage service in the Cloud. However, in contrast…
medium.com

ขั้นตอนการสร้าง DigitalOcean Spaces

  1. เข้าไปที่ Spaces จากเมนู Create

2. เลือกว่าจะให้ data center อยู่ที่ไหน เราก็เลือกใกล้เราที่สุดซึ่งก็หนีไม่พ้นสิงคโปร์ครับ

3. ต้องกรอกชื่อที่เป็น unique ของ space เราครับ

จากนั้นกด Create ได้เลยครับ เราจะได้ space ใหม่ของเราหน้าตาประมาณนี้

ขั้นตอนการอัพโหลดไฟล์เข้า Space ด้วย Laravel

ก่อนอื่นเลยเราจะใช้ library ที่ชื่อว่า league/flysystem-aws-s3-v3 ในการเชื่อมต่อ space ครับ จะเห็นว่าเราสามารถใช้ library เดียวกันกับกับ s3 ได้เลย

ติดตั้งด้วยคำสั่ง

composer require league/flysystem-aws-s3

จากนั้นให้ลองเปิดไฟล์ .env ครับ จากนั้นเพิ่มค่าที่ต้องใช้ในการเชื่อมต่อดังนี้

DO_SPACES_KEY=
DO_SPACES_SECRET=
DO_SPACES_ENDPOINT=
DO_SPACES_REGION=
DO_SPACES_BUCKET=

สำหรับ DO_SPACES_KEY และ DO_SPACES_SECRET เราจะต้องกลับไปสร้างใน Digitalocean ก่อนครับ

  1. ไปที่ Manage > API

2. สร้าง Personal key ขึ้นมาครับ จะได้หน้าตาประมาณนี้

3. สร้าง Key ใหม่ในการจัดการ Space ดังรูปด้านล่าง

เมื่อกรอกชื่อ Key ของเราก็จะได้แบบนี้มาครับ

ก็นำเอา Key และ Secret ที่ได้มาวางใน .env ของเราได้เลยครับ

หน้าตาของค่าที่เราใส่เพิ่มไปก็จะประมาณนี้ครับ

DO_SPACES_KEY=5B7C4ARFM7BWPA2VE2PY
DO_SPACES_SECRET=ETCxBF1zV7IzSlX9pkrxDnVdqGwEvxdu8WJmgiPeNQw
DO_SPACES_ENDPOINT=https://sgp1.digitaloceanspaces.com
DO_SPACES_REGION=sgp1
DO_SPACES_BUCKET=igg-test-laravel-space

ในกรณีที่เราเลือก สิงคโปร์ ค่าของ DO_SPACES_ENDPOINT และ DO_SPACES_REGION จะเป็นตามนี้เลย สำหรับ DO_SPACES_ENDPOINT สามารถดูได้ที่ Space ของเรา > Settings ครับ

*** สำคัญเลยครับ ถ้าเราใช้ Digitalocean space แต่เราใช้ Driver s3 ในการเชื่อมต่อต้องทำการระบุ endpoint ครับ ถ้าไม่ระบุตัว Library ส่วนใหญ่จะไปเชื่อมต่อกับ s3 เลย ทำให้ไม่สามารถใช้งานได้ครับ

ส่วนของ DO_SPACES_BUCKET นั้นก็คือชื่อที่เราตั้งไว้ตอนแรกครับ

จากนั้นไปที่ไฟล์ config/filesystems.php เพื่อทำการเพิ่ม Space driver ให้กับ Laravel สามารถใช้งานได้ครับ

  • ให้ทำการเพิ่มต่อจาก s3 ดังตัวอย่างนี้ครับ

'do_spaces' => [

'driver' => 's3',

'key' => env('DO\_SPACES\_KEY'),

'secret' => env('DO\_SPACES\_SECRET'),

'endpoint' => env('DO\_SPACES\_ENDPOINT'),

'region' => env('DO\_SPACES\_REGION'),

'bucket' => env('DO\_SPACES\_BUCKET'),

],

ทดลองอัพโหลดไฟล์ขึ้น Space กัน!

  1. ไปที่ routes/web.php ครับ ผมจะทำการเพิ่ม route อัพโหลดเพื่อทดสอบที่นี่เลย ไม่ไปสร้าง Controller ครับ

2. นำโค๊ดด้านล่างนี้ไปใส่ในไฟล์ที่บอกตอนแรก

Route::get('/upload', function () {

$image = file\_get\_contents('https://raw.githubusercontent.com/laravel/art/master/laravel-l-slant.png');

Storage::disk('do\_spaces')->put('laravel.png', $image);

return 'Upload done!';

});

โค๊ดด้านบนคือการดึงไฟล์รูป Logo laravel มาจากที่อื่น จากนั้นทำการอัพโหลดไฟล์ขึ้น Space ตามที่เราได้เพิ่มใน config ก่อนหน้า

เมื่อทดลองเข้าไปที่ {{laravel ip}}/upload จะพบข้อความว่า “Upload done!”

กลับไปดูที่ Space ของเราจะพบว่ามีไฟล์ laravel.png ถูกอัพโหลดขึ้นมาแล้วครับ

3. ในขั้นตอนการใช้งานจริง เราก็แค่เก็บ public path ของไฟล์ไว้ในฐานข้อมูลเท่านั้น เช่น อย่างรูปที่อัพโหลดไปจากตัวอย่างนี้ก็เก็บว่า laravel.png เท่านั้น แต่ทีนี้ปัญหาคือเราจะเรียกรูปมาแสดงได้อย่างไรกันน่ะ? เพราะถ้าเราลองเข้าลิงค์ตรง ๆ ของ Space จะขึ้นแบบนี้

เนื่องจากโดย Default ไฟล์เหล่านี้ควรจะต้องไม่สามารถหลุดออกไปได้ ถ้าไม่ได้มีการใช้งานผ่าน Application ของเราครับ ดังนั้น ต่อไปเราจะมาทำ Path ในการดึงรูปมาแสดงผ่าน Application ของเรากันครับ

การนำเอาไฟล์ที่อัพโหลดมาใช้งานใน Application

  1. กลับไปที่ routes/web.php เช่นเคยครับ เราจะมาสร้าง route ในการดึงไฟล์มาแสดงครับ
  2. นำโค๊ดนี้ไปไว้ด้านล่างไฟล์ครับ

Route::get('/images/{file}', function ($file) {

$url = Storage::disk('do\_spaces')->temporaryUrl(

  $file,

  now()->addMinutes(5)

);

if ($url) {

   return Redirect::to($url);

}

return abort(404);

})->where('file', '.+');

จากโค๊ดด้านบนผมเลือกใช้การสร้าง Temporay Url ครับ เนื่องจากเราต้องการให้ Url ของรูปสามารถเข้าถึงได้ในระยะเวลาจำกัด ซึ่งเราสามารถระบุได้ว่าจะให้หมดเวลากี่นาที จากตัวอย่างจะเห็นว่าผมตั้งค่าให้หมดเวลาใน 5 นาที (เพิ่มเวลาจากจุดปัจจุบันไป 5 นาที) สำหรับการใช้งาน Storage ของ Laravel ผมแนะนำว่าลองศึกษาต่อได้จากลิงค์ด้านล่างที่ผมแนบไว้ครับ

File Storage
Laravel provides a powerful filesystem abstraction thanks to the wonderful Flysystem PHP package by Frank de Jonge. The…
laravel.com

ทีนี้ก็ขึ้นอยู่กับเราแล้วครับว่าจะพัฒนาต่อไปในรูปแบบไหน ซึ่งการแยกก้อนของไฟล์ที่อัพโหลดออกมาเป็นอีกตัวก็ทำให้ในขั้นตอนการ Deploy ค่อนข้างสะดวกมากครับ อีกทั้งยังส่งผลให้เราสามารถเลือกได้ว่าจะ Scale อย่างไร ไม่ต้องภวงค์ในเรื่องของไฟล์ที่กระจัดกระจายตามที่ต่าง ๆ ด้วยครับ

สำหรับบทความนี้ก็น่าจะจบแต่เพียงเท่านี้ครับ ไว้ครั้งนี้มีเรื่องอะไรน่าสนใจ หรือ เครื่องมือใหม่ ๆ ที่พวกเรา I GEAR GEEK ได้มีโอกาสใช้งานก็จะมาแบ่งปันกันอีกครับผม ~~