Skip to content

Elixirデプロイメント完全ガイド

Elixirデプロイメント完全ガイド

Section titled “Elixirデプロイメント完全ガイド”

Elixirアプリケーションのデプロイメントを、実務で使える実装例とともに詳しく解説します。

Elixirアプリケーションは、mix releaseコマンドで生成される自己完結型リリースを使用してデプロイします。

デプロイメントの流れ
├─ リリースのビルド
├─ コンテナ化(Docker)
├─ デプロイ(Kubernetes/Render)
└─ 監視とログ
Terminal window
# リリースのビルド
MIX_ENV=prod mix release
# リリースの起動
_build/prod/rel/my_app/bin/my_app start
config/runtime.exs
import Config
config :my_app, MyAppWeb.Endpoint,
http: [port: System.get_env("PORT", "4000") |> String.to_integer()],
url: [host: System.get_env("HOST", "localhost")]
config :my_app, MyApp.Repo,
url: System.get_env("DATABASE_URL")

Elixirデプロイメントの基本思想

Section titled “Elixirデプロイメントの基本思想”

Elixirアプリケーションのデプロイメントの根幹には、mix releaseコマンドで生成される自己完結型リリースがあります。これは、アプリケーションのソースコード、依存ライブラリ、そして軽量なErlang VM (BEAM)をすべて一つの実行可能なファイルにまとめる機能です。このリリースの最大の利点は、デプロイ先のサーバーにElixirErlangを事前にインストールする必要がないことです。これにより、デプロイプロセスが劇的に簡素化され、DockerKubernetesのようなコンテナ環境との相性が非常に良くなります。

DockerKubernetesを使用したデプロイメント 🐳

Section titled “DockerとKubernetesを使用したデプロイメント 🐳”

自己完結型リリースをコンテナ化してデプロイするのは、最も一般的で堅牢な手法です。このプロセスは、通常、多段階ビルド (Multi-stage build) を使用して、本番用コンテナイメージのサイズを最小限に抑えます。

# ビルドステージ
# 完全なElixir環境を使ってリリースをビルド
FROM hexpm/elixir:1.14.3-erlang-25.3.2-ubuntu-jammy AS builder
WORKDIR /app
COPY mix.exs mix.lock ./
RUN mix deps.get --only prod
COPY priv priv
COPY lib lib
COPY config config
RUN mix release --env=prod
# ランタイムステージ
# わずか数MBの軽量なAlpineイメージに、ビルドしたリリースをコピー
FROM alpine:3.18.2
WORKDIR /app
RUN apk add --no-cache openssl
COPY --from=builder /app/_build/prod/rel/my_app ./
CMD ["/app/bin/my_app", "start"]

ビルドしたDockerイメージをKubernetesクラスタにデプロイするための設定例です。

apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
# Dockerイメージのリポジトリとタグを指定
image: your-docker-registry/my_app:latest
ports:
- containerPort: 4000

この設定により、Kubernetesはアプリケーションのコンテナを3つ起動し、自動的に負荷分散を行います。

Render.comでのデプロイメント 🚀

Section titled “Render.comでのデプロイメント 🚀”

Render.comのようなPaaSは、上記のDockerKubernetesの設定を気にすることなく、Elixirアプリケーションをデプロイできます。Renderは、Gitリポジトリと連携するだけで、自動的にビルドとデプロイを実行します。

Renderは、render.yamlという設定ファイルで、アプリケーションのビルドと起動方法を自動で認識します。

services:
- type: web
name: myapp
env: elixir
# ビルドコマンド。依存関係を取得し、リリースをビルド。
buildCommand: "mix do deps.get, compile, release"
# アプリケーションの起動コマンド
startCommand: "_build/prod/rel/my_app/bin/my_app start"
envVars:
- key: SECRET_KEY_BASE
generateValue: true

Renderは、Elixirの強みである分散ノード機能や自動スケーリングをネイティブにサポートしています。これにより、複数のインスタンスが互いに連携し、トラフィックの急増にも柔軟に対応できる、高可用性かつリアルタイムなアプリケーションを簡単に構築できます。

提供されたGitHub Actionsの例は、CI/CDプロセスを自動化するための良い出発点です。これをさらに洗練させ、デプロイフックを使用して自動デプロイを実現するワークフローの例を以下に示します。

GitHub Actionsワークフローの例 (.github/workflows/ci.yml)

Section titled “GitHub Actionsワークフローの例 (.github/workflows/ci.yml)”
name: Elixir CI/CD
on:
push:
branches:
- main
jobs:
build_and_deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Elixir
uses: erlef/setup-elixir@v1
with:
elixir-version: '1.14'
otp-version: '25'
- name: Install dependencies
run: mix deps.get
- name: Run tests
run: mix test
- name: Build release
# プロダクション環境用の設定でリリースをビルド
run: mix release --env=prod
- name: Deploy to Render
# テストとビルドが成功した場合にのみ実行
if: success()
run: curl -X POST ${{ secrets.RENDER_DEPLOY_HOOK }}

このワークフローは、mainブランチへのプッシュをトリガーに、テストを実行し、リリースをビルドします。すべてのステップが成功した場合にのみ、curlコマンドでRenderのデプロイフックを呼び出し、デプロイプロセスを自動で開始します。これにより、「テストが通ったときだけデプロイする」という安全で堅牢なパイプラインが構築できます。