Auto Deploy project Laravel lên Heroku

Mở đầu

Khi lập trình một website chắc hẳn ai cũng biết đến khái niệm Deploy. Có thể hiểu đơn giản đó là việc triển khai một website lên máy chủ (server) mà mọi người có thể truy cập được trang web đó từ bên ngoài thông qua internet.

Như vậy nhiều bạn sẽ nghĩ ngay rằng, việc deploy này chỉ thực hiện khi mà project của mình đã hoàn thiện. Đó là một ý nghĩ sai lầm mà trước đây làm project mình đã mắc phải. Thực tế môi trường trên server và trên local rất khác nhau. Nhiều thứ có thể chạy ngon lành cành đào trên local nhưng khi đưa lên server nó có thể bị lỗi. Nếu lỗi này không được phát hiện kịp thời và sửa ngay thì nó sẽ càng ngày càng trở nên trầm trọng hơn khi code của mình đủ lớn. Việc fix một cái lỗi lớn như vậy sẽ tốn rất nhiều công sức và làm chậm tiến độ hoàn thành project của mình.

Cách tốt nhất để phát hiện lỗi và sửa lỗi sớm là vừa code vừa deploy lên server. Nếu công việc này thực hiện bằng tay thì rất mất nhiều công sức, nó nên được thực hiện một cách tự động.

Bài viết hôm nay mình xin gửi tới các bạn cách thực hiện Auto deploy laravel project lên Heroku.

Server Heroku có nhiều ưu điểm thích hợp để demo các trang web nhỏ như:

  • Có thể kết nối với git
  • Up code bằng git, tốc độ đẩy code lên nhanh
  • Chạy rất tốt với ứng dụng PHP
  • Cho bạn host miễn phí 5 ứng dụng. Chứng thực bằng cách nhập thông tin thẻ tín dụng sẽ tăng lên 200 ứng dụng miễn phí
  • Và đặc biệt nó có chức năng auto deploy code khi kết nối với git mà chúng ta sẽ cùng tìm hiểu sau đây

Làm quen với Heroku

Tạo Heroku app và database

  • Trang chủ Heroku https://www.heroku.com/. Hãy tạo một tài khoản để sử dụng nhé.
  • Cài đặt Heroku cli
sudo add-apt-repository "deb https://cli-assets.heroku.com/branches/stable/apt ./"
curl -L https://cli-assets.heroku.com/apt/release.key | sudo apt-key add -
sudo apt-get update
sudo apt-get install heroku
  • Đăng nhập
heroku login
  • Tạo App

Có thể sử dụng giao diện trên dashboard để tạo hoặc dùng câu lệnh:

heroku create projectname

Quản lý các App đã tạo tại https://dashboard.heroku.com/apps

  • Tạo database
heroku addons:create heroku-postgresql:hobby-dev

Quản lý các database đã tạo tại https://data.heroku.com/

Để xem thông tin đăng nhập database các bạn vào database đó rồi chọn mục View Credentials...

Tạo biến config env

Một app Heroku có thể có các biến env. Nó như là các biến trong file .env của laravel vậy. Ta có thể vào phần setting của từng app để cấu hình biến này. Thông thường thì sẽ cấu hình Database và một số biến khác.

Add Buildpacks

Buildpacks là một thành phần rất quan trọng. Nó sẽ quy định xem ta sử dụng các gói cài đặt nào trong project của mình. Ở đây mình sử dụng Laravel và React nên sẽ cần 2 gói nodejsphp. Lưu ý: Các gói sẽ cài đặt theo thứ tự từ trên xuống dưới. Như ở hình trên nodejs sẽ được cài đặt trước. Ta phải để như vậy. Mục đích thì mình sẽ nói rõ hơn ở phần dưới.

Cài đặt thư mục root

Để cài đặt thư mục root cho app Heroku ta sử dụng lệnh sau

echo web: vendor/bin/heroku-php-apache2 public/ > Procfile

Câu lệnh trên thực chất là tạo file Procfile có nội dung là web: vendor/bin/heroku-php-apache2 public/ tại thư mục gốc trong project của mình.

Heroku và Git

Để Heroku auto deploy khi ta push một commit lên git ta cần làm 2 bước:

  • Liên kết ứng dụng với repository của git
  • Thiết lập file composer.json để khi Heroku auto deploy chạy đúng các lệnh

Liên kết Heroku với Git

Để liên kết với git ta vào một ứng dụng Vào phần Deploy. Trong mục Deployment method, chọn Git để liên kết. Ấn nút Connect to github sau đó thực hiện quá trình liên kết. Sau đó, đăng nhập vào Git rồi tiến hành liên kết. Nhập tên repository ở repo-name. Tìm kiếm rồi connect đến repository cần deploy.

Khi liên kết xong, trên giao diện sẽ xuất hiện ô chọn branch cần deploy. Bạn chọn branch cần thiết và ấn vào nút Enable Automatic Deploys. Như vậy là khi có một thay đổi nào đó được push lên branch được chọn, thì heroku sẽ tự động deploy cho mình. Nhưng mà làm thế nào để điều khiển Heroku chạy đúng các câu lệnh phục vụ cho deploy đây. Ví dụ như lệnh php artisan migrate của laravel chẳng hạn. Ý tưởng của mình là sẽ cho các lệnh đó chạy trong scripts của file composer.json.

Thiết lập file composer.json

Xem qua một chút về script trong file composer.json của laravel.

"scripts": {
        "post-root-package-install": [
            "php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "php artisan key:generate"
        ],
        "post-install-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postInstall",
            "php artisan optimize"
        ],
        "post-update-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postUpdate",
            "php artisan optimize"
        ]
},

Heroku khi build sẽ chạy script post-install-cmd. Để nó có thể chạy được các command như php artisan key:generate thì mình sẽ cho vào đây.

Nhưng trước hết nó phải có file .env đã (vì file này được ignore rồi). Để tạo file .env ta copy y nguyên dòng "php -r \"file_exists('.env') || copy('.env.example', '.env');\"" là xong. Tiếp đó là tạo key (key:generate), rồi cuối cùng mới chạy migrate. Chú ý: Bạn phải chắc chắn là đã cấu hình các biến env để kết nối với database Thế là xong phần chạy các lệnh cấu hình của laravel.

Để nó chạy các lệnh khác thì ta cũng làm tương tự. Ví dụ: project của mình sử dụng react nên cần phải chạy npm install, npm run production, ... thì script sẽ như sau:

"scripts": {
        "post-root-package-install": [
            "php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "php artisan key:generate"
        ],
        "deploy": [
            "php -r \"file_exists('.env') || copy('.env.example', '.env');\"",
            "php artisan key:generate",
            "php artisan migrate",
            "npm install",
            "npm run production"
        ],
        "post-install-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postInstall",
            "php artisan optimize",
            "@deploy"
        ],
        "post-update-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postUpdate",
            "php artisan optimize",
            "@deploy"
        ]
    },

Các bạn còn nhớ là phải để buildpack nodejs lên trên php không?

Chính là để phục vụ cho câu lệnh npm install đấy. Tức là khi nó deploy, nó sẽ chạy build nodejs trước build php sau. Thì như vậy lúc này ta mới có npm để chạy lệnh npm install được.

Bạn có thể tham khảo project của mình tại đây. Bạn có thể tìm hiểu thêm về script của composer tại đây https://getcomposer.org/doc/articles/scripts.md.

Travis với việc deploy project lên Heroku

Làm quen với travis ci

Travis là một dịch vụ (service) CI, miễn phí và là open source.

Trong đó CI là viết tắt của từ Continuous Integrantion, nghĩa là tích hợp liên tục. Tích hợp liên tục (CI) nghĩa là trong quá trình phát triển phần mềm, các thành viên trong nhóm nghiên cứu phải tích hợp công việc của họ thường xuyên, thông thường mỗi người đều phải tích hợp công việc ít nhất một lần vào cuối ngày. Sau mỗi tích hợp là công việc build tự động (bao gồm test) để phát hiện lỗi tích hợp càng sớm càng tốt. Chính vì tính chất có thể phát hiện lỗi sớm, nên CI đã rất được các team phát triển phần mềm ưa dùng.

Sử dụng phiên bản free tại https://travis-ci.org , và phiên bản trả phí tại https://travis-ci.com.

Các tính năng chính của Travis-ci

  • Tích hợp tự động với Github
  • Hỗ trợ cho hơn 20 ngôn ngữ lập trình
  • Hỗ trợ build và test
  • Hỗ trợ deploy lên nhiều cloud services
  • Cung cấp feedback qua mail
  • Check chất lượng code

Mục đích của việc sử dụng Travis-ci ở trong bài viết này là test các unit test, kiểm tra các lỗi trước khi deploy lên cloud services (cụ thể ở đây là Heroku).

Liên kết travis với git

Truy cập vào https://travis-ci.org, ấn vào nút "Sign in with Github" hay "Sign up" Sau đó thực hiện "Authorize application" là xong.

Sau khi đăng nhập xong sẽ có giao diện như sau:

Bạn ấn vào dấu cộng bên phải tab "My Repositories" để bật những Repositories cần travis-ci lắng nghe.

TIếp theo chúng ta cần tạo các file cấu hình cho travis-ci. Travis-ci sẽ cần 2 file cấu hình:

  • .travis.yml
  • phpunit.xml

Cấu hình travis cho laravel project

Đối với các project dùng laravel bạn có thể tham khảo cách cấu hình travis của mình như sau: File .env.travis

APP_ENV=testing
APP_KEY=SomeRandomString

DB_CONNECTION=testing
DB_TEST_USERNAME=root
DB_TEST_PASSWORD=

CACHE_DRIVER=array
SESSION_DRIVER=array
QUEUE_DRIVER=sync

Thêm connections testing vào file config/database.php

'connections' => [
        'testing' => [
            'driver'    => 'mysql',
            'host'      => env('DB_TEST_HOST', 'localhost'),
            'database'  => env('DB_TEST_DATABASE', 'homestead_test'),
            'username'  => env('DB_TEST_USERNAME', 'homestead'),
            'password'  => env('DB_TEST_PASSWORD', 'secret'),
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
            'strict'    => false,
        ],
]

File .travis.yml

language: php

php:
  - 5.6

before_script:
  - cp .env.travis .env
  - mysql -e 'create database homestead_test;'
  - composer install --no-interaction
  - php artisan key:generate
  - php artisan migrate
script:
  - vendor/bin/phpunit
deploy:
  provider: heroku
  api_key: fd0f0e37-2887-484e-a6e0-137cdxxxxxxx
  app: react-tutorial-hoanghoi
  run:
    - php artisan migrate --force

Giải thích một chút về phần deploy trong file cấu hình trên file .travis.yml:

  • provider: heroku ==> cloud services Heroku
  • api_key: fd0f0e37-2887-484e-a6e0-137cdxxxxxxx ==> Api Key. Bạn có thể xem Api của mình tại Account Settings
  • app: react-tutorial-hoanghoi ==> Tên App heroku sẽ deploy lên
  • run: ==> các lệnh sau khi chạy build các gói đã cài đặt trong Heroku sẽ được thêm ở đây.

File composer.json và các biến env của Heroku sẽ cấu hình tương tự như cách auto deploy trực tiếp từ Heroku.

Còn file phpunit.xml thì laravel tự động có nên ta sẽ giữ nguyên.

Bạn có thể tham khảo project của mình tại đây.

Kết luận

Như vậy là chúng ta đã cùng nhau tìm hiểu cách deploy một project laravel lên Heroku một cách tự động. Cảm ơn các bạn đã đọc bài viết của mình. Nếu thấy bài viết hay hãy vote up và chia sẻ cho bạn bè nhé. 😃

Nếu có thắc mắc gì về bài viết xin hãy để lại comment bên dưới.