Особенности деплоя assets в Rails (5.2, 6+) при помощи Capistrano
Всем привет!
Сегодня попробую опубликовать свою первую техническую мини-статью на тему деплоя рельсовых приложений при помощи Capistrano. Пишу её в том числе и для себя, так как неоднократно сталкиваюсь с подобными проблемами при деплое своих проектов. Я убил несколько дней, собрал все возможные ошибки и точно знаю, что самая частая из них — это проблема компиляции ассетов.
На эту тему есть достаточно много гайдов и туториалов:
Один из таких туториалов, который я настоятельно рекомендую для новичков:
https://gorails.com/deploy/ubuntu/18.04
Но даже если вы будете ему следовать, с высокой долей вероятности у вас будут возникать ошибки, которые никем не документированы.
На одну из таких ошибок напоролся и я, когда настраивал капистрано для шестых рельс (А впервые я столкнулся с этой особенностью на рельсах 5.2. На версии 5.1, деплой проходит без проблем).
Проблема с компиляцией ассетов
Я столкнулся с тем, что у меня постоянно падал таск прекомпиляции ассетов: assets:precompile
Проблема заключалась в том, что капистрано падал с ошибкой: Status error code: 1, а в самом сообщении ничего отображалось (Nothing written). То есть капистрано просто отказывался работать дальше, но причину своего отказа не сообщал.
Как оказалось, эта проблема может быть вызвана одной из двух причин:
- Отсутствие необходимых библиотек и пакетов на сервере.
- Недостаточно ресурсов у VPS, в особенности оперативной памяти.
А вот теперь подробнее о каждой причине и что нужно сделать.
Отсутствие необходимых библиотек и пакетов на сервере.
Для компиляции ассетов на сервере, вам необходимо убедиться, что у вас установлен NodeJS, а начиная с версии 5.2 (и если у вас установлен gem ’webpacker’), то и Yarn
Проверить, что у вас установлены оба пакета на сервере:
node -v
yarn -v
Рекомендую ставить nodejs не ниже v8.16.0 (а ещё лучше 12 и выше). Если не знаете, какую версию чего ставить, посмотрите, какие версии пакетов у вас установлены локально.
Чтобы установить оба пакета, введите следующие команды на сервере:
Сначала NodeJS
curl -sL https://deb.nodesource.com/setup_12.x -o nodesource_setup.sh
nano nodesource_setup.sh
sudo bash nodesource_setup.sh
sudo apt install nodejs
Затем Yarn
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update && sudo apt install yarn
sudo apt update && sudo apt install --no-install-recommends yarn
После установки также проверьте версии пакетов, что всё установлено корректно.
Обратите внимание на другие гемы и библиотеки, с которыми вы работаете. Некоторые из них требуют свои зависимости. Например: в одном из моих проектов есть гем ’mini_magick’, для корректной работы которого требуется установка библиотеки ImageMagick.
По идее этого должно хватить для корректной компиляции ассетов, но в процессе работы я собрал ещё парочку ошибок, о которых также хочу упомянуть)
Если видите, что капистрано ругается на nodejs или yarn, скорее всего, вам нужно обновить текущую версию одного или обоих пакетов и затем снова перезапустить деплой, командой: cap production deploy.
Другая ошибка связана с ExecJS Runtime. Это ошибка интересней и связана с тем, что у JavaScript есть разные стандарты. Чтобы их корректно различать, вам нужно подключить интерпретатор. Чтобы починить этот баг, вам нужно добавить в Gemfile и сделать bundle следующий гем:
gem "therubyracer"
Недостаточно ресурсов у VPS, в особенности оперативной памяти
А вот эта причина уже интереснее! И когда я на неё наткнулся в версии рельс 5.2, то убил целый день на поиск решения проблемы.
Оказывается мои ассеты не компилировались из-за малого количества ресурсов.
Дело в том, что все свои приложения я размещаю на каплях (droplets) DigitalOcean и беру самый дешевый тариф с 1Гб оперативной памяти.
При компиляции ассетов «отжирается» практически вся память, из-за чего капистрано валится с неизвестной ошибкой.
Чтобы починить это, у вас есть два варианта: купить VPS с большим количеством ресурсов, либо создать файл подкачки (swap).
Суть файла подкачки в том, что в случае если ресурсы оперативной памяти заканчиваются, текущий процесс мог бы использовать мощности жесткого диска. Да, он не такой быстрый как оперативка, но для нашей цели подходит.
Однако, по-умолчанию, на сервере от DigitalOcean, эта возможность отсутствует. Файл подкачки нужно создать.
Создаем файл-подкачки (SWAP) на сервере
Я не буду расписывать то, что и так можно найти в интернете, просто дам ссылку на digital ocean, где достаточно подробно и на русском языке описан весь этот процесс: https://www.digitalocean.com/community/tutorials/how-to-add-swap-space-on-ubuntu-18-04-ru
Для решения проблемы с ассетами, вам нужно пройти с 1 по 5 шаг.
Надеюсь после этой статьи вы закроете проблему с компиляцией ассетов раз и навсегда)
Для себя, кстати, я решил, что следующий проект буду деплоить при помощи CI, используя Docker. Я несколько дней потратил на то, чтобы подружить весь свой технический «зверинец» друг с другом и заставить их работать вместе. И, честно сказать, задолбался.
PS Поменьше вам ошибок и по-больше счастья при деплое ваших приложений! Аминь.