Tại sao CI/CD quan trọng cho dự án Laravel Livewire
Laravel Livewire là một framework full‑stack cho phép xây dựng giao diện động mà không cần viết JavaScript. Tuy nhiên, khi dự án phát triển, số lượng component, migration, và test case sẽ tăng nhanh, khiến việc quản lý môi trường phát triển, kiểm thử và triển khai trở nên phức tạp. CI/CD (Continuous Integration / Continuous Deployment) giúp tự động hoá các bước này, giảm thiểu lỗi con người, tăng tốc độ đưa tính năng mới vào production và duy trì tính ổn định của hệ thống.
Đối với Livewire, một trong những thách thức lớn là đồng bộ trạng thái component giữa server và client. Khi có thay đổi trong component, chúng ta cần chắc chắn rằng các unit test và integration test vẫn chạy thành công trước khi đẩy lên môi trường thực tế. CI/CD cung cấp một quy trình chuẩn, từ build Docker image, chạy phpunit, tới deploy tự động, giúp đội ngũ phát triển tập trung vào việc viết code thay vì lo lắng về cấu hình môi trường.
Chuẩn bị môi trường Docker cho Laravel Livewire
Docker cho phép chúng ta đóng gói toàn bộ stack (PHP, Nginx, MySQL, Redis, …) vào các container độc lập, tái tạo môi trường một cách nhất quán trên máy local, CI runner và server production. Đối với Livewire, chúng ta cần một image PHP-FPM có các extension cần thiết (pdo_mysql, bcmath, intl, …) và một web server (thường là Nginx) để phục vụ các request.
Tạo Dockerfile cho PHP-FPM
FROM php:8.2-fpm
# Cài đặt các extension cần thiết cho Laravel
RUN apt-get update && apt-get install -y \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
zip \
unzip \
git \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install gd pdo_mysql bcmath intl opcache
# Cài đặt Composer
COPY --from=composer:2.7 /usr/bin/composer /usr/bin/composer
# Thiết lập thư mục làm việc
WORKDIR /var/www/html
# Copy source code (sẽ được mount trong docker‑compose cho môi trường dev)
COPY . /var/www/html
# Đặt quyền cho storage và bootstrap/cache
RUN chown -R www-data:www-data storage bootstrap/cache
EXPOSE 9000
CMD ["php-fpm"]Dockerfile trên sử dụng php:8.2-fpm làm base image, cài đặt các extension Laravel thường dùng và Composer. Lưu ý việc chown thư mục storage và bootstrap/cache để PHP‑FPM có quyền ghi.
Cấu hình Docker Compose cho môi trường phát triển
version: "3.9"
services:
app:
build:
context: .
dockerfile: Dockerfile
image: laravel-livewire-app:dev
container_name: livewire_app
restart: unless-stopped
volumes:
- .:/var/www/html
environment:
- APP_ENV=local
- APP_DEBUG=true
- DB_HOST=db
- DB_DATABASE=livewire
- DB_USERNAME=root
- DB_PASSWORD=secret
depends_on:
- db
- redis
networks:
- laravel
nginx:
image: nginx:stable-alpine
container_name: livewire_nginx
restart: unless-stopped
ports:
- "8080:80"
volumes:
- .:/var/www/html
- ./nginx/conf.d:/etc/nginx/conf.d
depends_on:
- app
networks:
- laravel
db:
image: mysql:8.0
container_name: livewire_mysql
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=secret
- MYSQL_DATABASE=livewire
volumes:
- db_data:/var/lib/mysql
ports:
- "3306:3306"
networks:
- laravel
redis:
image: redis:7-alpine
container_name: livewire_redis
restart: unless-stopped
ports:
- "6379:6379"
networks:
- laravel
networks:
laravel:
driver: bridge
volumes:
db_data:File docker-compose.yml định nghĩa bốn service: app (PHP‑FPM), nginx, db (MySQL) và redis. Thông qua volumes chúng ta mount source code vào container, cho phép hot‑reload khi chỉnh sửa file.
Cấu hình GitHub Actions: workflow tự động
GitHub Actions là nền tảng CI/CD tích hợp sẵn trong GitHub, cho phép chúng ta định nghĩa các job dưới dạng YAML. Dưới đây là một workflow mẫu thực hiện các bước:
- Checkout code.
- Build Docker image.
- Chạy unit test với PHPUnit.
- Push image lên Docker Hub (hoặc GitHub Container Registry).
- Deploy image tới server production bằng SSH.
File .github/workflows/ci-cd.yml
name: CI/CD Laravel Livewire
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build-test-deploy:
runs-on: ubuntu-latest
services:
mysql:
image: mysql:8.0
env:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: livewire_test
ports: ["3306:3306"]
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
extensions: mbstring, bcmath, intl, pdo_mysql, gd
tools: composer
- name: Install dependencies
run: composer install --prefer-dist --no-progress --no-suggest
- name: Generate application key
run: php artisan key:generate
- name: Run migrations
env:
DB_HOST: 127.0.0.1
DB_DATABASE: livewire_test
DB_USERNAME: root
DB_PASSWORD: secret
run: php artisan migrate --no-interaction
- name: Run PHPUnit tests
env:
DB_HOST: 127.0.0.1
DB_DATABASE: livewire_test
DB_USERNAME: root
DB_PASSWORD: secret
run: vendor/bin/phpunit --colors=always
- name: Build Docker image
run: |
docker build -t myrepo/livewire-app:${{ github.sha }} .
- name: Log in to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Push Docker image
run: |
docker push myrepo/livewire-app:${{ github.sha }}
- name: Deploy to production server
if: github.ref == 'refs/heads/main'
uses: appleboy/[email protected]
with:
host: ${{ secrets.PROD_HOST }}
username: ${{ secrets.PROD_USER }}
key: ${{ secrets.PROD_SSH_KEY }}
script: |
docker pull myrepo/livewire-app:${{ github.sha }}
docker stop livewire_app || true
docker rm livewire_app || true
docker run -d \
--name livewire_app \
-p 9000:9000 \
-e APP_ENV=production \
-e APP_DEBUG=false \
-e DB_HOST=${{ secrets.PROD_DB_HOST }} \
-e DB_DATABASE=${{ secrets.PROD_DB_NAME }} \
-e DB_USERNAME=${{ secrets.PROD_DB_USER }} \
-e DB_PASSWORD=${{ secrets.PROD_DB_PASS }} \
myrepo/livewire-app:${{ github.sha }}Workflow trên sử dụng service MySQL để chạy migration và test, sau đó build Docker image, đẩy lên Docker Hub và cuối cùng SSH vào server để khởi chạy container mới. Tất cả các biến nhạy cảm được lưu trong GitHub Secrets để bảo mật.
Kiểm thử tự động với PHPUnit
Laravel đã tích hợp sẵn PHPUnit, cho phép viết unit test cho model, service, và thậm chí cho Livewire component. Đối với Livewire, chúng ta có thể sử dụng Livewire\Testing\Testable để mô phỏng hành vi của component.
Ví dụ test một component Livewire
assertSet('count', 0)
->call('increment')
->assertSet('count', 1);
}
}
?>
Test trên khởi tạo một instance của component Counter, kiểm tra giá trị mặc định count và gọi method increment. Khi chạy vendor/bin/phpunit, GitHub Actions sẽ tự động thực thi và báo cáo kết quả.
Triển khai lên môi trường production
Sau khi Docker image đã được đẩy lên registry, chúng ta có thể triển khai bằng nhiều cách: Docker Swarm, Kubernetes, hoặc đơn giản là Docker Compose trên server. Đối với các dự án vừa và nhỏ, Docker Compose vẫn là lựa chọn nhanh chóng.
docker‑compose.production.yml
version: "3.9"
services:
app:
image: myrepo/livewire-app:${IMAGE_TAG}
container_name: livewire_app_prod
restart: always
environment:
- APP_ENV=production
- APP_DEBUG=false
- DB_HOST=${DB_HOST}
- DB_DATABASE=${DB_DATABASE}
- DB_USERNAME=${DB_USERNAME}
- DB_PASSWORD=${DB_PASSWORD}
networks:
- laravel
nginx:
image: nginx:stable-alpine
container_name: livewire_nginx_prod
restart: always
ports:
- "80:80"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
depends_on:
- app
networks:
- laravel
networks:
laravel:
driver: bridge
Trên server production, chúng ta chỉ cần thiết lập các biến môi trường (IMAGE_TAG, DB_HOST, …) và chạy docker compose -f docker-compose.production.yml up -d. Docker sẽ tải image mới nhất, khởi động các container và tự động cân bằng tải qua Nginx.
Kết luận và hướng học thêm
Việc thiết lập một pipeline CI/CD hoàn chỉnh cho Laravel Livewire không chỉ giúp giảm thiểu rủi ro khi đưa tính năng mới lên production mà còn tạo ra một môi trường phát triển nhất quán, dễ bảo trì. Các bước chính bao gồm: xây dựng Docker image chuẩn, viết test tự động với PHPUnit, cấu hình workflow GitHub Actions và triển khai bằng Docker Compose hoặc orchestrator khác. Khi quy trình này được tự động hoá, đội ngũ phát triển có thể tập trung vào việc tối ưu UI/UX của Livewire component, cải thiện trải nghiệm người dùng mà không lo lắng về các lỗi môi trường.
Để nâng cao kiến thức và thực hành chi tiết hơn, Tham khảo khóa học "Khóa học Laravel Livewire từ cơ bản đến nâng cao" tại đây.





