Деплой приложения Nuxt с SSR на Amazom EC2
Ходят легенды, что раньше фронтендеры писали код сугубо для браузеров. Да, им тогда приходилось устанавливать Node.js для бандла и тестирования (а еще скачивать чужой код с помощью npm), но свои обязанности эти ребята знали хорошо. Но в наше время творится безумное...
Товарищи фронтендеры сорвались в цепи и теперь пытаются отвоевать земли бескрайнего и щедрого на ресурсы Сервера. Next, Nuxt, серверный рендеринг, серверные компоненты, статический генератор. Все больше и больше приходится слушать это традиционным разработчикам и недоумевать от современных трендов.
Прошли времена, когда рядовому фронтендеру нужно было собрать коробку и отдать его специальному человеку, чтобы он с помощью веб-сервера раздавал его файлы. Теперь для работы многих современных фронтенд приложений нужен постоянно работающий демон, которого зовут Node. Этот демон будет отправлять запросы, рендерить HTML и даже работать API на стороне Сервера. Именно таким образом работают приложения на Nuxt и Next (Биба и Боба), как и вообще любое приложение с SSR (server-side rendering). В этом плане, деплой таких приложений не будет кардинально отличаться от развертки бэкенд-приложения на Node.js. Приступаем!
Для развертки подойдет любой нестыдный облачный VPS на рынке, но в моем случае это именно Amazon EC2. Перед тем как смотреть дальше у вас уже должен быть создан инстанс(так называются виртуальные сервера EC2), с настроенным Elastic IP и доступными способами подключения (по SSH, HTTP, HTTPS). Удостоверьтесь, что у вас совпадает с тем, что на скриншоте.
Security group
Elastic IP
Подключаемся через SSH к EC2 инстансу и сразу устанавливаем Node(через NVM!), PM2 и NGINX. Краткий ликбез по предназначению и установке каждого из них.
NVM - node version manager. По названию понятно, что это менеджер, который позволяет управлять версиями Node. Советуется устанавливать Node именно через NVM.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
source .bashrc
nvm install --lts
// вместо --lts можете написать нужную версию PM2 - менеджер процессов написанный на Node.js. Он позволяет управлять приложениями и на Node, Python, Ruby и т.д. Он нужен нам, чтобы создать демона и "забыть" о нем. Но часто нам приходится обновлять или восстанавливать процессы, иногда на нескольких серверах. Для таких случаев мы установим PM2 локально и создадим ecosystem.config.js файл для того, чтобы удаленно управлять процессами.
// пропишите эту команду и на инстансе, и локально на своей машине
npm i -g pm2Далее создайте файл "ecosystem.config.js" в корне своего проекта.
pm2 ecosystemИ в самом файле прописываем
module.exports = {
apps: [
{
script: "команда, которая запускает ваше nuxt приложение",
},
],
deploy: {
production: {
key: "ключ для подключения к EC2 инстансу",
user: "root юзер в вашем инстансе",
host: "название хоста вашего инстанса",
ref: "основная ветка вашего репозитория",
repo: "ваш репозиторий по ssh",
path: "путь куда клонировать ваш проект в вашем инстансе",
"pre-deploy-local": "",
"post-deploy":
"source ~/.nvm/nvm.sh && pnpm install && yarn build && pm2 reload ecosystem.config.js --env production",
"pre-setup": "",
ssh_options: "ForwardAgent=yes",
},
},
};
// post-deploy может отличаться в зависимости, какие пакетные менеджеры вы используете и так далее.Теперь делаем переадресацию ssh агента. Это позволит использовать ваш локальный SSH-ключ для Github(или GitLab) на инстансе EC2.
vim ~/.ssh/configИ прописываем
Host [название хоста вашего EC2 инстанса]
ForwardAgent yesДобавляем ключи к агенту
ssh-addТеперь нужно подключиться к инстансу по SSH. На самом сервере подключаемся к Github.
ssh -T git@github.comПривязываем SSH ключ вашего инстанса к вашему репозиторию. Сгенерируйте ключ и вставьте его в настройках вашего репозитория в разделе Deploy Key.
Наконец, мы можем удаленно задеплоить с помощью PM2. Пропишете эти команды в корне вашего проекта.
pm2 deploy production setup
pm2 deploy productionНастраиваем NGINX
В моем случае стоит дистрибьютив Amazon Linux 2 со встроенным пакетным менеджером YUM. Если вы выбрали Ubuntu, то вы устанавливаете через APT.
sudo yum update
sudo yum install -y nginx
sudo service nginx restartКонфигурируем виртуальный хост для домена.
sudo vim /etc/nginx/sites-available/домен вашего сайтаШаблон конфигурации.
server {
listen 80;
# Your domain
server_name домен вашего сайта;
# Proxy to nuxt renderer.
location / {
proxy_pass http://localhost:порт приложения;
}
# Redirect from /path/ to /path
rewrite ^/(.*)/$ /$1 permanent;
}
# Redirect domain aliases
server {
server_name www.домен вашего сайта;
return 301 https://$host$request_uri;
}Создаем символическую символку в "sites-enabled".
sudo ln -s /etc/nginx/sites-available/домен вашего сайта /etc/nginx/sites-enabled/Чтобы удостовериться, что с вашими конфигурациями все в порядке прописываем.
sudo nginx -tДолжны получить примерно такое сообщение.
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successfulПерезапускаем NGINX.
sudo systemctl reload nginxНастройка домена
Этот этап у каждого может быть разным. Но основные шаги выглядят следующим образом образом.
1.) Регистрируете доменное имя в DNS
2.) Обновляете DNS записи в вашем DNS провайдере. Доменное имя вашего сайта должен перенаправлять на Elastic IP вашего инстанса. А доменное имя с WWW на доменное имя вашего сайта.
3.) Следует ждать, пока все это заработает (обычно не больше дня). Пока можно полазить по настройкам вашего DNS провайдера. Например выберите способ SSL/TLS шифрования для вашего сайта.
Ставим SSL сертификат
Первым делом установите certbot на ваш инстанс. Этот шаг был для меня нетипичным из-за дистрибьютива, но если вы используете APT, то для вас все должно быть легко.
Прописываете эту команду.
sudo certbot --nginx -d ваше доменное имя -d ваше доменное имяДалее certbot будет спрашивать вашу почту и то, как конфигурировать подключение по HTTPS. Нажимаете на 1 или 2 по вашему предпочтению. В конце должно выйти сообщение о том, что вы получили нужные сертификаты.
Пришло время для самого волнительного момента. Вы пишите в адресной строке доменное имя вашего сайта и видите, что у вас все получилось 😋.