ლარაველის პროექტის სერვერზე გამართვა

შესავალი

და დგება ის მომენტი, როდესაც შენს აპლიკაციას სული უნდა შთაჰბერო, სერვერზე გამართო, დომენი მიაბა და https://my-app.ge -ზე შესვლა შენსგარდა სხვასაც შეეძლოს.

ჩვენ ვიცით ლოკალურად როგორ უნდა გავუშვათ დეველოპმენტ სერვერი: php artisan serve და ეგ არი.

მაგრამ… პროდაქშენის სერვერზეც ვიზამთ მსგავსად?

ჰმმ.. კი შეგვიძლია. მაგრმ არ უნდა ვქნათ. ამაზე ოდნავ მერე.

პროდაქშენში უნდა გამოვიყენოთ სხვადასხვა ხელსასწყო იმისათვის, რომ სერვერზე ჩვენი აპლიკაცია საათვით მუშაობდეს. ამ ხელსაწყოებს წარმოადგენს nginx და php-fpm.

ეს ორი ხელსაწყო უზრუნველყოფს იმას, რომ ჩვენმა აპლიკაციამ ოპტიმალურად გამოიყენოს სერვერის რესურსი, გვაძლევს საშუალებას არაერთი აპლიკაცია გავმართოთ სერვერზე, გვქონდეს ქეშირება და ა.შ.

სერვერზე ხელსაწყოებისა და პროგრამების დაყენება

პირველ რიგში, როდესაც დავლოგინდებით სერვერზე საჭიროა, რომ გავუშვათ ბრძანება: sudo apt update

ეს ბრძანება ფექიჯების შესახებ ინფორმაციას დაააფდეითებს სერვერზე იმისათვის, რომ შემდგომში sudo apt install something -ს რომ გავუშვებთ, იცოდეს ეს something საიდან გადმოწეროს.

შემდგომ გვჭირდება, რომ php-ის custom რეპოზიტორია დავამატოთ უბუნტუს package manager-ში, იმისათვის, რომ უახლესი php დავაინსტალიროთ.

გავუშვათ ბრძანება: sudo add-apt-repository ppa:ondrej/php

შემდეგ კი დავაინსტალიროთ php-ის 8 ვერსია რამოდენიმე ექსთენშენთან ერთად: sudo apt install php8.1 php8.1-curl php8.1-mbstring php8.1-xml php8.1-sqlite3

apt რეპოზიტორიის დამატების შემდგომ სტანდარტულად აპაჩეს ვებსერვერიც ყენდება, ჩვენ აპაჩე არ გვჭირდება და წავშალოთ სისტემიდან შემდეგი ბრძანებით: sudo apt purge apache2

გარდა ამისა, რამოდენიმე დამატებითი ფექიჯიც, იმისათვის, რომ ამ ყველაფერმა გამართულად იმუშაოს: sudo apt install zip sqlite3

ამათ გარდა გვჭირდება კომპოუზერი და ნოუდიც. კომპოუზერის დაინსტალირებისთვის გავუშვათ შემდეგი ბრძანებები: curl https://getcomposer.org/installer | php sudo mv composer.phar /usr/bin/composer

ნოუდისათვის კი: curl https://deb.nodesource.com/setup_14.x | sudo bash sudo apt install nodejs

სერვერზე Laravel-ის პროექტის ჩამოტვირთვა

ჩვენს home ფოლდერში შევქმნათ apps ფოლდერი სადაც გვექნება აპლიკაციები, რომელსაც ჩვენს სერვერზე გავმართავთ. შემდეგ შევიდეთ apps ფოლდერში და დავკლონოთ გიტჰაბიდან რეპოზიტორია:

cd ~ mkdir apps cd apps git clone https://github.com/my-app.git

თუ ვნახავთ apps ფოლდერის შიგთავსს, დავინახავთ, რომ გვაქვს ჩამოტვირთული ჩვენი პროექტი. შევიდეთ ჩვენს პროექტში და დავიწყოთ მისი გამართვა.

თუ ძველი პროექტია და ვიყენებთ webpack-ს vite-ის ნაცვლად, მომდევნო ბრძანებებში npm run build -ის ნაცვლად უნდა გავუშვად npm run prod

cd my-app composer install npm install npm run build cp .env.example .env php artisan key:generate php artisan storage:link touch database/database.sqlite

ამ ქომანდების შემდეგ გვჭირდება, რომ .env ფაილი შევცვალოთ და sqlite დავაყენოთ ჩვენს ბაზად(სტანდარტულად mysql არის მონაცემთა ბაზის დრაივერი).

როდესაც .env -ს შევცვლით გავუშვათ შემდეგი ბრძანებები:

php artisan optimize php artisan migrate

და ასევე ნებისმიერი ბრძანება, რაც ჩვენს პროექტს სჭირდება.

php artisan serve და რატომ — არა?

ჩვენ შეგვიძლია შევიდეთ ახლა ჩვენს პროექტში და გავუშვათ შედეგი ბრძანება:

cd ~/apps/my-app sudo php artisan serve --host=0.0.0.0 --port=80

ამის შემდგომ თუ შევალთ ჩვენი სერვერის IP-ზე დავინახავთ ჩვენს პროექტს. შესაბამისად php artisan serve -ის გამოყენება პროდაქშენში სავსებით შესაძლებელია.

და, რატომ არ უნდა გამოვიყენოთ? მავანმა, ამ კითხვაზე შეიძლება პასუხების ვრცელი ნუსხა გაჩვენოთ, მაგრამ ჩვენ დავკონცენტრირდეთ მთავარ მომენტებზე რაც ჩვენს რეალობაშსთანაა შესაბამისობაში:

  • პირველი და მთავარი მიზეზი: PHP სტანდარტულად არ არის მრავალნაკადიანი(სრედიანი) ენა, რაც იმას ნიშნავს, რომ როდესაც php artisan serve -ს ვუშვებთ ჩვენი პროექტი გაშვებულია მხოლოდ და მხოლოდ პროცესორის ერთ ნაკადზე. წარმოიდგინეთ — გაქვთ არანორმალურად მძლავრი სერვერი, მაგალითისთვის ვთქვათ — 32 ნაკადიანი პროცესორით. ჩვენ თუ ამ სერვერზე php artisan serve -ით გვექნება ჩვენი ლარაველის პროექტი გაშვებული გამოდის, რომ 32 ნაკადიდან მხოლოდ ერთს ვიყენებ. ეს იმასაც ნიშნავს, რომ სერვერი მომენტში მხოლოდ ერთ რექვესთს დაამუშავებს. და თუ ერთდროულად1-ის ნაცვლად 100 რექვესთი მიიღო — შესაბამისად დანარჩენი 99 რექვესთი რიგში უნდა ჩადგეს, რაც იმას ნიშნავს, რომ იქმნება bottleneck და მომხმარებელს უწევს ლოდინი სანამ საიტი ჩაეტვირთება.

  • ვერ დავაყენებთ SSL-ს რაიმე დამატებითი ხელსაწყოს გარეშე, როგორიცაა Nginx, Apache ან სერვისი მაგალითად — cloudflare.

  • ვერ გავუშვებთ სერვერზე ერთზე მეტ ვებგვერდს(ერთი და იმავე პორტზე).

  • ვერ გვექნება სწრაფი სტატიკური ფაილების serving-ი

  • ასევე სტატიკური ფაილების ქეშირება: Cache Control Policy

ეს მიზეზები საკმაოდ საკმარისია, იმისათვის, რომ ცოტა nginx-სა და php-fpm-სკენ გავიხედოთ.

Nginx, PHP-FPM და Laravel

რა ურთიერთ დამოკიდებულებაში არიან Nginx, PHP-FPM და Laravel- ი?

განვიხილოთ 2 ვარიანტი.

ვთქვათ, ვაგზავნით რექვესთს https://my-app.ge/cars/list -ზე. სადაც blade-ით უნდა დაგენერირდეს მანქანების html სია და უნდა შეიცავდეს მანქანების შესახებ ინფორმაციას, რომელიც უნდა იქნას წამოღებული მონაცემთა ბაზიდან. როდესაც ბრაუზერიდან გავაგზავნით რექვესთს, პირველი რაც შეხვდება რექვესთს არის Nginx. ვებსერვერი, ამ შემთხვევაში nginx ნახავს url-ს, სერვერზე თუ არსებობს მსგავსი ფაილი შეამოწმებს — ამ შემთხვევაში: /home/user/apps/my-project/public/cars/list რაიმე ასეთი ფაილი თუ არსებობს. თუ ნახა, რომ არ არსებს Nginx ამ რექვესთს გადაამისამართებს PHP FPM-თან. შესაბამისად მეორე რაც რექვეთს შეხვდება არის PHP FPM. არსებობს ერთი მთავარი PHP FPM პროცესი, რომელსაც ქვია Master Process და ამ მთავარი პროცესის გარდა არიან შვილი პროცესები — child processes. მთავარი პროცესი ამენეჯებს შვილ პროცესებს და როდესაც რექვესთი შემოდის ერთ-ერთთან გადაამისამართებს.

შემდეგ შვილი FPM პროცესი დაამუშავებს ამ რექვესთს: გააკეთებს მონაცემთა ბაზასთან კომუნიკაციას, ბლეიდით ააწყობს html-ს და ა.შ. და ბოლოს დააბრუნებს Response-ს უკან. Master პროცესი პასუხს Nginx-ს დაუბრუნებს, ხოლო Nginx ბრაუზერს. აქედან ვხედავთ, რომ რა პრობლემაც php artisan serve -ს ჰქონდა, ეგ პრობლემა PHP FPM-ის შვილი პროცესებით არის მოგვარებული. გვაქვს დასტარტული ბევრი შევილი პროცესი და როგორც კი შემოვა რექვესთი, რომელი შვილი პროცესიც თავისუფალია მასთან ვამისამართებთ და ვამუშავებინებთ რექვესთს.

ახლა განვიხილოთ მეორე ვარიანტი. ვთქვათ, ვაგზავნით რექვესთს https://my-app.ge/css/app.css — ზე. ამ შემთხვევაში Nginx შეამოწმებს რაიმე ფაილი თუ არსებობს შემდეგ მისამართზე: /home/user/my-project/public/css/app.css და თუ ნახავს, რომ ასეთი ფაილი არსებობს უკვე პირდაპირ ბრაუზერს თითონ გაუგზავნის ამ ფაილს და php-ს და ლარაველს საერთოდ აღარც შეეხება.

PHP FPM-ის კონფიგურაცია

პირველრიგში უნდა დავაინსტალიროთ PHP FPM: sudo apt install php8.1-fpm

სერვერზე შევიდეთ შემდეგ ფოლდერში: cd /etc/php/8.1/fpm/pool.d

წავშალოთ სტანდარტული კონფიგურაცია: rm www.conf

შევქმნათ ახალი ფაილი: touch my-app.conf

და შიგნით ჩავწეროთ შემდეგი კონფიგურაცია:

; Your application name
[my-app]

; Set these two variables to your user name
user = YOUR_USER_NAME
group = YOUR_USER_NAME

; With this configuration line, php-fpm will
; Create unix socket for our application and
; We will redirect request to this socket from Nginx
; ! change 'my-app' to you project specific name
listen = /run/php/php8.1-my-app-fpm.sock

; Keep this two lines as it is.
listen.owner = www-data
listen.group = www-data

; Dynamicly increase and decrease number of child processes
pm = dynamic

; Max number of child processes that can be alive at 
; any given moment
pm.max_children = 5

; Number of child process that will be started at FPM startup
pm.start_servers = 2

; Min child processes that can be without any job
pm.min_spare_servers = 1

; Max child procesess that can be without any job
pm.max_spare_servers = 3

შეინახეთ ფაილი და გადატვირთეთ fpm-ის პროცესი: sudo systemctl restart php8.1-fpm.service

გადატვირთვისას შეიქმნებოდა unix-ის სოკეტი: /run/php/php8.1-my-app-fpm.sock

NGINX-ის კონფიგურაცია

პირველ რიგში დავინსტალიროთ nginx: sudo apt install nginx

სერვერზე შევიდეთ შემდეგ ფოლდერში: cd /etc/nginx/sites-enabled

წავშალოთ არსებული default კონფიგურაციის ფაილი: sudo rm default

შევქმნათ ახალი კონფიგურაციის ფაილი: touch my-app.ge

და შიგნით ჩავწეროთ შემდეგი კონფიგურაცია:

 server {
 
 listen 80;
 
 # change this line according to your app's public path
 root /home/user/apps/my-app/public;
 
 # change this [!] DOMAIN [!] according to your domain
 server_name my-app.ge;
 
 index index.php;
 
 location / {
    try_files $uri $uri/ /index.php?$query_string;
 }
 
 location ~ \.php$ {
     include snippets/fastcgi-php.conf;
     
     # change socket address according to your created socket path
     fastcgi_pass unix:/run/php/php8.1-my-app-fpm.sock;
 }
}

ასევე საჭიროა, რომ nginx-ის მომხმარებელს მივცეთ წვდომა ჩვენი მომხმარებლის ფოლდერებსა და ფაილებზე იმისათვის, რომ ჩვენი აპლიკაციის დამუშავებისათვის ჰქონდეს შესაბამისი უფლებები. ამისათვის გაუშვით ქვემოთ შემდეგი ორი ბრძანება:

sudo usermod -aG [your-username] www-data 
sudo systemctl restart nginx

SSL-ის დაყენება LetsEncrypt-ით

იმისათვის, რომ LetsEncrypt-ის სერტიფიკატი დავაყენოთ ჩვენს საიტზე, საჭიროა, რომ რამოდენიმე ფექიჯი დავაინსტალიროთ: sudo apt install certbot python3-certbot-nginx

შემდგომ გავუშვათ ბრძანება: sudo certbot

და მივყვეთ certbot-ის ინსტრუქციებს.

დასკვნა

ლარაველის პროექტის Production სერვერზე გასამართად ჩასატარებელია რიგი პროცედურები:

  • სერვერზე საჭირო ფექიჯების დაყენება

  • პროექტის ჩამოტვირთვა და შესაბამისი dependencies-ების დაინსტალირება

  • PHP FPM-ის კონფიგურაცია

  • Nginx-ის კონფიგურაცია

  • LetsEncrypt-ით SSL-ის დაყენება

აბა თქვენ იცით, ღმერთი თქვენსკენ 🙏

Last updated