W tym kompleksowym przewodniku zbudujemy solidny pipeline GitLab CI/CD dla aplikacji Laravel, który obejmuje automatyczne testowanie, kontrolę jakości kodu, budowanie zasobów i wdrażanie w wielu środowiskach. Ten pipeline zapewnia jakość kodu, zapobiega regresji i umożliwia niezawodne wdrożenia.
📋 Spis Treści
- 🚀 Budowanie Produkcyjnego Pipeline'u GitLab CI/CD dla Laravel: Od Testowania do Wdrożenia
Wprowadzenie
Dobrze zaprojektowany pipeline CI/CD jest kluczowy dla utrzymania jakości kodu i umożliwienia szybkich, niezawodnych wdrożeń. Ten przewodnik pokazuje, jak zbudować gotowy do produkcji pipeline GitLab CI/CD dla aplikacji Laravel, który obejmuje kompleksowe testowanie, analizę kodu, kompilację zasobów i automatyczne wdrażanie w wielu środowiskach.
Nasz pipeline następuje nowoczesne praktyki DevOps z równoległym wykonywaniem, inteligentnym cache'owaniem i wdrożeniami specyficznymi dla środowisk, zachowując jednocześnie bezpieczeństwo i niezawodność.
Przegląd Pipeline'u
Nasz pipeline CI/CD składa się z trzech głównych etapów:
- Etap Testowania: Uruchamia testy PHP i JavaScript równolegle
- Etap Budowania: Tworzy zoptymalizowane artefakty produkcyjne
- Etap Wdrażania: Wdraża do środowisk deweloperskich i produkcyjnych
Pipeline używa niestandardowego obrazu Docker zoptymalizowanego dla aplikacji Laravel i implementuje inteligentne cache'owanie w celu skrócenia czasów budowania.
Wymagania i Konfiguracja
Konfiguracja Obrazu Docker
Używamy niestandardowego obrazu Docker, który zawiera PHP 8.4 ze wszystkimi niezbędnymi rozszerzeniami:
image: registry.gitlab.com/dommmin/gitlab-ci/php-8.4-fpm:latest
Ten obraz powinien zawierać:
- PHP 8.4 z rozszerzeniami (mbstring, xml, bcmath, itp.)
- Composer
- Node.js i npm
- Git
- SQLite (do testowania)
Zmienne Środowiskowe
Skonfiguruj te globalne zmienne dla optymalnej wydajności:
variables:
COMPOSER_NO_INTERACTION: 1
COMPOSER_CACHE_DIR: .composer-cache
NODE_VERSION: "22"
FF_USE_FASTZIP: "true"
TRANSFER_METER_FREQUENCY: "2s"
PHPUNIT_JOBS: 4
COMPOSER_PROCESS_TIMEOUT: 2000
COMPOSER_MEMORY_LIMIT: -1
Wyjaśnienie kluczowych zmiennych:
COMPOSER_NO_INTERACTION: Zapobiega zadawaniu interaktywnych pytań przez ComposerFF_USE_FASTZIP: Włącza szybszą kompresję artefaktówPHPUNIT_JOBS: Włącza równoległe wykonywanie testówCOMPOSER_MEMORY_LIMIT: Usuwa limity pamięci dla Composer
Strategia Cache'owania
Implementuj inteligentne cache'owanie w celu skrócenia czasów budowania:
cache:
key:
files:
- composer.lock
- package-lock.json
paths:
- vendor/
- node_modules/
- .composer-cache/
policy: pull-push
when: on_success
untracked: true
Ta konfiguracja:
- Tworzy klucze cache oparte na plikach blokady
- Cache'uje zależności i artefakty budowania
- Aktualizuje cache tylko przy udanych buildach
- Zawiera nieśledzone pliki w cache
Etapy Pipeline'u
Etap Testowania
Job Testowania PHP
test:php:
stage: test
services:
- redis:latest
variables:
DB_CONNECTION: sqlite
DB_DATABASE: ":memory:"
SESSION_DRIVER: array
CACHE_DRIVER: array
QUEUE_CONNECTION: sync
before_script:
- *install_dependencies
- echo "=== Budowanie zasobów dla testów PHP ==="
- npm ci --no-audit --no-fund
- npm run build
- php artisan ziggy:generate
script:
- echo "=== Uruchamianie testów PHP i analizy ==="
- composer larastan || true
- composer pint --test || true
- ./vendor/bin/pest --log-junit=junit.xml --parallel
artifacts:
reports:
junit: junit.xml
paths:
- public/build
when: always
expire_in: 1 week
Ten job:
- Używa SQLite w pamięci dla szybkich testów bazy danych
- Uruchamia analizę statyczną z Larastan
- Sprawdza formatowanie kodu z Laravel Pint
- Wykonuje testy równolegle z Pest
- Generuje raporty JUnit dla integracji z GitLab
Job Testowania JavaScript
test:js:
stage: test
before_script:
- *install_dependencies
script:
- echo "=== Uruchamianie testów JavaScript i analizy ==="
- npm ci --no-audit --no-fund
- npm run build
- php artisan ziggy:generate
- npm run format || true
- npm run types || true
- npm run lint || true
artifacts:
paths:
- public/build
when: always
expire_in: 1 week
Ten job obsługuje:
- Sprawdzanie typów TypeScript
- Kontrolę jakości kodu ESLint
- Formatowanie kodu Prettier
- Kompilację i optymalizację zasobów
Etap Budowania
Etap budowania tworzy zoptymalizowane artefakty produkcyjne:
build:
stage: build
environment:
name: production
needs:
- test:php
- test:js
script:
- echo "=== Budowanie aplikacji ==="
- composer install --optimize-autoloader --classmap-authoritative --no-dev --prefer-dist --no-interaction --no-progress
- php artisan config:clear
- php artisan route:clear
- php artisan view:clear
- php artisan ziggy:generate
- echo "=== Budowanie zasobów frontend ==="
- npm ci --omit=dev --no-audit --no-fund
- npm install -g dotenv-cli
- dotenv -e $ENV_FILE -- npm run build:ssr
- echo "=== Tworzenie pakietu wydania ==="
- mkdir -p release
- shopt -s extglob
- cp -r !(release|.git|tests|node_modules|*.tar.gz|*.log|coverage.xml|junit.xml) release/
- tar -czf release.tar.gz -C release .
- rm -rf release
- ls -lah release.tar.gz
- echo "✅ Budowanie zakończone pomyślnie"
artifacts:
paths:
- release.tar.gz
expire_in: 1 day
Kluczowe optymalizacje:
- Instalacja Composer zoptymalizowana dla produkcji
- Czyszczenie cache dla optymalnej wydajności
- Build SSR (Server-Side Rendering)
- Tworzenie skompresowanych artefaktów
- Wykluczenie niepotrzebnych plików z wdrożenia
Etap Wdrażania
Szablon Wdrażania
.deploy_template: &deploy_template
stage: deploy
image: alpine:3.19
needs: [build]
before_script:
- apk add --no-cache openssh-client
- mkdir -p ~/.ssh
- echo "$SSH_KEY" | tr -d '\r' > ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- ssh-keyscan -p $SSH_PORT $SSH_HOST >> ~/.ssh/known_hosts
script:
- scp -P $SSH_PORT release.tar.gz $SSH_USER@$SSH_HOST:/home/$SSH_USER/laravel/ || exit 1
- scp -P $SSH_PORT $ENV_FILE $SSH_USER@$SSH_HOST:/home/$SSH_USER/laravel/shared/.env || exit 1
- scp -P $SSH_PORT deploy.sh $SSH_USER@$SSH_HOST:/home/$SSH_USER/laravel/ || exit 1
- ssh -p $SSH_PORT $SSH_USER@$SSH_HOST "cd laravel && chmod +x ./deploy.sh && ./deploy.sh" || exit 1
Wdrożenia Specyficzne dla Środowisk
deploy_dev:
<<: *deploy_template
environment:
name: development
only:
- develop
deploy_prod:
<<: *deploy_template
environment:
name: production
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: manual
allow_failure: false
Funkcje:
- Automatyczne wdrażanie do środowiska deweloperskiego z gałęzi
develop - Manualne wdrażanie do produkcji z gałęzi
main - Bezpieczne zarządzanie kluczami SSH
- Konfiguracja specyficzna dla środowisk
Zaawansowana Konfiguracja
Testowanie Równoległe
Włącz równoległe wykonywanie testów dla szybszego feedback'u:
variables:
PHPUNIT_JOBS: 4
script:
- ./vendor/bin/pest --log-junit=junit.xml --parallel
Zarządzanie Artefaktami
Optymalizuj przechowywanie i transfer artefaktów:
artifacts:
reports:
junit: junit.xml
paths:
- public/build
when: always
expire_in: 1 week
Kwestie Bezpieczeństwa
- Zarządzanie Kluczami SSH: Przechowuj klucze SSH jako chronione zmienne
- Pliki Środowiskowe: Używaj zmiennych plikowych GitLab dla wrażliwej konfiguracji
- Ochrona Gałęzi: Ogranicz wdrożenia produkcyjne do określonych gałęzi
- Manualne Zatwierdzenia: Wymagaj manualnego zatwierdzenia dla wdrożeń produkcyjnych
Częste Problemy i Rozwiązania
1. Problemy z Pamięcią w Composer
Problem: Composer kończy pamięć podczas instalacji
Rozwiązanie:
variables:
COMPOSER_MEMORY_LIMIT: -1
2. Powolne Budowanie Zasobów
Problem: Budowanie frontend zajmuje zbyt dużo czasu
Rozwiązania:
- Używaj
npm cizamiastnpm install - Implementuj odpowiednie cache'owanie
- Używaj flag
--no-audit --no-fund
3. Problemy z Bazą Danych Testowych
Problem: Testy bazy danych zawodzą lub są powolne
Rozwiązanie:
variables:
DB_CONNECTION: sqlite
DB_DATABASE: ":memory:"
4. Błędy Połączenia SSH
Problem: Wdrożenie zawodzi z powodu problemów SSH
Rozwiązania:
- Sprawdź format klucza SSH (brak końców linii Windows)
- Dodaj host do known_hosts
- Sprawdź ustawienia firewall i portów
5. Unieważnienie Cache
Problem: Buildy używają przestarzałych zależności z cache
Rozwiązanie:
cache:
key:
files:
- composer.lock
- package-lock.json
Najlepsze Praktyki
1. Optymalizacja Pipeline'u
- Używaj równoległych jobów gdzie to możliwe
- Implementuj inteligentne cache'owanie
- Minimalizuj rozmiary artefaktów
- Używaj konkretnych tagów obrazów Docker
2. Strategia Testowania
- Uruchamiaj testy równolegle
- Używaj baz danych w pamięci dla szybkości
- Dołączaj zarówno testy jednostkowe jak i funkcjonalne
- Generuj raporty pokrycia
3. Bezpieczeństwo
- Przechowuj wrażliwe dane w zmiennych GitLab
- Używaj chronionych gałęzi i środowisk
- Implementuj manualne zatwierdzenia dla produkcji
- Regularnie rotuj klucze SSH
4. Monitorowanie i Debugowanie
- Używaj znaczących nazw i opisów jobów
- Dołączaj wskaźniki postępu w skryptach
- Przechowuj artefakty do debugowania
- Ustaw odpowiednie czasy wygaśnięcia artefaktów
5. Zarządzanie Środowiskami
- Używaj zmiennych specyficznych dla środowisk
- Implementuj odpowiednie zarządzanie sekretami
- Utrzymuj oddzielne konfiguracje wdrożeń
- Używaj wdrożeń blue-green lub rolling
Podsumowanie
Ten pipeline GitLab CI/CD zapewnia solidne podstawy dla wdrażania aplikacji Laravel z automatycznym testowaniem, kontrolą jakości kodu i niezawodnymi procesami wdrażania. Konfiguracja kładzie nacisk na wydajność, bezpieczeństwo i łatwość utrzymania, zapewniając jednocześnie elastyczność dla różnych scenariuszy wdrażania.
Kluczowe korzyści tego podejścia:
- Szybki Feedback: Równoległe testowanie i inteligentne cache'owanie
- Zapewnienie Jakości: Kompleksowe testowanie i analiza kodu
- Bezpieczne Wdrażanie: Wdrażanie oparte na SSH z odpowiednim zarządzaniem sekretami
- Zarządzanie Środowiskami: Oddzielne pipeline'y deweloperskie i produkcyjne
- Skalowalność: Łatwe do rozszerzenia i modyfikacji dla różnych wymagań
Pamiętaj o:
- Regularnym aktualizowaniu obrazów Docker i zależności
- Monitorowaniu wydajności pipeline'u i optymalizacji wąskich gardeł
- Przechowywaniu skryptów wdrażania i konfiguracji w kontroli wersji
- Dokładnym testowaniu pipeline'u przed wdrożeniem na produkcję
- Implementacji odpowiedniego monitorowania i alertów dla wdrożeń
Śledź mnie na LinkedIn po więcej porad dotyczących DevOps i wdrażania Laravel!
Chcesz dowiedzieć się więcej o optymalizacji GitLab CI/CD lub strategiach wdrażania Laravel? Daj mi znać w komentarzach poniżej!