Laravel, Gitlab CI/CD, Laravel Envoy, AWS EC2, Deploy

Akın Akalın
4 min readJul 15, 2020

--

Yazının başlığı “Bir Laravel uygulamasını; Gitlab CI/CD ve Laravel Envoy kullanarak AWS EC2'ye hiç kesinti yaşamadan deploy etmek” olmalıydı ancak çok uzun olduğu için anahtar kelimeleri kullanmaya karar verdim.

Yapacağımız işlerden özetle bahsetmek gerekirse; bir Laravel uygulamasını önce test edeceğiz (Unit Test, PHP Mess Detector, CodeSniffer gibi) sonra AWS EC2'ya deploy edeceğiz. Testleri hem develop hem de master branch’i için yaparken, deploy işlemini sadece master branch’i için koşacağız.

Ben bu yazı için; Ubuntu 18.04 kurulu bir t2.micro instance, Nginx, PHP 7.4.7 ve Laravel 7 kullandım.

Kullandığım Laravel uygulaması: https://github.com/akinakalin/laravel-deploy-tests

Nginx Ayarları

Buradaki en önemli konu “root” dizininin belirlenmesi olacaktır. Nginx; belirleyeceğimiz bir dizine bakmalı ve biz deploy işlemini farklı bir dizine yapmalıyız. Her şey yolunda gittiğinde belirlediğimiz o dizine symbolic link vermeliyiz. Yaklaşık olarak dizin yapımız şöyle olmalı;

— /var/www/app
— — current -> /var/www/app/releases/release2
— — releases
— — — release0
— — — release1
— — — release2
— — storage

Örneğe göre, Nginx “/var/www/app/current” dizinine bakıyor ve current dizini ile “/var/www/app/releases/release2” dizini arasında symbolic link oluşturuluyor. Bir sonraki release, release3 olduğunda artık current ile /var/www/app/releases/release3 arasında bir symbolic link oluşturmamız gerekiyor. Şimdi Nginx ayalarını kurgumuza göre düzenlemek için;

 sudo nano /etc/nginx/sites-available/default

İncelediğinizde -varsayılan gelen ayarlara dokunmadığınızı/farklı bir conf kullanmadığınızı varsayıyorum- root değeri için “/var/www/html” belirlendiğini görebilirsiniz. Uygulamamız için biz root dizinini “/var/www/app/current” olarak belirleyeceğiz.

root /var/www/app/current/public;

Basitçe bir Nginx dosyası aşağıdaki gibi görünmeli;

Nginx Örneği

Bu düzenlemeden sonra restart gerektiğini unutmamalısınız.

sudo systemctl restart nginx

Kullanıcı Ayarları

Deploy işlerini gerçekleştirmek için “deployer“ adında bir kullanıcı oluşturmalı ve yetkilendirmeliyiz. Bu adımdan sonraki tüm işler artık “deployer” kullanıcısı üzerinden gerçekleşeceği için, bir komutu çalıştırmadan hangi kullanıcıda olduğunuzu kontrol etmenizde fayda var.

# Kullanıcı oluşturuluyor.
sudo adduser deployer
# var/www dizini için yetki veriliyor.
sudo setfacl -R -m u:deployer:rwx /var/www
# Kullanıcı değiştiriliyor.
su deployer

Dizin Ayarları

Nginx ayarlarında bahsettiğimiz dizinleri oluşturmak için (deployer kullanıcısında olduğunuzdan emin olun);

cd /var/www/# app, storage ve releases dizinlerini oluşturuyoruz.
mkdir app
mkdir app/storage
mkdir app/storage/framework
mkdir app/storage/framework/sessions
mkdir app/storage/framework/views
mkdir app/storage/framework/cache
mkdir app/storage/framework/cache/data
mkdir app/releases
# storage dizini için izinler
chmod -R ug+rwx app/storage
# .env dosyasını da "app" dizini altında tutabilirsiniz
touch app/.env

Storage; tüm release versiyonlarında ortak olacağı için app dizinin içinde oluşturup, uygulamamızda yer alan storage dizini ile aralarında symbolic link oluşturacağız. Yine aynı sebeplerden .env dosyanızı da dışarı alabilirsiniz ki bu örnekte öyle yapacağız.

Gitlab

Test işlemi için “laravel-deploy-tests” adında bir repository oluşturdum (Github) ve Laravel 7 için PHPMD, Code CodeSniffer ve Unit Test hazırlıklarını yaptım. Buradaki testlerin deploy ile hiç bir bağı yok ancak olması gerektiği yönünde düşünüyorum.

Dockerfile

Gitlab üzerinden deploy etmek ve testlerimizi çalıştırmak için; projenin ana dizinine bir Dockerfile oluşturuyoruz. Oldukça basit bir Dockerfile kullanmaya gayret gösterdim. İhtiyaçlarınız doğrultusunda düzenlemeniz gerekebilir.

Dockerfile

Oluşturduğumuz Dockerfile’ı build edip Gitlab’e göndermek için; Packages & Registries > Container Registry sayfasında üç yönerge ile karşılacaksınız. Yaklaşık olarak aşağıda verilen örnek gibi olacaktır. Buradaki işlemleri yapabilmeniz için kullanmış olduğunuz bilgisayarınızda Docker’ın çalışıyor olması gerekmektedir.

# Login olmanızı sağlar. (Gitlab bilgileriniz ile)
docker login registry.gitlab.com
# Oluşturduğumuz Dockerfile için build işlemi yapar.
docker build -t registry.gitlab.com/akinakalin/laravel-deploy-tests .
# Gitlab'e push etmenizi sağlar.
docker push registry.gitlab.com/akinakalin/laravel-deploy-tests

GitLab CI/CD Ayarları

CI/CD ayarları için yine projenin ana dizine .gitlab-ci.yml dosyası oluşturuyoruz. Burada dikkat edilmesi gereken; image adresidir. Bu adres Gitlab Container Registry’a push ettiğimiz image adresidir. Ulaşmak için Packages & Registries > Container Registry sayfasını kontrol edebilirsiniz.

Envoy Ayarları

Uygulamamızın ana dizinine “Envoy.blade.php” adında bir blade dosyası oluşturuyoruz. Aşağıda örneği verilen Envoy için;

servers: deployer kullanıcımızı belirtiyoruz.

setup: Görevleri başlatmadan önce PHP kodları yürütmemiz gerekebilir (değişken tanımlamak ya da daha genel işler olabilir) bu işleri setup içinde yapabiliriz.

story: Bir dizi görevi gruplamak için kullanılır. Bizim örneğimize göre “clone” ile başlayıp “clean_old_releases” ile bitecektir. Burada belirtilen görevler sırayla yapılacaktır.

Görevler

clone: Belirttiğimiz repository’i setup içerisinde ürettiğimiz “$new_release_dir” dizinine indirecektir.

run_composer: Bağımlılıkları yükleyecektir.

update_symlinks: Laravel içerisinde gelen storage dizini ve .env dosyası için app dizini içerisinde oluşturduğumuz storage ve .env ile aralarında symbolic link oluşturacaktır. Ve en önemli adım olan current dizinimiz ile son release dizini arasında symbolic link oluşturulacaktır.

clean_old_releases: Son 3 release hariç eski release’leri silecektir.

artisan_commands: Deploy sonrası çalıştırmanız gereken artisan komutlarını çalıştıracaktır.

Envoy.blade.php Örneği

SSH ve Gitlab Ayarları

Bu adımları deployer kullanıcısı için yapacağız. Doğru kullanıcıda olduğunuzdan emin olmalısınız.

# deployer kullanıcısı
su deployer
# SSH Key oluşturuluyor.
ssh-keygen
# Oluşturduğumuz public key'i yetkili keylere ekliyoruz.
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
# Private Key'i alıyoruz.
cat ~/.ssh/id_rsa

Settings > CI/CD > Variables sayfasında; Key “SSH_PRIVATE_KEY” ve Value bir önceki adımda kopyaladığımız private key olacak şekilde ekliyoruz.

# Public Key'i alıyoruz.
cat ~/.ssh/id_rsa.pub

Project > Settings > Repository > Deploy Key sayfasında; Title “deployer” ve Key kopyaladığımız public key olacak şekilde ekliyoruz.

Deployer kullanıcısının repository’e ulaşıp ulaşmadığını test etmek için;

cd /var/www/app# Clone
git clone git@gitlab.com:xxxx/laravel-deploy-tests.git test
# Her şey yolundaysa silebiliriz
# rm -rf test

Ve sanırım her şey tamam. İlk commit’i atıp test edebiliriz.

Pipelines
Develop branch’i için sadece tests çalışmakta
Master merge işleminden sonra hem tests hem deploy çalışmakta
Ve sonuç..

Umarım faydalı olmuştur..

--

--