Sytuacja kobiet w IT w 2024 roku
24.11.20204 min
Gabriel Umoh

Gabriel UmohWeb DeveloperPhree Media Technology

Continuous Deployment w Laravelu z gitem i webhooks

Sprawdź, jak możesz ustawić Continuous Deployment w Laravelu, wykorzystując do tego git oraz webhooks.

Continuous Deployment w Laravelu z gitem i webhooks

Witajcie! Mam nadzieję, że z kodem wszystko w porządku! W tym artykule pokażę prosty sposób na Continuous Deployment w Laravelu, mając do dyspozycji m.in. git. Zanim jednak przejdziemy dalej, musimy się upewnić, że mamy wszystko, co potrzebne:

  • Projekt w Laravelu
  • Coś do obsługi git (ja użyję GitHuba, ale wszędzie wygląda to podobnie)
  • Dostęp do serwera (możecie też testować lokalnie, ale to nie będzie to samo)
  • Oczy
  • Palce
  • Mózg
  • no i tyle!


Zacznijmy zatem od początku!


Laravel to wspaniały framework — i wcale nie żałuję odejścia od ASP.NET.  Pierwszą rzeczą będzie użycie programu composer do zainstalowania symfony/process w naszym projekcie, ponieważ będziemy potrzebować tego pakietu później. Można to zrobić, odpalając prostą komendę w katalogu głównym projektu. 

$  composer require symfony/process

Załaduje to wszystkie potrzebne pliki do composer.json. Aby dodać pakiet do projektu, uruchom poniższą komendę:

$ composer update


Doda to powyższy pakiet do folderu vendor oraz wygeneruje wymagane klasy i inne potrzebne rzeczy. Jeżeli chcecie dowiedzieć się więcej, zachęcam do zapoznania się z dokumentacją Symfony. 

Będziemy też potrzebować skryptu, który odegra tutaj bardzo ważną rolę. Oto nasz skrypt:

#!/bin/sh

# activate maintenance mode
php artisan down

# update source code
git pull

# update PHP dependencies
composer install --no-interaction --no-dev --prefer-dist

# --no-interaction Do not ask any interactive question
# --no-dev  Disables installation of require-dev packages.
# --prefer-dist  Forces installation from package dist even for dev versions.

# update database
php artisan migrate --force

# --force  Required to run when in production.

# stop maintenance mode

php artisan up


Nazwijmy ten plik deploy.sh. To oczywiście tylko szablon. Skrypt można modyfikować, według potrzeb. 

Teraz trzeba sprawić, aby nasz skrypt dało się uruchomić.

$ sudo chmod +x deploy.sh


W zależności od środowiska produkcyjnego powyższa metoda może się okazać ryzykowna, a więc jeśli kochasz bezpieczeństwo, to nie zwracaj na nią uwagi i przejdź dalej. Jeśli jednak korzystasz z Linuksa i wiesz, co się z tym wiąże, to możesz ją śmiało uruchomić. Nasz skrypt jest zatem gotowy. Musimy teraz przygotować git webhook. 

Na stronie repozytorium GitHuba otwórz zakładkę Settings, a następnie Webhooks po lewej. Możesz też uruchomić poniższy adres:

https://github.com/<your account>/<your repository>/settings/hooks


Kliknij Add Webhook:

  • Payload URL: http://example.com/deploy
  • Sekret: dodaj losowy i długi ciąg znaków (im dłuższy, tym lepszy)


Dodamy ten webhook do naszego projektu. Następnie dodajmy do projektu nasz sekret. Musimy dać projektowi znać, że on istnieje. Dodaj tę linijkę do config/app.php:

'deploy_secret' => env('APP_DEPLOY_SECRET'),


Sekret dodaj w pliku .env

APP_DEPLOY_SECRET=changemenoworfacetheconsequences


To by było na tyle, jeżeli chodzi o ręczne ustawianie projektu. Teraz przejdźmy do kodu. Musimy stworzyć kontroler, który będzie przechowywał naszą logikę. Pozwoli on uruchomić się naszemu deploymentowi. A teraz stwórzmy kontroler: 

$ php artisan make:controller DeployController


Ja go nazwę DeployController, aby uniknąć nieporozumień.  Potem dodamy cały kod. Nasz kontroler powinien finalnie wyglądać tak:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Symfony\Component\Process\Process;

class DeployController extends Controller
{
  public function deploy(Request $request)
  {
     $githubPayload = $request->getContent();
     $githubHash = $request->header('X-Hub-Signature');

     $localToken = config('app.deploy_secret');
     $localHash = 'sha1=' . hash_hmac('sha1', $githubPayload, $localToken, false);

     if (hash_equals($githubHash, $localHash)) {
          $root_path = base_path();
          $process = new Process('cd ' . $root_path . '; ./deploy.sh');
          $process->run(function ($type, $buffer) {
              echo $buffer;
          });
     }
  }
}


Oto, co robi kod:

  • Sprawia, że żądanie z GitHuba wykorzystuje X-Hub-Signature. Można to usunąć, ale polecam tego nie robić.
  • Zawsze można się zwrócić do dokumentacji wersji gita, której używasz, aby wykorzystać ich własne X-Signature. 
  • Kod potwierdza, że żądanie pochodzi z Twojego repozytorium na GitHubie, poprzez sprawdzenie zgodności sekretu (w środowisku produkcyjnym istnieją inne sposoby weryfikacji przed i po więc nie przejmuj się kruchymi zabezpieczeniami)
  • Kod wykorzystuje proces Symfony, aby odpalać skrypt deploymentowy w ścieżce głównej projektu.


Przejdźmy teraz do dodania ścieżki do obsługi webhooków, które dodaliśmy do GitHuba. Przejdź do route/web.php w swoim projekcie i dodaj poniższą linijkę:

Route::post('deploy', 'DeployController@deploy');


Metoda HTTP dla ścieżki zawsze musi być metodą post, ponieważ github wysyła tylko takie żądania jako webhooki. Może to być następna metoda weryfikacji. Po drugie, aby zapobiec błędom walidacji tokenu CSRF, dodajemy powyższą ścieżkę do naszej ścieżki wyjątku w Middleware/VerifyCsrfToken.php. Powinno to wyglądać tak:

<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;

class VerifyCsrfToken extends Middleware
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        '/deploy',
    ];
}


Następnie zmień na serwerze grupę unix w folderze projektu na www-data. Jest to konieczne, aby skrypt działał, jak trzeba. Zezwól też użytkownikowi www-data na aktualizację folderu projektu. Powyższe rzeczy można zrobić w następujący sposób:

$ sudo chgrp -R www-data .


I w taki oto sposób dotarliśmy do końca. Ustawiliśmy właśnie prosty auto deployment (albo Continuous Deployment) w projekcie przy użyciu git (a Jenkins oraz Travis mogą odpocząć).

Dziękuję za uwagę!

Oryginał tekstu w języku angielskim możesz przeczytać tutaj.


Masz jakieś przemyślenia po lekturze? Podziel się nimi w komentarzu
?

<p>Loading...</p>