Blog

🚀 Budowanie Produkcyjnego Pipeline'u GitLab CI/CD dla Laravel: Od Testowania do Wdrożenia

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

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:

  1. Etap Testowania: Uruchamia testy PHP i JavaScript równolegle
  2. Etap Budowania: Tworzy zoptymalizowane artefakty produkcyjne
  3. 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 Composer
  • FF_USE_FASTZIP: Włącza szybszą kompresję artefaktów
  • PHPUNIT_JOBS: Włącza równoległe wykonywanie testów
  • COMPOSER_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

  1. Zarządzanie Kluczami SSH: Przechowuj klucze SSH jako chronione zmienne
  2. Pliki Środowiskowe: Używaj zmiennych plikowych GitLab dla wrażliwej konfiguracji
  3. Ochrona Gałęzi: Ogranicz wdrożenia produkcyjne do określonych gałęzi
  4. 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 ci zamiast npm 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!

Wsparcie istniejącego systemu

Potrzebujesz pomocy z działającą aplikacją?

Pomagam firmom rozwijać działające systemy, porządkować wdrożenia i dodawać nowe funkcje bez dokładania chaosu do projektu.

Komentarze (0)
Zaloguj się, aby dodać komentarz

Musisz być zalogowany, aby dodać komentarz.

Zaloguj się

Potrzebujesz kogoś, kto weźmie odpowiedzialność za kolejny krok?

Porozmawiajmy o Twoim projekcie i określmy zakres, który ma sens dla Twoich celów.