工具 6 分鐘閱讀

用 GitHub Actions 自動部署 Laravel 專案:CI/CD 入門

用 GitHub Actions 自動部署 Laravel 專案:CI/CD 入門

前言

做了一年的接案,我歸納出一個道理:手動部署遲早會出事。 某次凌晨部署更新忘了跑 migration,整個網站掛了兩小時。從那之後我就開始認真研究 CI/CD。

什麼是 CI/CD?

  • CI(Continuous Integration):每次 push 自動跑測試
  • CD(Continuous Deployment):測試通過後自動部署

簡單來說,就是把手動的「測試 → 建構 → 部署」流程全部自動化。

GitHub Actions 基本架構

在專案根目錄建立 .github/workflows/ 資料夾,裡面放 YAML 設定檔。

第一步:自動化測試

# .github/workflows/tests.yml
name: Tests

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]

jobs:
  tests:
    runs-on: ubuntu-latest

    services:
      mysql:
        image: mysql:8.0
        env:
          MYSQL_ROOT_PASSWORD: password
          MYSQL_DATABASE: testing
        ports:
          - 3306:3306
        options: >-
          --health-cmd="mysqladmin ping"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=3

    steps:
      - uses: actions/checkout@v4

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.3'
          extensions: mbstring, pdo_mysql
          coverage: xdebug

      - name: Install Dependencies
        run: composer install --no-interaction --prefer-dist

      - name: Copy Environment File
        run: cp .env.ci .env

      - name: Generate Key
        run: php artisan key:generate

      - name: Run Migrations
        run: php artisan migrate --force
        env:
          DB_CONNECTION: mysql
          DB_HOST: 127.0.0.1
          DB_PORT: 3306
          DB_DATABASE: testing
          DB_USERNAME: root
          DB_PASSWORD: password

      - name: Run Tests
        run: php artisan test
        env:
          DB_CONNECTION: mysql
          DB_HOST: 127.0.0.1
          DB_PORT: 3306
          DB_DATABASE: testing
          DB_USERNAME: root
          DB_PASSWORD: password

第二步:自動部署

測試通過後,自動部署到正式環境:

# .github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    needs: tests

    steps:
      - uses: actions/checkout@v4

      - name: Deploy to Server
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SERVER_SSH_KEY }}
          script: |
            cd /var/www/project
            git pull origin main
            composer install --no-dev --optimize-autoloader
            php artisan migrate --force
            php artisan config:cache
            php artisan route:cache
            php artisan view:cache
            php artisan queue:restart

設定 Secrets

在 GitHub 的 Repository Settings → Secrets and variables → Actions 中加入:

  • SERVER_HOST:伺服器 IP
  • SERVER_USER:SSH 使用者名稱
  • SERVER_SSH_KEY:SSH 私鑰

.env.ci 範例

APP_NAME=Laravel
APP_ENV=testing
APP_KEY=
APP_DEBUG=true

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=testing
DB_USERNAME=root
DB_PASSWORD=password

加入前端建構

如果專案有前端資源需要編譯:

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install npm dependencies
        run: npm ci

      - name: Build assets
        run: npm run build

進階:通知

部署完成後發送通知到 LINE 或 Slack:

      - name: Notify on LINE
        if: success()
        run: |
          curl -X POST https://notify-api.line.me/api/notify \
            -H "Authorization: Bearer ${{ secrets.LINE_TOKEN }}" \
            -F "message=✅ 部署完成:${{ github.sha }}"

與其他工具搭配

  • 搭配 Git 工作流程,push 到 main 就自動部署
  • 搭配 Docker 可以做容器化部署
  • 前端可以部署到 Vercel,後端用 GitHub Actions 部署

小結

做了一年的接案,我歸納出:CI/CD 是投資報酬率最高的自動化之一。設定一次之後,每次部署都是安心的、可預期的、可回溯的。不再需要凌晨手動部署時心驚膽戰了。

如果你需要類似的系統,歡迎聯繫討論。

#GitHub Actions #CI/CD #Laravel
Thousand Lab

Thousand Lab