Установка программного обеспечения
Порядок установки платформы Айвенго
Убеждаемся, что 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
Бэкапы попадают в папку
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