Установка программного обеспечения

56

Порядок установки платформы Айвенго

 

Убеждаемся, что root заходит через ssh-ключи

 

Обновление системы:

apt update && apt upgrade -y && apt dist-upgrade -y && apt autoremove -y

 

Если видим надпись The following packages have been kept back, то:

apt --with-new-pkgs upgrade <packages>

Например:
apt --with-new-pkgs upgrade -y dnsmasq-base python3-update-manager update-manager-core

 

apt install -y htop fail2ban zip unzip git rename ntp

 

Устанавливаем временную зону Europe/Moscow

dpkg-reconfigure tzdata

 

Swap 2 GB

fallocate -l 2G /swapfile

chmod 600 /swapfile

mkswap /swapfile

swapon /swapfile

echo '/swapfile none swap sw 0 0' | tee -a /etc/fstab

echo 'vm.swappiness=10' >> /etc/sysctl.conf

echo 'vm.vfs_cache_pressure=50' >> /etc/sysctl.conf

 

Добавить юзера ubuntu с паролем 1234

(не страшно, доступа снаружи по паролю не будет)

adduser ubuntu

usermod -aG sudo ubuntu

echo "ubuntu ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers

 

Переключаемся на него

su ubuntu

 

Создаем ключи

cd ~

mkdir .ssh && chmod 700 .ssh

touch .ssh/authorized_keys

chmod 600 .ssh/authorized_keys

Добавляем в authorized_keys наши ключи.

 

Запрещаем юзеру ubuntu входить по паролю

exit

echo "

Match User ubuntu

    PasswordAuthentication no" >> /etc/ssh/sshd_config

service ssh restart

 

Отключаемся и перезаходим уже сразу под юзером ubuntu

 

Настраиваем алиасы

В файл /home/ubuntu/.profile добавляем:

 

alias chownub="sudo chown -R ubuntu:ubuntu *"

alias nrestart="sudo nginx -t && sudo service nginx restart"

alias nreload="sudo nginx -t && sudo service nginx reload"

alias nclear="sudo nginx -t && sudo rm -rf /cache_front && sudo service nginx restart"

alias gp="git pull"

 

alias qq="php artisan"

alias debug="php artisan app:debug"

alias logs="bash ~/check_logs.sh"

alias logsclear="bash ~/clear_logs.sh"

 

alias update="bash ~/update.sh"

alias api="cd /var/www/market/api-ms"

alias front="cd /var/www/market/front"

alias merchant-api="cd /var/www/market/merchant-api-ms"

alias moysklad="cd /var/www/market/moysklad-ms"

alias report-ms="cd /var/www/market/report-ms"

alias front-build="cd /var/www/market/front && git pull && npm i && npm run build && pm2 restart front && sudo rm -rf /cache_front && sudo service nginx restart"

alias up='git pull --no-edit && rm bootstrap/cache/* && composer update

if [ $(basename "$PWD") != "admin" ] && [ $(basename "$PWD") != "mas" ]; then

    php artisan migrate --force && php artisan config:cache && php artisan queue:restart

fi'

 

Закрываем терминал и перезаходим, чтобы алиасы применились

 

Максимальный размер логов 100M

sudo find /etc/systemd -type f -name journald.conf -exec sed -i -r 's/#SystemMaxUse=/SystemMaxUse=100M/g' {} \;

sudo systemctl daemon-reload

sudo systemctl restart systemd-journald

 

 

PHP 8.5

sudo apt install software-properties-common -y

sudo add-apt-repository ppa:ondrej/php

sudo apt update && sudo apt upgrade -y

sudo apt install php8.5-common -y

sudo apt install php8.5-cli -y

sudo apt install php8.5-{curl,intl,mysql,readline,xml,mbstring,pgsql,redis,gd,zip} -y

sudo apt install php8.5-imagick -y

sudo apt install php8.5-fpm -y

sudo chown -R ubuntu:ubuntu /etc/php

 

Выбираем версию по-умолчанию 8.5

sudo update-alternatives --config php

 

Редактируем

/etc/php/8.5/fpm/pool.d/www.conf

 

user = ubuntu

group = ubuntu

 

pm = ondemand

pm.max_children = 120

pm.start_servers = 50

pm.min_spare_servers = 50

pm.max_spare_servers = 120

pm.process_idle_timeout = 10s

 

 

Настройки PHP

echo 'memory_limit = 2G
post_max_size = 100M

upload_max_filesize = 100M

date.timezone="Europe/Moscow"'>/etc/php/my.ini

 

sudo find /etc/php -type d -name conf.d -exec ln -s /etc/php/my.ini {}/my.ini \;

sudo service php8.5-fpm restart

 

Composer

cd ~

php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"

php composer-setup.php

php -r "unlink('composer-setup.php');"

sudo mv composer.phar /usr/local/bin/composer

composer -V

 

Yandex Mirror

sudo chown ubuntu:ubuntu /etc/apt/sources.list

 

если Ubuntu 24

echo '

# Yandex Mirror

deb http://mirror.yandex.ru/ubuntu/ noble main restricted

deb-src http://mirror.yandex.ru/ubuntu/ noble main restricted' >> /etc/apt/sources.list

 

если Ubuntu 22 (deprecated)

echo '

# Yandex Mirror

deb http://mirror.yandex.ru/ubuntu/ jammy main restricted

deb-src http://mirror.yandex.ru/ubuntu/ jammy main restricted' >> /etc/apt/sources.list

 

 

sudo apt update && sudo apt upgrade && sudo apt autoremove -y

 

ElasticSearch - российские ip забанены, используем зеркало

echo "deb [trusted=yes] https://mirror.yandex.ru/mirrors/elastic/8/ stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list

sudo apt update && sudo apt install -y elasticsearch

 

sudo nano /etc/elasticsearch/elasticsearch.yml

xpack.security.enabled: false

xpack.security.enrollment.enabled: false

 

Ограничение расхода памяти

sudo nano /etc/elasticsearch/jvm.options

 

Нужно раскомментировать и убрать первый пробел

-Xms4g

-Xmx4g

 

Для систем с ОЗУ 8 GB и менее ставим
-Xms2g

-Xmx2g

 

sudo nano /lib/systemd/system/elasticsearch.service

 

Добавляем в секцию [Service]:

Restart=always

 

Проверяем

sudo systemctl cat elasticsearch.service

 

sudo systemctl daemon-reload

sudo systemctl enable elasticsearch.service

sudo systemctl start elasticsearch.service

curl -X GET http://localhost:9200

 

 

Удаляем репу (она выдает ошибки)

sudo rm -rf /etc/apt/sources.list.d/elastic-8.x.list

 

Redis

 

sudo apt install redis-server -y

sudo systemctl enable redis-server

 

Создаем папку для проекта

sudo mkdir -p /var/www

sudo chown -R ubuntu:ubuntu /var/www

mkdir /var/www/market

 

Создать logs (admin и mas все еще нужны, так как есть такие хосты в Nginx)

mkdir /var/www/market/logs/

mkdir /var/www/market/logs/admin

mkdir /var/www/market/logs/mas

mkdir /var/www/market/logs/api

mkdir /var/www/market/logs/front

 

 

Создать ssh ключи (без фразы)
ssh-keygen
cat ~/.ssh/id_rsa.pub
или cat ~/.ssh/id_ed25519.pub

 

Далее этот ключ нужно добавить в Gitlab Settings / Repository / Deploy Keys во все микросервисы, которые будут устанавливаться через git clone (в библиотеки соответственно добавлять не нужно)

Для композера создаем Personal Access Tokens с правами read_api:
https://gitlab.com/-/user_settings/personal_access_tokens

Удаляем предложенную дату, чтобы токен был не на 1 месяц, а на 11

Gitlab Token

echo '{

    "gitlab-token": {

        "gitlab.com": "TOKEN"

    }

}' > ~/.config/composer/auth.json

 

 

Node 18

sudo apt install curl -y

curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash

source ~/.bashrc

nvm install 18

nvm alias default 18

npm install yarn -g

npm install pm2 -g

 

 

Микросервисы

cd /var/www/market

git clone git@gitlab.com:lennuf/api.git

git clone git@gitlab.com:lennuf/front.git front

 

 

Базы данных

 

sudo apt install curl ca-certificates

sudo install -d /usr/share/postgresql-common/pgdg

curl -fsSL https://postgresql.org | sudo gpg --dearmor -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.gpg

 

 

 

 

# 1. Скачиваем ключ и сохраняем его в правильное место

curl -fsSL https://postgresql.org | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg

 

# 2. Добавляем репозиторий

echo "deb http://postgresql.org $(lsb_release -cs)-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list

 

# 3. Обновляем списки

sudo apt update

 

 

 

 

 

sudo apt install postgresql postgresql-contrib -y

 

Для всех баз используем пользователя postgres с паролем postgres

sudo -u postgres psql

ALTER USER postgres WITH PASSWORD 'postgres';

exit

 

Для поиска требуется расширение pg_trgm

Проверка:

SELECT * FROM pg_extension WHERE extname = 'pg_trgm';

Установка:

CREATE EXTENSION pg_trgm;

 

Создаем базы

sudo -u postgres createdb api

sudo -u postgres createdb report

 

 

Certbot

 

sudo apt install certbot python3-certbot-nginx -y

sudo systemctl status certbot.timer

CTRL+C / Q

sudo chown -R ubuntu:ubuntu /etc/letsencrypt

 

Nginx

sudo apt install -y nginx ufw

sudo ufw allow 'Nginx Full'

sudo ufw allow 'ssh'

sudo ufw enable

sudo ufw status

 

Получаем последнюю стабильную версию из офиц. репо

sudo apt install -y curl gnupg2 ca-certificates lsb-release

 

curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \

| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

 

gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg

 

echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \

http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \

    | sudo tee /etc/apt/sources.list.d/nginx.list

 

echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \

    | sudo tee /etc/apt/preferences.d/99nginx

 

sudo apt update

sudo apt install nginx -y

 

Должно показать версию 1.26 и выше

nginx -v

sudo chown -R ubuntu:ubuntu /etc/nginx

sudo chown -R ubuntu:ubuntu /var/log/nginx

sudo usermod -aG www-data nginx

 

Добавить в nginx.conf в секцию http

server_names_hash_bucket_size 128;

include /etc/nginx/sites-enabled/*.conf;

 

Nginx sites-enabled и sites-available

Размещаем хосты сразу в sites-enabled без симлинков!

rm -f /etc/nginx/sites-enabled/*

mv /etc/nginx/sites-available/* /etc/nginx/sites-enabled/

rm -rf /etc/nginx/sites-available

rm -rf /etc/nginx/conf.d/*

nrestart

 

Для старых версий симлинки можно создавать так:

sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/

sudo nginx -t && sudo service nginx restart

 

Nginx настройки

echo 'ssl_ciphers EECDH:+AES256:-3DES:RSA+AES:RSA+3DES:!NULL:!RC4;

ssl_session_cache shared:SSL:5m;

ssl_session_timeout 1h;

resolver 8.8.8.8;

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";' > /etc/nginx/conf.d/ssl.conf

 

echo 'server_tokens off;

client_max_body_size 100m;

limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;

limit_conn_zone $binary_remote_addr zone=addr:10m;

' > /etc/nginx/conf.d/vhosts.conf

 

nreload

 

Создаем конфиги хостов

 

mkdir /etc/nginx/conf.host

echo -n 'location /api {

    include conf.host/ips.conf;

    try_files $uri $uri/ /index.php?$query_string;

}' > /etc/nginx/conf.host/api.conf

 

Не забываем заменить IP сервера

echo -n 'allow 127.0.0.1;        # localhost

allow 95.143.188.246;   # server

deny all;

' > /etc/nginx/conf.host/ips.conf

 

 

Копируем хосты для Nginx с других недавно установленных серверов в sites-enabled (кроме default). На примере из brikson.ru в sweetstore.lennuf.market. Не забываем, что у главного хоста обычно есть www. Переименовываем и удаляем строки с ssl-сертификатами.

 

cd /etc/nginx/sites-enabled

rename 's/brikson.ru/sweetstore.lennuf.market/g' *.conf

find . -name "*.conf" -type f | xargs sed -i -r 's/brikson.ru/sweetstore.lennuf.market/g'

find . -name "*.conf" -type f | xargs sed -i -r 's/listen 80/listen 81/g'

find . -name "*.conf" -type f | xargs sed -i -e '/listen 443/d'

find . -name "*.conf" -type f | xargs sed -i -e '/letsencrypt/d'

find . -name "*.conf" -type f | xargs sed -i -e '/_cors/d'

find . -name "*.conf" -type f | xargs sed -i -e '/resolver/d'

nreload

 

 

Получаем сертификаты для каждого хоста.

 

Пример (можно выполнить все сразу)

sudo certbot --nginx -d brikson.ru -d www.brikson.ru
sudo certbot --nginx -d api.brikson.ru

sudo certbot --nginx -d admin.brikson.ru

sudo certbot --nginx -d mas.brikson.ru

 

find . -name "*.conf" -type f | xargs sed -i -r 's/ # managed by Certbot//g'

 

Проходимся по каждому хосту и удаляем блок server с listen 80, который создал certbot, а тот, где listen 81 переименовываем в 80. И для надежности в конце выполняем

cd /etc/nginx/sites-enabled

find . -name "*.conf" -type f | xargs sed -i -r 's/listen 81/listen 80/g'

nreload

ТОЛЬКО ЕСЛИ В ХОСТАХ НЕТ СТРОЧКИ http2 on;

HTTP2 (для Nginx 1.25 и выше)

grep -rls 'listen 443 ssl;' /etc/nginx/sites-enabled | xargs perl -p -i -e 's/listen 443 ssl;/listen 443 ssl;\n\thttp2 on;/g'

nreload

 

HTTP2 (для Nginx 1.24 и ниже)

grep -rls 'ssl;' /etc/nginx/sites-enabled/* | xargs perl -p -i -e 's/ssl;/ssl http2;/g'

nreload

 

 

Настраиваем .env - лучше всего взять с beed.ru - он самый актуальный

 

Если просто скопировали энвы, то заменяем домены

cd /var/www/market

find -type f \( -name .env -o -name .env.json \)  -exec sed -i -r 's/beed.ru/kipavt.ru/' {} \;

 

 

*Если копируем с сервера Faraday - то убираем лишние свойства - REDIS_PREFIX, ELASTIC_INDEX_PREFIX. Свойства S3_HOST (кроме file-ms), JAEGER, SENTRY, ONE_C также удаляем.

 

Название баз данных вписываем актуальное. Лучше всего использовать без лишних суффиксов ms_db.

 

Если загрузка файлов локальная, а не в облако, то в file-ms в .env
FILESYSTEM_DRIVER=local

S3_HOST=https://file-ms.sweetstore.lennuf.market/storage/

 

и также создаем симлинк

ln -s /var/www/market/api/storage/app /var/www/market/api/public/storage

 

Больше не требуется

В admin и mas в html выполняем yarn install && yarn dev-build

*Иногда при ошибке установки пакетов помогает:

yarn add @fortawesome/free-solid-svg-icons

*Либо удаление yarn.lock

 

Установка

Копируем с других серверов /home/ubuntu/update.sh и выполняем команду update

 

Генерация ключей

В каждом микросервисе выполняем php artisan key:generate

cd /var/www/market/api-ms && php artisan key:generate --force

cd /var/www/market/report-ms && php artisan key:generate --force

 

SALT для admin и mas (один токен для обоих)

date | md5sum

 

Сиды и импорт sql

 

auth-ms (если не появился robots.txt в меню, после выполнения перелогиниться)

php artisan db:seed --class=PermissionSeeder

 

api-ms

Команды ниже выполняются очень долго, поэтому лучше скопировать таблицы с предыдущего сервера таблицы cities, city_delivery_service_link и points. Также их можно скачать по ссылке: https://disk.yandex.ru/d/VfdsQYoc5s3RLA

 

*Можно в phpStorm сделать экспорт в SQL (INSERTS) без галочки “Add table definition (DDL)”.

 

Полученные файлы скопировать на новый сервер в /var/www/market и выполнить:

 

Вначале очищаем эти таблицы из базы api (у cities truncate не выйдет, добавляем CASCADE)

 

cd /var/www/market

sudo su postgres

 

psql

\c api

TRUNCATE logistics_points;

TRUNCATE logistics_city_delivery_service_link;

TRUNCATE logistics_cities CASCADE;

exit

 

psql -d api -f logistics_cities.sql

psql -d api -f logistics_city_delivery_service_link.sql

psql -d api -f logistics_points.sql

exit

rm -f *.sql

 

\q

exit

 

Если таблицы не импортировали, то тогда запуск команд (нужно временно прописать CDEK_ACCOUNT данные):

запускаем в фоновом режиме через screen

php artisan import:delivery-service-cities:cdek

php artisan import:points:cdek

 

api-ms: Больше выполнять не нужно

php artisan db:seed --class=VariableSeeder

 

импортировать таблицы: https://disk.yandex.ru/d/KO9oQWZsMb6wsQ

 

cd /var/www/market

sudo su postgres

psql

\c api

TRUNCATE ONLY message_templates;

TRUNCATE ONLY message_service_notifications;

exit

psql -d api -f message_templates.sql

psql -d api -f message_service_notifications.sql

psql -d api -f message_communication_statuses.sql

psql -d api -f message_communication_themes.sql

psql -d api -f message_communication_types.sql

exit

rm -f *.sql

 

Supervisor

sudo apt install supervisor -y

sudo chown -R ubuntu:ubuntu /etc/supervisor

 

в файл supervisord.conf секцию include обновляем

[include]

files = /etc/supervisor/conf.d/*.conf

 /var/www/market/api-ms/supervisor/*.conf

 

sudo service supervisor restart

sudo supervisorctl status

 

Индексация товаров и услуг

cd /var/www/market/api-ms
php artisan elastic:reindex product --force

php artisan elastic:reindex category --force

 

Фронт
front-build
cd /var/www/market/front

pm2 start npm --name "front" -- start

pm2 startup

pm2 save
sudo rm -rf /cache_front && sudo service nginx restart

 

После настройки фронта следует перезагрузить сервер и убедиться, что фронт поднимается автоматически:

 

sudo reboot

pm2 status

 

Если не поднялся, то тогда заново:

cd /var/www/market/front

pm2 start npm --name "front" -- start

pm2 startup

 

скопировать вывод на экране и выполнить, обычно это:

sudo env PATH=$PATH:/home/ubuntu/.nvm/versions/node/v18.20.4/bin /home/ubuntu/.nvm/versions/node/v18.20.4/lib/node_modules/pm2/bin/pm2 startup systemd -u ubuntu --hp /home/ubuntu

 

pm2 save

 

Еще раз ребут и окончательная проверка

 

 

Создание файла стилей и robots.txt

Залогиниться в админку:

super-admin@mas.ru
HLZhMYGBn$

 

Сменить пароль и настроить пользователей

 

Перейти в раздел Веб-витрина / Тема и стили и пересохранить

Перейти в Seo/robots.txt и пересохранить

Проверка данных после установки

Если клиент не передал данные, эти значения нужно очистить

 

Перенести oms-ms/storage/app/document-templates

Обновить S3 в file-ms

Обновить APISHIP_TOKEN в api-ms

Обновить DADATA_API_TOKEN и DADATA_API_SECRET в api-ms

Обновить DADATA_TOKEN в admin и mas

Обновить DADATA_API_KEY в front

Обновить Y_CHECKOUT_SHOP_ID в oms

Обновить SMSC_LOGIN и SMSC_PASSWORD в api-ms (message-ms)

Обновить MAIL в message-ms

Обновить FOOTER_COPY и другие параметры в front

 

 

Crontab (nano)

crontab -e

 

* * * * * cd /var/www/market/api-ms && php artisan schedule:run > /dev/null 2>&1

* * * * * cd /var/www/market/report-ms && php artisan schedule:run >> /dev/null 2>&1

 

Обслуживание системы и дампы

В домашней папке должны быть скрипты backup.sh (нужно поменять имя сервера и настроить dropbox через dropbox_uploader.sh), dumps.sh и clear_nginx_logs.sh. Проверить их корректное выполнение.

 

Для Dropbox нужно иметь доступ в корпоративный аккаунт.

Dropbox Uploader App key нужно получить по адресу https://www.dropbox.com/developers/apps/info/lu5eun00w1jwcpo

 

Бэкапы попадают в папку

https://www.dropbox.com/work/%D0%90%D0%B4%D0%BC%D0%B8%D0%BD%20iWENGO/%D0%9F%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F/Backup_lennuf

 

crontab -e

0 2 * * * cd ~ && bash backup.sh > /dev/null 2>&1

 

clear_nginx_logs.sh

 

#!/bin/bash

 

sudo rm /var/log/nginx/*.*

sudo rm /var/www/*/logs/*/*.*

sudo service nginx reload

sudo chown -R ubuntu:ubuntu /var/www

 

 

dumps.sh

 

#!/bin/bash

 

mkdir -p dumps

 

DB_USER=postgres

DB_PASSWORD=postgres

 

 

DBS=(

    "api"

)

 

for DB in ${DBS[@]}; do

    PGPASSWORD=$DB_PASSWORD pg_dump -h 127.0.0.1 -p 5432 -U $DB_USER $DB | gzip > dumps/$DB.sql.gz

done

 

backup.sh

 

#!/bin/bash

 

SERVER_NAME=example.com

SITES_DIR="/var/www/market"

 

bash dumps.sh

 

for i in `ls dumps`; do

    bash dropbox_uploader.sh upload dumps/$i $SERVER_NAME/sql/$i

done

 

sudo chown -R ubuntu:ubuntu $SITES_DIR

 

for i in `ls $SITES_DIR`; do

    tar czfP $i.tar.gz --exclude-vcs --exclude "node_modules" $SITES_DIR/$i

    echo $i.tar.gz

    bash dropbox_uploader.sh upload $i.tar.gz $SERVER_NAME/www/$i.tar.gz

    rm -f $i.tar.gz

done

 

# Conf backup

sudo tar czfP etc.tar.gz /etc

bash dropbox_uploader.sh upload etc.tar.gz $SERVER_NAME

rm -f etc.tar.gz

 

# Logs backup

sudo tar czfP log.tar.gz /var/log

bash dropbox_uploader.sh upload log.tar.gz $SERVER_NAME

rm -f log.tar.gz

 

# Clear Nginx Logs

bash clear_nginx_logs.sh