Wdrożenie aplikacji na Laravel 7 na Ubuntu & Nginx

Wdrożenie aplikacji na Laravel 7 na Ubuntu & Nginx

Postanowiłem stworzyć swoje portfolio na Laravel 7. Chciałem, aby strona główna była landingiem, a wszystkie informacje na niej mogły być zmieniane za pomocą panelu administracyjnego. Nie o tym jednak mowa. Doszedłem do etapu wdrożenia. Znalazłem kilka dobrych tutoriali, jak to zrobić na pełnoprawnym serwerze ze wszystkimi zawirowaniami. Nie jestem mocny w wdrożeniach, w ogóle bardziej zajmuję się frontendem niż fullstackiem. Jeśli chodzi o pisanie i testowanie w PHP, to jeszcze sobie radzę, ale nie dorosłem do zarządzania serwerem itd. Musiałem jednak się tym zająć.

Teraz przejdziemy przez wszystkie kroki, zaczynając od uruchomienia przez SSH, a kończąc na działającej stronie. Postaramy się ominąć wszelkie pułapki.

Możliwe, że znajdziesz podobne instrukcje w internecie. W końcu ja też je znalazłem. Prawda, że nie w jednym miejscu, nie bez pomocy StackOverflow i raczej nie w języku polskim. Trochę się namęczyłem. Dlatego postanowiłem ułatwić wam życie.

Będziemy wszystko robić na droplecie z DigitalOcean. Oczywiście nie jest to obowiązkowe, możecie wybrać dowolny hosting. Jeśli dotrzecie do działającego serwera na Ubuntu, wróćcie. Dla tych, którzy zdecydowali się na DigitalOcean, będą też porady dotyczące konfiguracji domeny. A także link partnerski na 100$.

Wszystkie specyficzne dla DigitalOcean kroki będą podane w podobnych przypisach.

Zaczynamy.

TL;DR (tylko podstawowe komendy)

Tworzymy użytkownika

  • ssh root@[adres IP waszego dropletu]
  • adduser laravel
  • usermod -aG sudo laravel
  • su laravel

Dodajemy mu SSH

  • mkdir ~/.ssh
  • chmod 700 ~/.ssh
  • vim ~/.ssh/authorized_keys
  • Wklejamy klucz publiczny
  • chmod 600 ~/.ssh/authorized_keys

Zapora

  • sudo ufw allow OpenSSH
  • sudo ufw enable
  • sudo ufw status

Nginx

  • sudo apt update
  • sudo apt install -y nginx
  • sudo ufw allow 'Nginx HTTP'
  • sudo ufw status

MySQL

  • sudo apt install -y mysql-server
  • sudo mysql_secure_installation, NYNNY
  • sudo mysql
  • ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '';
  • SELECT user,authentication_string,plugin,host FROM mysql.user;
  • FLUSH PRIVILEGES;
  • exit

PHP

  • sudo apt update

  • sudo apt install -y curl wget gnupg2 ca-certificates lsb-release apt-transport-https

  • sudo apt-add-repository ppa:ondrej/php

  • sudo apt update

  • 7.3: sudo apt install -y php7.3-fpm php7.3-mysql

  • 7.4: sudo apt install -y php7.4-fpm php7.4-mysql

  • sudo vim /etc/nginx/sites-available/

Podstawowa konfiguracja:

server {
        listen 80;
        root /var/www/html;
        index index.php index.html index.htm index.nginx-debian.html;
        server_name ;

        location / {
                try_files $uri $uri/ =404;
        }

        location ~ .php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
        }

        location ~ /.ht {
                deny all;
        }
}

Tylko konfiguracja HTTP pod Laravel:

serwer {
    nasłuchuj 80;
    nasłuchuj [::]:80;

    root /var/www/html//public;
    index index.php index.html index.htm index.nginx-debian.html;

    server_name ;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ .php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    }

    location ~ /.ht {
        deny all;
    }
}

Konfiguracja HTTPS dla Laravel:

serwer {
    nasłuchuj 80;
    nasłuchuj [::]:80;

    server_name  www.; 
    return 301 https://$server_name$request_uri;
}

serwer {
    nasłuchuj 443 ssl http2;
    nasłuchuj [::]:443 ssl http2;
    server_name  www.;
    root /var/www/html//public;

    ssl_certificate /etc/letsencrypt/live//fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live//privkey.pem;

    ssl_protocols TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
    ssl_prefer_server_ciphers on;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    index index.php index.html index.htm index.nginx-debian.html;

    charset utf-8;

    location / {
            try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ .php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    }

    location ~ /.ht {
            deny all;
    }

    location ~ /.well-known {
            allow all;
    }
}

  • sudo ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/
  • sudo unlink /etc/nginx/sites-enabled/default
  • sudo nginx -t
  • sudo systemctl reload nginx

Laravel

  • 7.3: sudo apt install -y php7.3-mbstring php7.3-xml composer unzip

  • 7.4: sudo apt install -y php7.4-mbstring php7.4-xml composer unzip

  • mysql -u root -p

  • STWÓRZ BAZĘ DANYCH laravel DOMYŚLNE ZBIORY ZNAKÓW utf8 KOLIZJA utf8_unicode_ci;

  • PRZYZNANIE WSZYSTKIM DOSTĘPU DO laravel.* DO 'root'@'localhost' ZIDENTYFIKOWANE HASŁEM '' ;

  • FLUSH PRIVILEGES;

  • exit

  • cd /var/www/html

  • sudo mkdir -p

  • sudo chown laravel:laravel

  • cd ./

  • git clone . / git clone -b --single-branch .

  • composer install

  • vim .env

APP_NAME=Laravel
APP_ENV=produkcja
APP_KEY=
APP_DEBUG=false
APP_URL=http://

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=

  • php artisan migrate

  • php artisan key:generate

  • sudo chown -R $USER:www-data storage

  • sudo chown -R $USER:www-data bootstrap/cache

  • chmod -R 775 storage

  • chmod -R 775 bootstrap/cache

HTTPS

  • sudo add-apt-repository ppa:certbot/certbot

  • sudo apt install -y python-certbot-nginx

  • sudo certbot certonly --webroot --webroot-path=/var/www/html//public -d -d www.

  • sudo nginx -t

  • sudo ufw allow 'Nginx HTTPS'

  • sudo ufw status

  • sudo systemctl reload nginx

Tworzymy droplet na DigitalOcean i rejestrujemy nowy klucz SSH

Szczerze wierzę, że sam poradzisz sobie z rejestracją na DigitalOcean. Nie jest to proste, z mnóstwem weryfikacji i innymi zawirowaniami. Jeśli podczas weryfikacji za pomocą dokumentów ciągle występuje błąd sieci, spróbuj wszystkiego zrobić przez VPN, powinno pomóc.

W górnym menu klikamy Utwórz->Droplety. Wybieramy Ubuntu.

Po zarejestrowaniu się otrzymasz 100$ na konto. Ale nie łudź się. Masz tylko 60 dni na ich wydanie. A to bardzo mało. Możesz, tak jak ja, zechcieć wykorzystać droższy plan, a potem, gdy pojawią się prawdziwe pieniądze, przejść na tańszy. Od razu mówię, nie da się. Można tylko zwiększać, a nie zmniejszać. Takie są zasady. Wybieram Standard->$5.

Wybieram region najbliższy nam Frankfurt. Sieć VPC->default-fra1

Autoryzację zrealizujemy przez SSH. Klikamy Nowy klucz SSH. Jeśli nie masz SSH, po prawej znajduje się bardzo prosta instrukcja. Otwórz terminal bash, wklej ssh-keygen. Następnie wchodzimy do pliku z kluczem publicznym /Users/<Ваше имя пользователя>/.ssh/id_rsa.pub (lub po prostu cat ~/ .ssh/ id_rsa.pub), kopiujemy zawartość i wklejamy w oknie po lewej. Nazwa jest dowolna.

Wymyślamy nazwę hosta dla dropleta.

Klikamy Utwórz Droplet

Tworzymy nowego użytkownika

  • ssh root@[adres IP waszego dropletu]
  • Czy na pewno chcesz kontynuować łączenie (tak/nie/[odcisk])? yes
  • Wprowadź swoje hasło do SSH
  • Tworzymy użytkownika laravel: adduser laravel
  • Wprowadź hasło i inne informacje (wprowadzam tylko Pełne Imię)
  • Dodajemy użytkownika do grupy sudo: usermod -aG sudo laravel

SSH dla nowego użytkownika

  • Przełączamy się na nowego użytkownika: su laravel

Wszystkie dalsze działania, aż do końca artykułu, wykonujemy jako użytkownik laravel. Dlatego, jeśli nagle przerwałeś, zaloguj się ponownie i wprowadź su laravel

  • mkdir ~/.ssh
  • chmod 700 ~/.ssh
  • vim ~/.ssh/authorized_keys

Otworzyliśmy plik w Vimie. Jeśli nie znasz się na nim w ogóle, możesz pracować w Nano, twoje prawo.

Najbardziej podstawowe komendy Vim

Żeby podczas czytania artykułu korzystać z edytora Vim, wystarczy znać następujące.

  • W Vimie są różne tryby: zwykły (tryb Normal), w którym wprowadzasz komendy i wybierasz inne tryby.
  • Aby wyjść z dowolnego trybu i przejść do trybu normalnego, wystarczy nacisnąć Esc
  • Poruszanie się: można po prostu używać strzałek
  • Wyjdź bez zapisywania <Normal mode>: :q!
  • Wyjdź i zapisz <Normal mode>: :wq
  • Przejdź do trybu wprowadzania tekstu <Normal mode>: i (z ang. insert)
  • Wklejamy nasz klucz publiczny (który robiliśmy wcześniej)
  • Zabezpieczamy przed zmianami: chmod 600 ~/.ssh/authorized_keys

Ustawiamy zaporę ogniową

  • Patrzymy na wszystkie dostępne ustawienia: sudo ufw app list
  • Zezwalamy na OpenSSH (w przeciwnym razie nas zablokuje): sudo ufw allow OpenSSH
  • Uruchamiamy zaporę ogniową: sudo ufw enable, y
  • Sprawdzamy: sudo ufw status

Status: aktywny

Do                         Akcja      Od
--                         ------      ----
OpenSSH                    ZEZWÓL       Wszędzie
OpenSSH (v6)               ZEZWÓL       Wszędzie (v6)

Wszystko w porządku.

Instalujemy Nginx

Podczas instalacji czasami zapyta "Jesteś pewien?". Odpowiadaj y (no tylko, jeśli jesteś pewien).

  • sudo apt update
  • sudo apt install nginx

Dodajemy Nginx do ustawień zapory ogniowej

  • sudo ufw app list
  • sudo ufw allow 'Nginx HTTP'
  • sudo ufw status

Status: aktywny

Do                         Akcja      Z
--                         ------      ----
OpenSSH                    ZEZWOLEŃ       Wszędzie
Nginx HTTP                 ZEZWOLEŃ       Wszędzie
OpenSSH (v6)               ZEZWOLEŃ       Wszędzie (v6)
Nginx HTTP (v6)            ZEZWOLEŃ       Wszędzie (v6)

Przejdź do swojego IP. Jeśli wszystko jest w porządku, powinieneś zobaczyć następujące.

Wdrożenie aplikacji na Laravel 7 na Ubuntu & Nginx

Instalujemy MySQL

  • sudo apt install mysql-server
  • Uruchamiamy automatyczny skrypt ochrony sudo mysql_secure_installation

Odpowiedz na zadane pytania. Jeśli nie wiesz, co odpowiedzieć, oto zalecane opcje:

  • Wtyczka walidacji hasła — N

  • Usunąć anonimowych użytkowników? — Y

  • Zabronić zdalnego logowania roota? — N

  • Usunąć testową bazę danych i dostęp do niej? — N

  • Czy przeładować tabele uprawnień teraz? — Y

  • Logujemy się do MySQL: sudo mysql

  • Sprawdzamy metody dostępu: SELECT user,authentication_string,plugin,host FROM mysql.user;

  • Ustawiamy hasło dla roota: ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '';

  • Sprawdzamy metody dostępu ponownie: SELECT user,authentication_string,plugin,host FROM mysql.user;

  • Zastosujemy zmiany i wyjdziemy z MySQL: FLUSH PRIVILEGES; i exit

  • Teraz, aby zalogować się do MySQL, musisz użyć mysql -u root -p i wpisać hasło

Instalujemy PHP

Skorzystamy z zewnętrznego repozytorium od Ondřej Surý

  • sudo apt update
  • sudo apt install -y curl wget gnupg2 ca-certificates lsb-release apt-transport-https
  • sudo apt-add-repository ppa:ondrej/php
  • sudo apt update

Teraz wybieramy. Dla Laravel 7 możesz wybrać PHP 7.3 lub 7.4. Różnica będzie jedynie w liczbach 3 i 4.

  • 7.3: sudo apt install -y php7.3-fpm php7.3-mysql
  • 7.4: sudo apt install -y php7.4-fpm php7.4-mysql

PHP FastCGI Process Manager (fpm) obsługuje żądania PHP. mysql, oczywiście, do pracy z MySQL.

Resztę będę robić na 7.4.

Konfigurujemy Nginx

  • sudo vim /etc/nginx/sites-available/

Zamiast "<Twój domen>" wpisz domenę (na przykład, mysite.ru), którą chcesz używać w przyszłości. Jeśli jeszcze jej nie masz, wpisz cokolwiek, a później po prostu powtórz te kroki w tym rozdziale dla swojej domeny, gdy ją wybierzesz.

Wpisujemy następujące:

server {
        listen 80;
        root /var/www/html;
        index index.php index.html index.htm index.nginx-debian.html;
        server_name ;

        location / {
                try_files $uri $uri/ =404;
        }

        location ~ .php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
        }

        location ~ /.ht {
                deny all;
        }
}

Jeśli wybrałeś wersję 7.3 zamiast php7.4-fpm.sock wpisz php7.4-fpm.sock.

Słuchamy portu 80 na server_name, gdy przychodzi zapytanie w korzeniu /var/www/html bierze plik index. Jeśli po server_name coś jest, szukamy takiego pliku. Nie znajdujemy, wyrzucamy 404. Jeśli kończy się na .php, przetwarzamy przez fpm. Jeśli jest .ht, zabraniaj (403).

  • Tworzymy link z sites-available do sites-enabled: sudo ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/
  • Usuwamy link do default: sudo unlink /etc/nginx/sites-enabled/default
  • Sprawdzamy na błędy: sudo nginx -t
  • Restartujemy: sudo systemctl reload nginx

Sprawdzamy działanie:

  • sudo vim /var/www/html/info.php
  • Piszę: <?php phpinfo();
  • Przechodzimy do <Twoje IP>/info.php

Powinieneś zobaczyć coś podobnego:

Wdrożenie aplikacji na Laravel 7 na Ubuntu & Nginx

Teraz ten plik można usunąć: sudo rm /var/www/html/info.php

Instalujemy Laravel

  • 7.3: sudo apt install php7.3-mbstring php7.3-xml composer unzip

  • 7.4: sudo apt install php7.4-mbstring php7.4-xml composer unzip

  • Logujemy się do MySQL: mysql -u root -p

  • Tworzymy bazę danych o nazwie laravel: STWÓRZ BAZĘ DANYCH laravel DOMYŚLNE ZBIORY ZNAKÓW utf8 KOLIZJA utf8_unicode_ci;

  • Dajemy dostęp roota do laravel: PRZYZNANIE WSZYSTKIM DOSTĘPU DO laravel.* DO 'root'@'localhost' ZIDENTYFIKOWANE HASŁEM '' ;

  • FLUSH PRIVILEGES;

  • exit

  • cd /var/www/html

  • Tworzymy folder dla projektu: sudo mkdir -p

  • Dajemy użytkownikowi laravel uprawnienia do projektu: sudo chown laravel:laravel

Następnie trzeba przenieść projekt. Na przykład, klonując z Github.

  • cd ./
  • git clone .

Należy pamiętać, że jeśli nie zachowałeś statycznych plików (na przykład z /public) na Github, to nie będziesz ich miał. Ja, na przykład, dla rozwiązania tego stworzyłem oddzielną gałąź deploy, z której już klonowałem: git clone -b --single-branch ..

  • Instalujemy zależności: composer install
  • Tworzymy .env: vim .env

Jego podstawowa wersja wygląda tak:

APP_NAME=Laravel
APP_ENV=produkcja
APP_KEY=
APP_DEBUG=false
APP_URL=http://

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=

Jeśli kopiujesz swój .env, zamień APP_ENV na production, APP_DEBUG na false i wprowadź odpowiednie ustawienia dla MySQL.

  • Migrujemy bazę danych: php artisan migrate
  • Generujemy kod: php artisan key:generate

Zmieniamy uprawnienia:

  • sudo chown -R $USER:www-data storage
  • sudo chown -R $USER:www-data bootstrap/cache
  • chmod -R 775 storage
  • chmod -R 775 bootstrap/cache

Ostatnia rzecz, która pozostała, to skonfigurować Nginx pod Laravel:

sudo vim /etc/nginx/sites-available/

serwer {
    nasłuchuj 80;
    nasłuchuj [::]:80;

    root /var/www/html//public;
    index index.php index.html index.htm index.nginx-debian.html;

    server_name ;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ .php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    }

    location ~ /.ht {
        deny all;
    }
}

Jak i poprzednio, jeśli wybrałeś wersję 7.3 zamiast php7.4-fpm.sock wpisz php7.4-fpm.sock.

Konfiguracja domeny na DigitalOcean

Wszystko jest bardzo proste. Kupujesz domenę (gdziekolwiek), przechodzisz na DigitalOcean w Utwórz->Domains/DNS. W polu Dodaj domenę wpisujesz tę domenę, naciskasz dodaj. Następnie przechodzisz do ustawień domeny i w polu HOSTNAME wpisujesz @. Wybierasz projekt i naciskasz Utwórz rekord.
Teraz przechodzisz na stronę, gdzie kupiłeś domenę, znajdujesz tam "Serwery DNS" (lub coś podobnego) i wpisujesz serwery DigitalOcean (a dokładnie ns1.digitalocean.com, ns2.digitalocean.com, ns3.digitalocean.com). Teraz musisz poczekać (trochę lub dużo), aż te ustawienia zostaną przyjęte. Gotowe!
Jedynym problemem jest to, że twoja strona będzie dostępna tylko jako HTTP. Aby uzyskać HTTPS, przechodzimy do następnej części.

Konfigurujemy HTTPS

Instalujemy certbot i przekazujemy mu nazwę domeny (w formacie mysite.ru) oraz nazwę domeny z www (www.mysite.ru).

  • sudo add-apt-repository ppa:certbot/certbot
  • sudo apt install python-certbot-nginx
  • sudo certbot certonly --webroot --webroot-path=/var/www/html//public -d -d www.

Teraz musimy ponownie skonfigurować Nginx (nie zapomnij wprowadzić własnych wartości):

serwer {
    nasłuchuj 80;
    nasłuchuj [::]:80;

    server_name  www.; 
    return 301 https://$server_name$request_uri;
}

serwer {
    nasłuchuj 443 ssl http2;
    nasłuchuj [::]:443 ssl http2;
    server_name  www.;
    root /var/www/html//public;

    ssl_certificate /etc/letsencrypt/live//fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live//privkey.pem;

    ssl_protocols TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
    ssl_prefer_server_ciphers on;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    index index.php index.html index.htm index.nginx-debian.html;

    charset utf-8;

    location / {
            try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ .php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    }

    location ~ /.ht {
            deny all;
    }

    location ~ /.well-known {
            allow all;
    }
}

Myślę, że już zrozumiałeś, co trzeba zmienić dla PHP 7.3.

Tutaj, naprawdę, wszystko jest proste. Po prostu przekierowujemy wszystkie żądania z HTTP (port 80) na HTTPS (port 443). A tam robimy dokładnie to samo, co wcześniej, ale już z szyfrowaniem.

Pozostało ustawić uprawnienia w zaporze:

  • sudo nginx -t
  • sudo ufw app list
  • sudo ufw allow 'Nginx HTTPS'
  • sudo ufw status
  • sudo systemctl reload nginx

Teraz wszystko powinno działać, jak należy.

[Дополнительно] Установка Node.js

Jeśli nagle będziesz potrzebować uruchamiać polecenia npm bezpośrednio na serwerze, musisz zainstalować Node.js.

  • sudo apt update
  • sudo apt install -y nodejs npm
  • nodejs -v

To wszystko, zatrzymałem się na tym etapie. Tak naprawdę, jestem zadowolony z rezultatu. Może przejdę z DigitalOcean gdzie indziej, bliżej Rosji i taniej. Ale ponieważ przeszedłem wszystkie etapy weryfikacji na stronie i wszystko robiłem tam, pokazałem na ich przykładzie. Poza tym ich startowe 100 dolarów to doskonała baza do ćwiczeń.

P.S. Szczególne podziękowania dla autora tego gista, który posłużył za podstawę wszystkich powyższych działań. W niektórych momentach nie działa to dla Laravel 7, poprawiłem to.

P.P.S. Jeśli jesteś świetnym inżynierem, który myśli w skryptach bash, proszę, nie bądź zbyt surowy. Może poziom tego artykułu wydać się zbyt niski, ale cieszyłbym się, gdybym znalazł coś takiego, kiedy tego potrzebowałem. Jeśli masz sugestie dotyczące ulepszeń, chętnie je przyjmę.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster