Розгортка проектів на VPS
В даній статті я хочу описати процес розгортки додатків, який я використовую. Основною особливістю мого підходу є те що я не використовую контейнеризацію, тим самим пропускаючи доволі довгий крок зі збіркою образу додатку. Натомість для моніторингу роботи сервісів я використовую PM2.
Також дана стаття припускає, що ви вже маєте налаштований сервер готовий до роботи. Якщо це не так, то ви можете скористатися іншою статтею де описано процес підготовки нового серверу.
Завантаження коду на сервер
Перш за все, для розгортки нашого додатку нам необхідно отримати
копію нашого коду на сервері. Це можна зробити різним чином, найпростіше це
прямо скопіювати код через команду scp
. Робити так звісно не варто.
Стандартним підходом в даному випадку буде клонування git репозиторію на сервер. Таким чином ми зможемо отримувати актувальну версію коду, без зайвих проблем. Репозиторій з кодом ми можемо розмістити на якомусь хмарному провайдері на кшталт GitHub, GitLab або створити bare репозиторій безпосередньо на нашому сервері.
Після того як ми розмістили наш код у віддаленому репозиторії ми можемо його клонувати
безпосередньо на сервер в робочу директорію з проектами. Я би радив використовувати
для цього або домашню директорію користувача /home/our-user/
або теку /opt/
(попередньо видавши необхідні дозволи нашому користувачу).
Власний хостинг
Якщо ми хостимо репозиторій на нашому сервері, то клонувати наш репозиторій ми можемо командою
git clone /srv/git/cern-ibm5100
Github
Якщо ж ми використовуємо хмарного провайдера, то необхідно ознайомитись з їхньою документацією. Для прикладу в GitHub треба додати Deploy key, щоби мати змогу клонувати приватні репозиторії. Для цього нам необхідно для кожного окремого проекту генерувати власні ssh ключі. Нижче буде приклад того як це можна робити.
ssh-keygen -f ~/.ssh/github-cern-ibm5100 # Генеруємо ключ для приватного репозиторія
cat ~/.ssh/github-cern-ibm5100.pub # Копіюємо вивід команди в налаштування репозиторія на гітхабі Settings -> Deploy keys
vim ~/.ssh/config # Налаштовуємо використання згенерованого ключа під ssh аліас
В файлі ssh конфігурації необхідно додати аліас який дозволить нам без зайвих команд використовувати саме цей ключ при роботі з цим репозиторієм
Host github-cern-ibm5100
Hostname github.com
IdentityFile /home/adam/.ssh/github-cern-ibm5100
Дані рядки означають що для хостнейму github-cern-ibm5100
, треба використоувати ключ
/home/adam/.ssh/github-cern-ibm5100
і переадресувати запити на github.com
.
Після цього ми можемо клонувати наш репозиторій командою
git clone git@github-cern-ibm5100:AltairInglorious/cern-ibm5100.git
Важливо в даному посилані використовувати github-cern-ibm5100
замість стандартного github.com
,
таким чином буде застосована наша конфігурація.
Налаштування проекту
Після клонування в поточній теці утвориться нова директорія з назвою cern-ibm5100
.
Перейшовши в неї ми можемо виконати всі необхідні налаштування як ось встановлення пакетів,
створення файлів конфігурації, застосування міграцій БД ітд. Дані кроки залежатимуть від
вашого проекту.
Підготовка PM2
Якщо у вас на сервері ще не встановлений PM2, ви можете це зробити виконавши команду
bun i -g pm2 # Встановлення PM2
pm2 startup # Налаштування автозапуску демону PM2 (ви отримаєте інструкцію, для вашого дистрибутиву)
Завершивши налаштування проекту ми можемо підготувати його до запуску в PM2.
Я надаю перевагу декларативному методу запуску через файл ecosystem.config.(c)js
.
Для його створення варто виконати команду
pm2 init simple
Після цього у вас з’явиться новий файл з налаштуваннями. По своїй суті він аналогічний до docker-compose.yml
,
в ньому ви зможете налаштувати запуск ваших додатків (авторестарт, змінні оточення, логування ітд).
Більше детальніше про налаштування цього файлу ви можете
прочитати в документації.
Я наведу приклад цього файлу для запуску API на Bun та NextJS додатку з
монорепозиторію з двома теками api
та web
відповідно
module.exports = {
apps : [{
name : "api",
script : "index.ts",
interpreter: "/home/adam/.bun/bin/bun",
cwd: "./api",
time: true,
env: {
NODE_ENV: "production",
SHOW_REQ: "true",
PORT: 4000,
},
},{
name : "admin",
script : "./node_modules/next/dist/bin/next",
args: 'start',
cwd: "./web",
time: true,
env: {
NODE_ENV: 'production',
PORT: 4001,
NEXT_PUBLIC_API_ENDPOINT: 'https://example.com/api',
}
}]
}
Створивши даний файл ми можемо запустити наш проект виконавши
pm2 start ecosystem.config.js # Запуск нашого проекту
pm2 save # Збереження проекту в конфігу для автозапуску при старті серверу
В залежності від налаштувань свого проекту на TypeScript ви можете отримати помилку пов’язану з CommonJS.
Для її вирішення достатньо перейменувати ваш файл на ecosystem.config.cjs
.
Оновлення
Для оновлення нашого проекту ми можемо написати bash скрипт наступного вигляду
#!/bin/sh
# Оновлення репозиторію
git pull
# ...тут дії специфічні для вашого проекту, для прикладу
bun i -p --frozen-lockfile
# Перезапуск проекту
pm2 restart ecosystem.config.js
Звісно цей скрипт можна розширювати, ось приклад скрипту який дозволяє вибіркове оновлення монорепозиторного проекту
#!/bin/bash
for opt in $@
do
if [ "$opt" = "-h" ]; then
echo "-c Update core
-s Update web.shop
-a Update web.admin
-v Update web.vendor"
exit 0
fi
done
echo 'Updating repository...'
git pull
while getopts ":savc" opt; do
case ${opt} in
s)
echo 'Rebuilding web.shop...'
cd web.shop
bun i --frozen-lockfile
bun run build
cd ..
;;
a)
echo 'Rebuilding web.admin...'
cd web.admin
bun i --frozen-lockfile
bun run build
cd ..
;;
v)
echo 'Rebuilding web.vendor...'
cd web.vendor
bun i --frozen-lockfile
bun run build
cd ..
;;
c)
echo 'Update core...'
cd core
bun i --frozen-lockfile
cd ..
;;
?)
echo "Invalid option: -${OPTARG}."
;;
esac
done
echo 'Restarting services...'
pm2 restart ecosystem.config.js