Xin chào mọi người, như mọi người có thể đã biết thì kể từ 28/11/2022 Heroku đã chính thức ngừng cung cấp các plan miễn phí (Free Heroku Postgres, free Heroku Data for Redis®, and free Heroku Dynos). Hiện tại, heroku yêu cầu người dùng nâng cấp lên các plans giá rẻ hoặc cao hơn để tiếp tục sử dụng dịch vụ.
Với mong muốn đi tìm dịch vụ khác miễn phí thay thế Heroku để deploy cái project laravel làm demo, tìm một hồi thì cũng gặp được một bạn Voz giới thiệu đến Railway.App. Sau một hồi ngồi vọc vạch thì mình thấy nó khá dễ sử dụng và muốn chia sẻ với mọi người. Ở bài viết này xin mạn phép hướng dẫn mọi người vài bước đơn giản để deploy project laravel trên Railway.app.
Railway.App??
Giới thiệu
Railway.App mới được triển khai vào đầu năm 2021 đến nay với mong muốn cung cấp giải pháp dễ dàng và tiết kiệm để deploy một ứng dụng production chỉ trong vài phút.
Railway hỗ trợ triển khai project của bạn dựa trên Nixpacks, một open-source tool phát triển bởi Railway team. Bạn chỉ cần đưa project lên, Nixpacks sẽ dựa trên project của bạn để tạo image phù hợp và chạy project đó.
Bạn sẽ bắt đầu với gói miễn phí (Starter plan) sau khi xác thực tài khoản. Starter có $5 hoặc 500 giờ sử dụng/ tháng
, số giờ sẽ tính cho thời gian mà các services chạy, còn $5 là khoản chi trả cho RAM và CPU nếu project của bạn vượt giới hạn mức của plan.
Khi hết tài nguyên (dùng hết $5 hoặc 500 giờ chạy tùy theo cái nào đến trước) thì project của bạn sẽ bị ngưng và phải start lại thủ công vào tháng tiếp theo. Bạn cũng có thể thêm thẻ tín dụng để nâng các giới hạn.
Đăng ký tài khoản Railway
Việc đăng ký rất đơn giản, bạn chỉ cần xác thực bằng tài khoản github là có thể bắt đầu sử dụng được tài khoản của mình ở Railway. Nhớ đồng ý với điều khoản, kết nối với Github để verify tài khoản và nhận $5 và 500 giờ sử dụng/tháng.
Chuẩn bị Deploy project Laravel
Để bắt tay vào việc deploy project laravel của bạn thì cần phải chuẩn bị trước một chút. Đương nhiên là một project trên tài khoản github mà bạn vừa liên kết với Railway rồi. Ngoài ra, Railway cũng hỗ trợ deploy từ local, bạn có thể thamkhảo thêm https://docs.railway.app/.
Phần này sẽ giới thiệu trước một số thuật ngữ.
Projects
Ở trên Dashboard sẽ liệt kê tất cả các projects của bạn. Mỗi project sẽ bao gồm các services và environments - hỗ trợ cho bạn triển khai nhiều môi trường (develop, staging, product) cho project đó.
Services
Mỗi project thì có thể bao gồm nhiều services. Có 2 loại là:
- Persistent database services (PostgreSQL, MySQL, MongoDB, Redis)
- Ephemeral deployment services (Hỗ trợ template cho nhiều ngôn ngữ và nhiều framework khác nhau https://railway.app/templates)
Như đã giới thiệu từ trước,* Railway Nixpacks* sẽ đọc mã nguồn của bạn và tự tạo ra một bản image phù hợp. Trên một dự án Laravel tiêu chuẩn, Nixpacks sẽ thiết lập Nginx để xử lý các requests, PHP với phiên bản yêu cầu của dự án của bạn, NodeJS với trình quản lý package của bạn Yarn, pnpm hoặc npm.
Deploy project Laravel trên Railway
Create new project with Railway
Việc bắt đầu dự án mới với Railway rất đơn giản. Truy cập https://railway.app/new hoặc chọn Create a New Project tại Dashboard. Thiết lập kho lưu trữ mà bạn muốn.
Ở bài hướng dẫn này mình sử dụng Deploy from Github repo
. Bạn cần cấp quyền cho Railway App sử dụng repository github để triển khai. Ở đây mình đã cấp quyền trước đó rồi nên sẽ có lựa chọn để deploy ngay (Deploy now).
Project của bạn sẽ bắt đầu deploy service đầu tiên (service laravel), bước Build
và Deploy
có thể chạy suôn sẻ. Cũng đừng quá lo lắng khi bạn không thể truy cập trang đích ngay vì Laravel cần thiết lập một vài biến và chạy một vài lệnh, chúng ta sẽ hoàn tất trong các bước tiếp theo.
Create database to deploy project in Railway cung cấp các
Vì hệ thống sẽ được reset mỗi lần deploy nên không thể sử dụng CSDL cục bộ như SQLite. Railway cung cấp các DBMS như MySQL, PostgreSQL, MongoDB và Redis.
Trong Railway Project, chọn nút thêm mới New và chọn DBMS phù hợp với dự án của bạn.
Sau khi service MySQL
được khởi tạo xong, bạn có thể xem các thông tin đăng nhập tại tab Variables dưới dạng KEY và value bị ẩn đi.
Bạn có thể sao chép các giá trị này vào Enviroment variables của Laravel (ở bước sau) hoặc sử dụng biến dạng ${{ KEY }}
(ví dụ ${{ MYSQLDATABASE }}
) để project có thể kết nối vào DB.
Config enviroment variables cho Laravel service
Để Laravel có thể chạy được thì ta cần cấu hình lại file .env
tuy nhiên ở đây ta có thể cấu hình các biến môi trường trực tiếp trên service.
Có thể chọn Raw Editor để sửa 1 cục giống khi bạn edit file .env
Sử dụng https://generate-random.org/laravel-key-generator?count=1 để generate APP_KEY và thêm vào biến hệ thống
Các biến môi trường của Laravel để connect tới DB bạn có thể tham khảo đoạn sau:
DB_CONNECTION=mysql
DB_HOST=${{ MYSQLHOST }}
DB_PORT=${{ MYSQLPORT }}
DB_DATABASE=${{ MYSQLDATABASE }}
DB_USERNAME=${{ MYSQLUSER }}
DB_PASSWORD=${{ MYSQLPASSWORD }}
(trên ảnh mình sai DB_USERNAME=${{ MYSQLUSER }}
nha mọi người 😉)
Mỗi lần sửa lại các biến môi trường của service, một bản deploy sẽ được build lại từ đầu.
Custom Build command cho Laravel khi build Services
Mặc định, Nixpacks chỉ chạy một số lệnh đơn giản khi build project PHP . Để chạy các lệnh như php artisan migrate
hay clear cahce bạn cần custom lại Nixpacks để phù hợp với project của mình.
Cách tốt nhất để custom lại là thêm biến môi trường NIXPACKS_BUILD_CMD
giống như bạn thêm ở bước Config enviroment variables cho Laravel service
Như ảnh trên, trong bước build
, Nixpacks chỉ chạy lệnh [yarn|pnpm|npm] [prod|build]
. Khi ta overide lại bước này thì cũng cần thêm lại lệnh đó để build các tài nguyên assets. Phía dưới là NIXPACKS_BUILD_CMD
của mình:
NIXPACKS_BUILD_CMD = php artisan optimize && php artisan config:clear && php artisan cache:clear && php artisan migrate --force && npm install bower && ./node_modules/bower/bin/bower install && npm run prod
Mình minh họa một cách tiếp cận đơn giản bằng cách chạy từng lệnh trong một chuỗi với &&
, nhưng bạn có thể đặt tất cả lệnh này vào composer script, bash script hoặc Makefile.
Add custom acccess domain to project Railway
Theo mặc định, Project của bạn sẽ không được truy cập công khai. Bạn có thể đi tới Tab Settings của service Laravel để thêm miền phụ có sẵn hoặc tên miền tùy chỉnh của riêng bạn.
Bây giờ bạn đã có thể truy cập đường dẫn project của bạn rồi!
Một vài cài đặt thêm
Thêm https protocol
Mặc định thì Laravel sẽ sử dụng phương thức http
để render ra link assets. Mà railway có hỗ trợ https
khiến ứng dụng không thể tải được các tài nguyên assets.
Bạn nên buộc các URL sử dụng giao thức https
bằng cách thêm đoạn code sau vào hàm boot()
trong file App/Providers/AppServiceProvider
public function boot()
{ if ($this->app->environment('production')) { URL::forceScheme('https'); }
}
Sử dụng Redis và s3 để lưu trữ liên tục
Why are my file uploads missing/deleted from the Application? Do ngoài DB ra thì các services khác không có hệ thống lưu trữ file liên tục cho nên khi Services build lại sẽ mất hết dữ liệu cũ.
Mặc định Laravel sẽ sử dụng file driver để lưu cache, queue, log, session nên trong tình huống này có thể hoạt động không bình thường, làm ngắt kết nối người dùng sau mỗi lần deploy.
Chúng ta có thể sử dụng Redis để lưu trữ thay vì file. Tạo một service giống như bạn tạo service MySQL.
Sửa các biến môi trường driver của laravel về Redis và thêm biến mỗi trường kết nối với Redis
Còn đối với file thì bạn nên sử dụng các dịch vụ lưu trữ như s3
của AWS để thay thế.
Creating a worker server
Railway chỉ cho phép 1 tiến trình duy nhất chạy xuyên suốt với mỗi services, service laravel của chúng ta hiện tại đang chạy tiến trình của nginx và php.
Nếu bạn cần 1 tiến trình để chạy queue
cho project của mình?
Hãy tạo 1 service mới, cũng chọn repository đó một lần nữa. Sau đó copy toàn bộ biến môi trường của service laravel để chúng chạy chung 1 config. Bạn hãy overide lại biến NIXPACKS_START_CMD
để chạy tiến trình Laravel queue worker
Conclusion
Hy vọng là bài hướng dẫn này sẽ giúp ích mọi người deploy project Laravel lên internet bằng Railway. Vì tài nguyên của Railway cho có hạn nên chỉ có thể dùng để test, nghiên cứu và demo thôi.
Mình cảm thấy Railway sẽ là lựa chọn thay thế miễn phí hoàn hảo hiện nay cho Heroku. Mọi người còn trang nào khác ngon hơn không?
Mong các bạn xài chừng mực, hợp lí, đừng lập nhiều tài khoản spam. Nếu thế thì chẳng còn dịch vụ nào free mà ngon cho mọi người dùng nữa. Thân!
Tham khảo: https://invariance.dev/2022-08-04-deploy-laravel-on-railway.html Biên tập: nampt.me