Введение в развёртывание
Исходный кодКогда наше приложение готово к работе, можно приступать к его развёртыванию. Если ваше приложение ещё не совсем готово, не беспокойтесь. Просто следуйте руководству по созданию и запуску приложения, чтобы создать базовое приложение для работы.
При подготовке приложения к развёртыванию есть три основных шага:
- Обработка секретов приложения
- Компиляция ресурсов приложения
- Запуск сервера в production-среде
В этом руководстве мы узнаем, как локально запустить production-среду. Вы можете использовать описанные здесь методы для запуска приложения в production-среде, но в зависимости от инфраструктуры развёртывания потребуются дополнительные шаги.
В качестве примеров развёртывания в других инфраструктурах в наших руководствах рассматриваются четыре подхода: использование релизов Elixir с mix release, использование Gigalixir, использование Fly и использование Heroku. Мы также добавили ссылки на руководства сообщества по развёртыванию Phoenix на других платформах в разделе Руководства сообщества по развёртыванию. Наконец, в руководстве по релизам есть пример Dockerfile, который можно использовать, если вы предпочитаете развёртывание с помощью контейнерных технологий.
Давайте рассмотрим перечисленные выше шаги по порядку.
Обработка секретов приложения
Во всех приложениях Phoenix есть данные, которые нужно хранить в безопасности, например имя пользователя и пароль для production-базы данных, а также секрет, который Phoenix использует для подписи и шифрования важной информации. Обычно такие данные хранят в переменных среды и загружают в приложение. Это делается в config/runtime.exs (ранее config/prod.secret.exs или config/releases.exs), который отвечает за загрузку секретов и конфигурации из переменных среды при запуске.
Поэтому убедитесь, что в production-среде заданы все необходимые переменные:
$ mix phx.gen.secret REALLY_LONG_SECRET $ export SECRET_KEY_BASE=REALLY_LONG_SECRET $ export DATABASE_URL=ecto://USER:PASS@HOST/database
Не копируйте эти значения напрямую: задайте SECRET_KEY_BASE в соответствии с результатом выполнения mix phx.gen.secret, а DATABASE_URL — в соответствии с адресом вашей базы данных.
Если по какой-либо причине вы не хотите использовать переменные среды, можно указать секреты в коде в файле config/runtime.exs, но обязательно исключите этот файл из системы контроля версий.
Теперь, когда секретная информация надёжно защищена, можно настроить ресурсы!
Перед этим шагом нужно выполнить небольшую подготовку. Поскольку мы готовим всё для production-среды, в ней нужно установить зависимости и выполнить компиляцию.
$ mix deps.get --only prod $ MIX_ENV=prod mix compile
Компиляция ресурсов приложения
Этот шаг требуется только в том случае, если у вас есть ресурсы, которые нужно компилировать, например JavaScript и таблицы стилей. По умолчанию Phoenix использует esbuild, но всё заключено в одну задачу mix assets.deploy, определённую в файле mix.exs:
$ MIX_ENV=prod mix assets.deploy Check your digested files at "priv/static".
Вот и всё! По умолчанию задача Mix собирает ресурсы, а затем создаёт дайджесты и файл манифеста кэша, чтобы Phoenix мог быстро отдавать ресурсы в production-среде.
Примечание: если выполнить задачу выше на локальном компьютере, в
priv/staticпоявится множество ресурсов с дайджестами. Удалить лишние можно с помощью командыmix phx.digest.clean --all.
Имейте в виду: если вы вдруг забудете выполнить описанные выше шаги, Phoenix покажет сообщение об ошибке:
$ PORT=4001 MIX_ENV=prod mix phx.server 10:50:18.732 [info] Running MyAppWeb.Endpoint with Cowboy on http://example.com 10:50:18.735 [error] Could not find static manifest at "my_app/_build/prod/lib/foo/priv/static/cache_manifest.json". Run "mix phx.digest" after building your static files or remove the configuration from "config/prod.exs".
Сообщение об ошибке вполне понятно: в нём говорится, что Phoenix не удалось найти статический манифест. Чтобы исправить это, выполните приведённые выше команды. Если вы не отдаёте ресурсы или они вам совсем не нужны, просто удалите конфигурацию cache_static_manifest из конфигурации приложения.
Запуск сервера в production-среде
Чтобы запустить Phoenix в production-среде, при вызове mix phx.server нужно задать переменные среды PORT и MIX_ENV:
$ PORT=4001 MIX_ENV=prod mix phx.server 10:59:19.136 [info] Running MyAppWeb.Endpoint with Cowboy on http://example.com
Чтобы запустить сервер в отсоединённом режиме, при котором сервер Phoenix не остановится и продолжит работу даже после закрытия терминала:
$ PORT=4001 MIX_ENV=prod elixir --erl "-detached" -S mix phx.server
Если появится сообщение об ошибке, внимательно прочитайте его и создайте отчёт об ошибке, если способ её устранения всё ещё неясен.
Также можно запустить приложение в интерактивной оболочке:
$ PORT=4001 MIX_ENV=prod iex -S mix phx.server 10:59:19.136 [info] Running MyAppWeb.Endpoint with Cowboy on http://example.com
Собираем всё вместе
В предыдущих разделах описаны основные шаги, необходимые для развёртывания приложения Phoenix. На практике вам также придётся добавить собственные шаги. Например, если вы используете базу данных, перед запуском сервера нужно выполнить mix ecto.migrate, чтобы убедиться, что схема базы данных актуальна.
Ниже приведён скрипт, который можно использовать в качестве отправной точки:
# Initial setup $ mix deps.get --only prod $ MIX_ENV=prod mix compile # Compile assets $ MIX_ENV=prod mix assets.deploy # Custom tasks (like DB migrations) $ MIX_ENV=prod mix ecto.migrate # Finally run the server $ PORT=4001 MIX_ENV=prod mix phx.server
Вот и всё. Теперь можно воспользоваться одним из наших официальных руководств по развёртыванию:
- с помощью релизов Elixir
- на Gigalixir — платформе Elixir как услуге (PaaS)
- на Fly.io — платформе PaaS, которая развёртывает серверы ближе к пользователям и поддерживает встроенную распределённую работу
- и на Heroku — одной из самых популярных платформ PaaS.
Кластеризация и транспорт с длительным опросом
Phoenix поддерживает два типа транспорта для реализации сокетов: WebSocket и длительный опрос (Long-Polling). При создании проекта Phoenix в сгенерированном файле endpoint.ex можно увидеть конфигурацию по умолчанию:
socket "/live", Phoenix.LiveView.Socket, websocket: [connect_info: [session: @session_options]], longpoll: [connect_info: [session: @session_options]]
Эта конфигурация указывает Phoenix, что доступны оба варианта — WebSocket и длительный опрос. В зависимости от состояния сети клиента Phoenix сначала попытается подключиться через WebSocket, а по истечении заданного тайм-аута переключится на длительный опрос. Тайм-аут указан в сгенерированном файле app.js:
let liveSocket = new LiveSocket("/live", Socket, {
longPollFallbackMs: 2500,
params: {_csrf_token: csrfToken}
})
Если в production-среде запущено несколько машин, что в большинстве случаев является рекомендуемым подходом, у такого автоматического переключения есть важный нюанс. Чтобы длительный опрос работал корректно, приложение должно:
Использовать возможности кластеризации виртуальной машины Erlang, чтобы адаптер
Phoenix.PubSubпо умолчанию мог передавать сообщения между узламиВыбрать другой адаптер
Phoenix.PubSub(например,Phoenix.PubSub.Redis)Или использовать вариант развёртывания с привязкой сеансов, чтобы все запросы для определённого сеанса направлялись на одну и ту же машину
Причина проста. WebSocket — это длительное открытое соединение с одной и той же машиной, а длительный опрос работает так: клиент отправляет запрос на сервер и ждёт истечения тайм-аута или выполнения открытого запроса, после чего повторяет этот процесс. Чтобы сохранять состояние подключённого сокета пользователя и поддерживать длительное соединение, процесс пользователя остаётся активным, а каждый запрос длительного опроса пытается найти процесс с состоянием пользователя. Если этот процесс недоступен, каждый запрос будет создавать новый процесс и новое состояние, нарушая тем самым длительный характер соединения и сохранение его состояния.
Руководства сообщества по развёртыванию
- Render обеспечивает полноценную поддержку приложений Phoenix. Доступны руководства по размещению Phoenix с помощью релизов Mix и в виде распределённого кластера Elixir.
- Railway также поддерживает приложения Phoenix с помощью релизов Mix.
© 2014 Chris McCord
Licensed under the MIT License.
https://phoenix.hexdocs.pm/deployment.html