Programos diegimas Laravel 7 sistemoje Ubuntu ir Nginx

Programos diegimas Laravel 7 sistemoje Ubuntu ir Nginx

Aš nusprendžiau savo portfolio sukurti naudodamas Laravel 7. Kad pagrindinis puslapis būtų nukreipimo puslapis, o visą informaciją jame būtų galima keisti naudojant administratoriaus skydelį. Ne esmė. Atėjo iki dislokavimo. Radau porą gerų pamokymų, kaip tai padaryti pilnaverčiame serveryje su visomis bėdomis. Nesu labai stiprus dislokavimo srityje; paprastai esu daugiau priekyje nei pilnas. Ir jei dar galiu rašyti ir testuoti PHP, tai prieš valdant serverį ir pan. Aš dar nesuaugau. Bet aš turėjau tai išsiaiškinti.

Dabar atliksime visus veiksmus, pradedant paleidimu per SSH ir baigiant darbo svetaine. Stengsimės išvengti visų spąstų.

Panašių instrukcijų galite rasti internete. Juk pagaliau radau. Tiesa, ne vienoje vietoje, ne be StackOverflow pagalbos ir vargu ar rusiškai. Aš kentėjau. Štai kodėl aš nusprendžiau supaprastinti jūsų gyvenimą.

Viską padarysime su lašeliu „DigitalOcean“. Tai, žinoma, nėra būtina; pasirinkite bet kokį prieglobą. Kai pasieksite veikiantį Ubuntu serverį, grįžkite. Tiems, kurie vis dar nuspręs tai padaryti „DigitalOcean“, bus daugiau patarimų, kaip nustatyti domeną. Ir 100 USD nukreipimo nuoroda.

Visi su „DigitalOcean“ susiję veiksmai bus pateikti tokiose išnašose.

Pradėkime.

TL;DR (tik pagrindinės komandos)

Sukurti vartotoją

  • ssh root@[IP-адрес вашего дроплета]
  • adduser laravel
  • usermod -aG sudo laravel
  • su laravel

Pridėkite prie jo SSH

  • mkdir ~/.ssh
  • chmod 700 ~/.ssh
  • vim ~/.ssh/authorized_keys
  • Įdėkite viešąjį raktą
  • chmod 600 ~/.ssh/authorized_keys

Ugniasienė

  • 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 '<Ваш пароль для MySQL>';
  • 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/<Ваш домен>

Pagrindinė sąranka:

server {
        listen 80;
        root /var/www/html;
        index index.php index.html index.htm index.nginx-debian.html;
        server_name <Ваш домен или IP>;

        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;
        }
}

Tik „Laravel“ HTTP sąranka:

server {
    listen 80;
    listen [::]:80;

    root /var/www/html/<Имя проекта>/public;
    index index.php index.html index.htm index.nginx-debian.html;

    server_name <Ваш домен или IP>;

    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;
    }
}

„Laravel“ HTTPS nustatymas:

server {
    listen 80;
    listen [::]:80;

    server_name <Ваш домен> www.<Ваш домен>;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]: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

  • CREATE DATABASE laravel DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

  • GRANT ALL ON laravel.* TO 'root'@'localhost' IDENTIFIED BY '<Ваш пароль от MySQL>';

  • 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=production
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=<Ваш пароль от MySQL>

  • 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

Sukurkite lašelį „DigitalOcean“ ir užregistruokite naują SSH raktą

Tikrai tikiu, kad jūs patys išsiaiškinsite, kaip užsiregistruoti „DigitalOcean“. Tai nėra lengva, su daugybe patikrinimų ir kitų dalykų. Jei tikrindami dokumentus nuolat gaunate tinklo klaidą, pabandykite viską daryti per VPN, tai turėtų padėti.

Viršuje esančiame meniu spustelėkite kurti->Lašeliai. Pasirinkite ubuntu.

Kai tik užsiregistruosite, į savo sąskaitą gausite 100 USD. Bet neapsigaukite. Turite tik 60 dienų jį praleisti. Ir tai yra labai mažai. Galbūt, kaip ir aš, norėsite pasinaudoti brangesniu planu, kad vėliau, kai tik pradės plaukti tikri pinigai, galėtumėte pereiti prie pigesnio. Iš karto pasakysiu, kad tai neveiks. Galite jį padidinti, bet negalite jo sumažinti. Taip eina. aš renkuosi Standartas->$5.

Renkuosi artimiausią mums regioną Frankfurtas. VPC tinklas->default-fra1

Nedelsdami atliksime autentifikavimą per SSH. Spustelėkite Naujas SSH raktas. Jei neturite SSH, dešinėje yra labai paprastos instrukcijos. Atidarykite „bash“ terminalą ir įklijuokite ssh-keygen. Tada einame į failą su viešuoju raktu /Users/<Ваше имя пользователя>/.ssh/id_rsa.pub (arba tiesiog cat ~/.ssh/id_rsa.pub), nukopijuokite turinį ir įklijuokite jį į langą kairėje. Bet koks vardas.

Mes sugalvojame lašelio pagrindinio kompiuterio pavadinimą.

Spauskite čia Sukurkite lašelį

Sukurti naują vartotoją

  • ssh root@[IP-адрес вашего дроплета]
  • Ar tikrai norite tęsti ryšį (taip/ne/[piršto atspaudas])? yes
  • Įveskite savo SSH slaptažodį
  • Sukurti vartotoją laravelis: adduser laravel
  • Įveskite slaptažodį ir kitą informaciją (aš įvedu tik visą vardą)
  • Pridėkite vartotoją prie sudo grupės: usermod -aG sudo laravel

SSH naujam vartotojui

  • Perjungti į naują vartotoją: su laravel

Mes atliekame visus veiksmus toliau, iki straipsnio pabaigos, laravel vartotojo vardu. Todėl, jei jus staiga pertraukia, prisijunkite iš naujo ir įveskite su laravel

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

Failą atidarėme Vim. Jei nesate su juo susipažinę, galite dirbti „Nano“, jūsų teisė.

Paprasčiausios Vim komandos

Norėdami visame straipsnyje naudoti Vim redaktorių, tereikia žinoti šiuos dalykus.

  • Vim turi skirtingus režimus: įprastą režimą, kuriame įvedate komandas ir pasirenkate režimus bei kitus.
  • Norėdami išeiti iš bet kurio režimo ir grįžti į įprastą režimą, tiesiog paspauskite Esc
  • Judėti: galite tiesiog naudoti rodykles
  • Iseiti neissaugojus <Normal mode>: :q!
  • Išeikite ir išsaugokite <Normal mode>: :wq
  • Perjungti į teksto įvesties režimą <Normal mode>: i (iš anglų kalbos. įterpti)
  • Įterpiame viešąjį raktą (ką padarėme aukščiau)
  • Apsaugome nuo pokyčių: chmod 600 ~/.ssh/authorized_keys

Ugniasienės įdiegimas

  • Pažvelkime į visus galimus nustatymus: sudo ufw app list
  • Leisti OpenSSH (kitaip jis mus užrakins): sudo ufw allow OpenSSH
  • Paleiskite užkardą: sudo ufw enable, y
  • Mes patikriname: sudo ufw status

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)

Viskas gerai.

Nginx diegimas

Diegimo metu kartais jūsų paklaus: „Ar tu tikras? Atsakymas y (na, tik jei esate tikras).

  • sudo apt update
  • sudo apt install nginx

Nginx įtraukimas į ugniasienės nustatymus

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

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
Nginx HTTP                 ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
Nginx HTTP (v6)            ALLOW       Anywhere (v6)

Eikite į savo IP. Jei viskas klostosi gerai, turėtumėte pamatyti toliau pateiktą informaciją.

Programos diegimas Laravel 7 sistemoje Ubuntu ir Nginx

MySQL diegimas

  • sudo apt install mysql-server
  • Paleidžiamas automatinis apsaugos scenarijus sudo mysql_secure_installation

Atsakykite į užduotus klausimus. Jei nežinote, ką atsakyti, čia yra keletas siūlomų variantų:

  • Patvirtinkite slaptažodžio papildinį - N

  • Pašalinti anoniminius naudotojus? — Y

  • Neleisti root prisijungimo nuotoliniu būdu? — N

  • Pašalinti bandymų duomenų bazę ir prieigą prie jos? — N

  • Dabar iš naujo įkelti privilegijų lenteles? — Y

  • Eikime į MySQL: sudo mysql

  • Pažvelkime į prieigos būdus: SELECT user,authentication_string,plugin,host FROM mysql.user;

  • Nustatykite root slaptažodį: ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '<Ваш пароль для MySQL>';

  • Dar kartą pažvelkime į prieigos būdus: SELECT user,authentication_string,plugin,host FROM mysql.user;

  • Taikykite pakeitimus ir išeikite iš MySQL: FLUSH PRIVILEGES; и exit

  • Dabar, norėdami prisijungti prie MySQL, turite naudoti mysql -u root -p ir įveskite slaptažodį

PHP diegimas

Naudokime trečiosios šalies saugyklą iš Ondrejus 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

Dabar išsirinkime. „Laravel 7“ galite pasirinkti PHP 7.3 arba 7.4. Vienintelis skirtumas bus skaičiais 3 ir 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) veikia su PHP užklausomis. mysql, žinoma, darbui su MySQL.

Nuo šiol viską darysiu 7.4.

„Nginx“ nustatymas

  • sudo vim /etc/nginx/sites-available/<Ваш домен>

Vietoj „<Jūsų domenas>“ įveskite domeną (pvz., mysite.ru), kurį norite naudoti ateityje. Jei jo dar neturite, parašykite bet kurį, tada tiesiog pakartokite šiame skyriuje nurodytus veiksmus savo domenui, kai jį pasirinksite.

Įveskite:

server {
        listen 80;
        root /var/www/html;
        index index.php index.html index.htm index.nginx-debian.html;
        server_name <Ваш домен или IP>;

        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;
        }
}

Jei vietoj to pasirinkote 7.3 versiją php7.4-fpm.sock Įrašyk php7.4-fpm.sock.

Klausytis 80 prievado server_namekai pasiekiame pagrindinį prašymą /var/www/html paimkite indekso failą. Jei po server_name Kažkas yra, mes ieškome tokio failo. Jei nerandame, išmetame 404. Jei baigiasi .php, perbegti fpm... Jei yra .ht, uždrausti (403).

  • Kuriant nuorodą iš sites-available в sites-enabled: sudo ln -s /etc/nginx/sites-available/<Ваш домен> /etc/nginx/sites-enabled/
  • Pašalinama nuoroda į default: sudo unlink /etc/nginx/sites-enabled/default
  • Tikrinama, ar nėra klaidų: sudo nginx -t
  • Perkraukite: sudo systemctl reload nginx

Darbo tikrinimas:

  • sudo vim /var/www/html/info.php
  • Mes rašome: <?php phpinfo();
  • Eime <Ваш IP>/info.php

Turėtumėte pamatyti kažką panašaus:

Programos diegimas Laravel 7 sistemoje Ubuntu ir Nginx

Dabar šį failą galima ištrinti: sudo rm /var/www/html/info.php

Įdiekite 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

  • Eikime į MySQL: mysql -u root -p

  • Sukurkite duomenų bazę pavadinimu laravelis: CREATE DATABASE laravel DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

  • Suteikiame root prieigą prie laravelis: GRANT ALL ON laravel.* TO 'root'@'localhost' IDENTIFIED BY '<Ваш пароль от MySQL>';

  • FLUSH PRIVILEGES;

  • exit

  • cd /var/www/html

  • Sukurkite projekto aplanką: sudo mkdir -p <Имя проекта>

  • Mes suteikiame vartotojui laravelis teisės į projektą: sudo chown laravel:laravel <Имя проекта>

Toliau reikia perkelti projektą. Pavyzdžiui, klonavimas iš Github.

  • cd ./<Имя проекта>
  • git clone <ссылка на проект> .

Verta pagalvoti, kad jei neišsaugojote statinių failų (pavyzdžiui, iš /public) „Github“, tada, žinoma, jų neturėsite. Pavyzdžiui, aš sukūriau atskirą giją, kad tai išspręsčiau deploy, iš kurio jau klonavau: git clone -b <имя ветки> --single-branch <ссылка на проект> ..

  • Priklausomybių diegimas: composer install
  • Sukurti .env: vim .env

Pagrindinė jo versija atrodo taip:

APP_NAME=Laravel
APP_ENV=production
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=<Ваш пароль от MySQL>

Jei nukopijuosite .env, pakeiskite APP_ENV į gamybinę, APP_DEBUG į false ir įveskite teisingus MySQL nustatymus.

  • Duomenų bazės perkėlimas: php artisan migrate
  • Kodo generavimas: php artisan key:generate

Leidimų keitimas:

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

Paskutinis dalykas, kurį liko, yra iš naujo sukonfigūruoti „Nginx“, skirtą „Laravel“:

sudo vim /etc/nginx/sites-available/<Ваш домен>

server {
    listen 80;
    listen [::]:80;

    root /var/www/html/<Имя проекта>/public;
    index index.php index.html index.htm index.nginx-debian.html;

    server_name <Ваш домен или IP>;

    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;
    }
}

Kaip ir praėjusį kartą, jei vietoj to pasirinkote 7.3 versiją php7.4-fpm.sock Įrašyk php7.4-fpm.sock.

„DigitalOcean“ domeno nustatymas

Viskas iš tikrųjų labai paprasta. Perkate domeną (bet kur), pereikite prie DigitalOcean adresu kurti->Domenai/DNS... Lauke Pridėkite domeną įvedate šį domeną ir spustelėkite pridėti. Tada eikite į domeno nustatymus ir į lauką PRANEŠĖJO PAVADINIMAS įveskite @. Pasirinkite projektą ir spustelėkite Sukurti įrašą.
Dabar eikite į svetainę, kurioje įsigijote domeną, suraskite ten „DNS serveriai“ (ar ką nors panašaus) ir įveskite „DigitalOcean“ serverius (būtent ns1.digitalocean.com, ns2.digitalocean.com, ns3.digitalocean.com). Dabar reikia šiek tiek palaukti (arba daug), kol šie nustatymai bus priimti. Pasiruošę!
Vienintelė problema yra ta, kad jūsų svetainė bus atidaryta tik kaip HTTP. Norėdami turėti HTTPS, pereikite prie kitos dalies.

HTTPS nustatymas

Įdiekite certbot ir perduokite jam domeno pavadinimą (formatą mysite.ru) ir domeno vardą su 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.<Ваш домен>

Dabar reikia iš naujo sukonfigūruoti „Nginx“ (nepamirškite pakeisti savo verčių):

server {
    listen 80;
    listen [::]:80;

    server_name <Ваш домен> www.<Ваш домен>;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]: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;
    }
}

Manau, jūs jau suprantate, ką reikia pakeisti PHP 7.3.

Čia, tiesą sakant, viskas paprasta. Mes tiesiog peradresuojame visas užklausas iš HTTP (80 prievadas) į HTTPS (443 prievadas). O ten viską darome taip pat, kaip ir anksčiau, tik su šifravimu.

Lieka tik nustatyti leidimus ugniasienėje:

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

Dabar viskas turėtų veikti taip, kaip turėtų.

[Išplėstinė] Node.js diegimas

Jei staiga reikia paleisti npm komandas tiesiai serveryje, turite įdiegti Node.js.

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

Štai ir sustojau šiame etape. Iš principo esu patenkintas rezultatu. Galbūt aš pereisiu iš „DigitalOcean“ kur nors arčiau Rusijos ir pigiau. Bet kadangi jau buvau perėjęs visus patikrinimo etapus svetainėje ir viską ten padaręs, parodžiau juos savo pavyzdžiu. Be to, jų nuo 100 USD yra puikus tramplinas treniruotėms.

PS Ypatingas ačiū autoriui ši esmė, kuris buvo visų pirmiau minėtų veiksmų pagrindas. Kai kuriais atvejais jis neveikia Laravel 7, aš jį ištaisiau.

PPS Jei esate aukščiausio lygio inžinierius, mąstantis bash komandomis, neteiskite griežtai. Jums gali pasirodyti, kad šis straipsnis yra žemo lygio, bet aš mielai būčiau jį radęs, kai man jo prireiktų. Jei yra pasiūlymų tobulėti, aš už tai.

Šaltinis: www.habr.com

Добавить комментарий