ใน series โพสต์นี้ เราจะดู LiteStack one-stop-shop solution ที่ host และ process ข้อมูล production ทั้งหมดของคุณบน single machine LiteStack (ตามที่ชื่อบ่งชี้) ใช้ SQLite เพื่อให้:
- database ใช้ LiteDB adapter
- ActiveJob backend (LiteJob)
- ActionCable backend (LiteCable)
- ActiveSupport::Cache store (LiteCache)
ในโพสต์แรกนี้ เราจะแนะนำ basics ของ LiteStack และตั้งค่า example Rails application
มาเริ่มกัน!
บทนำสู่ SQLite
SQLite เองเป็น go-to embedded database ของหลายอุตสาหกรรมมาหลายทศวรรษ ตัวอย่างเช่น มันใช้กันอย่างกว้างขวางใน native app development, testing environments, caching และอื่นๆ
gầnๆ นี้ มันดึงดูด experimentation และ extensions มาก หนึ่งใน extensions ยอดนิยมคือ Litestream ซึ่งสามารถ recover stream changes ไปยัง S3-compatible bucket นี่หมายความว่าคุณได้ replica ของ production database ในราคาถูกมาก และสามารถ recover จาก failure ได้ทุกเมื่อ
โดยบังเอิญ สิ่งนี้ทำให้การใช้ SQLite เป็น production database สำหรับ Rails app ของคุณเป็น feasible option ร่วมกับ full-fledged development stack อย่าง LiteStack มันสัญญาว่าจะทำให้ apps hosted on a single machine กลายเป็นความจริง เราอยู่ที่นี่เพื่อทดสอบ hypothesis นี้และชี้แจงอุปสรรคใดๆ ในทาง
เพื่อทำนี้ เราต้องการ example app ที่ซับซ้อนพอที่จะเผย potential difficulties แต simple พอที่จะพอดีกับ series นี้
Example Rails Application ของเรา
เราจะเขียน app ที่ transform children's drawings โดยใช้ StableDiffusion บน replicate.com
เป็นตัวอย่าง นี่คือ cute teddy bear ที่ลูกสาวผมวาด พร้อมกับ StableDiffusion interpretations สองสามแบบ:

เป็น rough sketch แอปของเราจะครอบคลุมขั้นตอนต่อไปนี้:
- User uploads รูปภาพพร้อม textual prompt (เราจะแสดง advanced SQLite techniques ที่นี่)
- User เลือก image style (เช่น "cartoon", "oil painting", "photorealistic", "3D rendering")
- Processing เกิดขึ้นใน background (นี่ kick off LiteJob-powered job)
- ระหว่าง processing เราแสดง placeholder image และ update logs ที่ส่งโดย server เมื่อเสร็จ เราอัปเดตเพื่อแสดง actual image นี่ช่วยให้เราสำรวจ LiteCable ขณะที่เรา replace image ผ่าน Turbo Streams
- เราเก็บ image prediction
- เราใช้ LiteCache เพื่อ wrap computationally costly views
ขั้นตอนเหล่านี้ให้ scaffold สำหรับ series นี้ ส่วนที่เหลือของโพสต์นี้ จะเกี่ยวกับการ setup app
เราเริ่มด้วยการสร้าง Rails app ใหม่ชื่อ skAItch ใช้ esbuild เป็น JavaScript bundler และ SASS เป็น CSS preprocessor:
ติดตั้ง LiteStack
ต่อไป เราติดตั้ง LiteStack โดยใช้ generator ที่มาพร้อม:
หลังจากเสร็จ เรา complete setup และเริ่ม development server:
Authentication และ Tenants
ต่อมา เราต้องการวิธี authenticate users เพื่อ associate prompts กับพวกเขา แทนที่จะใช้ incumbent อย่าง Devise ผมเลือกใช้ approach ที่แตกต่าง authentication-zero gem สามารถ flexibly generate authentication system แทนที่จะ include เป็น engine สะดวกมาก มันมาพร้อม options เช่น:
- authentication by token (สำหรับ APIs)
- two-factor auth
- multitenancy
- rate limiting
- OmniAuth interface
- passwordless auth
ผมเลือกเพิ่ม option --tenantable เพราะมันเป็นไอเดียดีเสมอที่จะ automatically scope database records ของคุณไปยัง accounts Authentication-zero ให้สิ่งนี้ด้วย AccountScoped model concern
มาเพิ่ม first user ผ่าน database seeds:
Prompt Scaffold
ตอนนี้ถึงเวลาเริ่มเขียน application logic จริงของเรา เราเริ่มด้วยการ define central model ของแอป: Prompt
เราอยากให้ prompt มี title, description และ reference ไปยัง account ที่สร้างมัน นอกจากนี้ เพื่อทดสอบ "file system" capabilities ของ SQLite เราอยากให้มันเก็บ prompt image ในรูป binary:
prompts resources entry ก็ถูกเพิ่มเข้า config/routes.rb สังเกตว่า authentication-zero เพิ่ม before_action authenticating user ไปที่ ApplicationController โดย default
เพิ่มเติม เรา include AccountScoped concern ใน Prompt model ซึ่งอนุญาตให้เรา scope stored records ตาม logged-in account เรายัง validate ว่า prompt title และ image ต้อง present
ขั้นตอนสุดท้ายเพื่อ enable multitenancy เราต้อง connect prompt ไปยัง account เมื่อมันถูกสร้าง เราทำสิ่งนี้ใน PromptsController:
การเชื่อมต่อ Rails Application ของเรากับ Replicate.com
Replicate.com เป็น leading platform สำหรับรัน AI predictions บน high-performance graphics cards มันมี API สำหรับสร้าง predictions, train และ store models ฯลฯ เพื่อใช้มัน คุณต้องได้ API token จาก https://replicate.com/account/api-tokens
Note: การรัน predictions บน Replicate อยู่ภายใต้ charge
โชคดีที่มี official และ unofficial clients ที่ interface กับ API หนึ่งใน wrapper คือ replicate-rails gem ซึ่งเราจะติดตั้งตอนนี้:
เพื่อเก็บ API key อย่างปลอดภัย เราจะใช้ Rails credentials:
การ edit และ save ไฟล์นี้จะ encrypt credentials ของคุณ และมันสามารถเปิดได้ก็ต่อเมื่อให้ RAILS_MASTER_KEY ที่ถูกต้อง
ตอนนี้ เราต้องนำไปใช้ ตามที่แนะนำใน replicate-rails' README เรา authenticate ต่อ Replicate ใน initializer เรายัง define webhook handler ซึ่ง (ในกรณีของเรา) คือแค่ class ที่วางในไฟล์เดียวกัน สังเกตว่าผมเพิ่ม binding.irb breakpoint ที่นี่สำหรับ first test ของ functionality
Replicate-rails ยัง ship default webhook controller ซึ่งเรียก handler ข้างต้น เราแค่ต้อง mount มันใน config/routes.rb:
เพื่อ test webhook locally คุณต้อง setup tunnel ตัวอย่างเช่น Ngrok ขั้นตอนในการ setup เหล่านี้อยู่นอก scope ของบทความนี้ แตค่อนข้าง simple โปรดอ้างอิง Ngrok docs
อย่างไรก็ตาม คุณต้องบอก Rails ว่ามันอาจ listen ถึง tunnel's URL ของคุณ เพื่อ enable นี้ ให้เพิ่มมันไปที่ allowed_hosts ใน config/application.rb:
การรัน Prediction
ตอนนี้เราจะทดสอบการสร้าง prediction bit ที่ขาดไปคือ hook มันขึ้นใน PromptsController General workflow มีดังนี้:
- เรา retrieve model (ในกรณีของเรา
stable-diffusion-img2imgmodel) จาก Replicate - เรา grab specific version (ในกรณีของเรา latest) เพื่อรัน prediction against
- เรา run prediction โดยระบุ:
- Text prompt describing image (ในกรณีของเรา prompt's title)
- Image prompt ที่เราต้อง provide เป็น Base64-encoded Data URL
- Webhook to ping เมื่อ prediction completes (เรา point มันที่ webhook route ที่ replicate-rails ให้มา)
หากคุณไปที่ https://YOUR_NGROK_URL/prompts/new และ upload รูปภาพพร้อม title คุณจะ trigger prediction ตอนเสร็จ มันจะ callback ผ่าน webhook ที่ให้มา เนื่องจากเราตั้ง binding.irb breakpoint ที่นั่น controller action หยุดใน REPL และเราสามารถมองดูรอบๆ ได้:
ตามที่เห็น การรันครั้งแรกของ image-to-image generation สำเร็จ Prediction model คืนค่า URL ไปยัง created image ซึ่งเราจะอยากเก็บ locally (พวกมันถูกลบที่ Replicate เป็นระยะ) เราจะดูสิ่งนี้ใกล้ชิดครั้งหน้า
Up Next: LiteDB Deep Dive
ในโพสต์เปิดตัวนี้ เราแนะนำสภาพแวดล้อม LiteStack เป็น alternative ที่น่าสนใจสำหรับ host ทุก components ของ Rails app บน single machine เรายังตั้งค่า example app ที่พูดคุยกับ Replicate.com สำหรับ AI image generation
ในส่วนถัดไปของ series นี้ เราจะสำรวจ element แรกและกลางของ LiteStack — LiteDB — อย่างลึกขึ้น เราจะดู traits บางอย่างที่ทำให้มัน powerful อย่าง unique common pitfalls, limitations และ tradeoffs
จนกว่าจะเจอกันใหม่ Happy coding!
P.S. หากคุณต้องการอ่านโพสต์ Ruby Magic ทันทีที่เผยแพร่ ให้สมัครสมาชิก newsletter Ruby Magic ของเรา และจะไม่พลาดโพสต์เด็ดๆ ไป!