1 of 17

elixir on docker

2022-01-30 tokyo.ex #15 hands-on

2 of 17

agenda

  • About Me
  • ゴール
  • docker/docker-compose
  • why docker?
  • dockerの構造
  • docker-composeの構造
  • elixir/phoenixアプリへの適用
  • CIとは
  • CIへの組み込み方(CircleCI)
  • .circleci/config
  • まとめ

3 of 17

About Me

  • おーはら / Twitter: @ohrdev / Github: ohr486
  • 株式会社ドリコム SRE部 部長
    • Work:
      • エンジニアマネージャ
        • 技術戦略の策定/推進
        • エンジニア採用/採用戦略策定
      • サーバー/インフラエンジニア
        • 開発現場でゲームのバックエンド(Rails/Phoenix/Go/HCL)のコード書いてます
      • 新規事業/ディレクター
        • 負荷試験支援/DevOps推進支援/設計コンサル
  • Community
    • tokyo.ex / Japan Elixir Association / Erlang&Elixir Fest
  • Hobby
    • 仏像制作
    • 自転車

4 of 17

ゴール

  • ターゲット
    • docker/docker-composeの概要を理解したい人
    • elixir/phxアプリをdocker上で開発したい人
  • 今日のゴール
    • elixir/phxアプリをdocker上で動かす手順を理解する
  • 話さない事
    • docker, docker-composeのコマンド/オプションの解説
    • Dockerfile, docker-compose.ymlの詳細な説明

5 of 17

docker/docker-compose

  • docker とは?
    • コンテナのアプリ実行環境を管理するツール
    • Dockerfileでコンテナの構成を定義

  • docker-compose とは?
    • 複数のコンテナから構成されるサービスを構築・実行するための管理ツール
    • docker-compose.ymlでコンテナ群の構成を定義

6 of 17

why docker?

  • 例) dockerなしでelixirの開発環境をローカルマシンに構築する場合
    • elixir, erlangをインストール
    • nodejsをインストール(phoenixの場合)
    • DB(mysql, redis, memcached等のミドルウェアをインストール)
    • インストールしたミドルウェアの設定ファイルを作成
    • ミドルウェアを起動
      • mysqld start, etc
    • iex -s mix, mix phx.server 等で起動
    • 開発マシンのOS,言語,ミドルウェアのバージョンによって動作環境が異なる場合がある

  • 例) dockerありでelixirの開発環境をローカルマシンに構築する場合
    • docker, docker-composeをインストール
    • dockerfile, docker-compose.ymlを記述 (テキストファイルなのでgitで管理可能)
    • docker-compose upで起動
    • 言語/ミドルウェアのバージョンはdockerイメージを変更するだけで良い(再インストール不要)
    • 開発マシンの環境によらず、(docker上で動作するのであれば)動作は保証される

7 of 17

why docker?

  • (本番環境をkubernetesやECSで運用する場合、本番の)実行環境を開発環境と同じにできる
    • 例) 本番環境とローカル環境のミドルウェアや言語、OSのバージョンの違いで動作結果に差異がでる、環境依存のバグが発生する
      • フレームワークや言語のバージョン変更/アップグレード時の障害など

  • 開発者の開発環境による差分をなくせる
    • 例) 開発者がMacを使っていようがLinuxを使っていようが、(ほぼ)同じ条件・環境で開発を行うことができる

  • 環境構築が簡単
    • 例) 必要なミドルウェアや言語をインストールする必要がない、docker-composeのコマンドだけでセットアップできる

8 of 17

dockerの構造/Dockerfileの構成

FROM イメージ名

WORKDIR 作業ディレクトリのパス

RUN イメージ作成時に実行するコマンド

CMD コンテナ起動時に実行するコマンド

ENTRYPOINT コンテナ起動時に実行するコマンド

9 of 17

dockerの構造

docker registory

(dockerhub)

開発マシン

/path/to/work

Dockerfile

FROM

コンテナ runtime (docker)

コンテナ

マシン上のイメージ領域

image1

layer1

layer2

tag

docker build

docker images

image2

docker pull

docker ps

docker run

docker create

docker start

docker xxx

docker inspect

File

Process

10 of 17

docker-composeの構造/docker-compose.ymlの構成

version: ‘3’

services:

サービス名:

build or image: Dockerイメージ名 or Dockerfileのパス

command: コンテナ起動時に実行するコマンド

environment:

環境変数名: 環境変数の値

ports:

- ホスト側の通信ポート:コンテナ側の通信ポート

depends_on:

- コンテナ開始前に開始させるサービス名

volumes:

- ホスト側のパス or ボリューム名:コンテナ側のパス

サービス名:

volumes:

volume:

11 of 17

docker-composeの構造

開発マシン

コンテナ runtime (docker)

コンテナimage領域

コンテナvolume領域

/path/to/work

docker-compose.yml

サービス名:

demo_app

サービス名:

demo_db

volume2

image1

image2

/path/to/work/volume1

mount

mount

create

create

コンテナ間はサービス名(demo_app, demo_db)で通信可能

コンテナの構成を定義

portsで指定したportで該当のコンテナに通信可能

docker compose build

docker compose up/down

docker compose exec/run [cmd]

12 of 17

elixir/phoenixアプリへの適用

  • elixir/phxアプリの起動までの一般的な流れ
    • Dockerfileを作成
    • docker-compose.ymlを作成
    • docker compose build でコンテナイメージ、ボリューム、ネットワークを作成
    • docker compose run [mix phx.new …] でアプリの雛形を作成
    • config/*.exs をdocker環境に合わせて修正
      • アプリ/DBのhost,portなど
      • DBの設定(user,passなど)
    • docker compose run [mix ecto.create] でDBをcreate
    • docker compose up -d でコンテナを起動
    • docker compose logs -f でログ(標準出力)を表示
    • localhost:4000 をブラウザで参照してwebアプリの画面を確認
  • elixir/phxアプリの停止方法
    • docker compose down

13 of 17

elixir/phoenixアプリへの適用

開発マシン

コンテナ runtime (docker)

コンテナvolume領域

/path/to/work

docker-compose.yml

app

db

node_modules

db_data

/app/assets/node_modules

/var/lib/postgresql/data

/app

mount

mount

5432 : 5432

4000 : 4000

Dockerfile

WORKDIR /app

docker compose build

docker compose run --rm app mix phx.new …

docker compose run --rm app mix ecto.create

docker compose up -d

docker compose logs -f

docker compose down

localhost:4000 でappに通信

host=dbで通信

14 of 17

CIとは

  • CIとは?
    • Continuous Integrationの略で、継続的インテグレーション
    • ソフトウェア開発における品質管理の手法
    • コンパイル、テスト、デプロイなどの開発サイクルを頻繁/高速に繰り返し実行してバグ/問題の早期発見や開発の効率化を行う手法
  • CIツール
    • CIを高速に回す為に、一般的に以下の様なツールを利用する
    • ※ 本トーク/ハンズオンではCIrcleCIを利用します

15 of 17

CIへの組み込み方(CircleCI)

  • CircleCIを利用してCIのパイプラインを作成する手順
    • githubのリポジトリを作成
    • .circleci/config.yml ファイルを作成
    • 作成したアプリ(ファイル)をリポジトリにpush(ブランチはmainとしておく)
    • circleciにgithubでログイン(Log In with GitHub)
      • https://circleci.com/ja/
    • circleciのプロジェクトページを開く
      • https://app.circleci.com/projects/
      • Organization, Project(作成したリポジトリ)を指定
      • [Select a config.yml file] で [If you already have .circleci/config.yml in your repo]を指定
      • pushしたブランチ(main)を指定
      • [Set Up Project]を指定
    • circleciのdashboardが表示される
      • configがvalidならpush毎にpipelineが実行される

16 of 17

.circleci/config

version: ‘3’

jobs:

build:

docker:

- image: circleci/elixir:1.13-node

environment:

MIX_ENV: test

MIX_TEST_DB_HOST: localhost

- image: circleci/postgres:9.6

environment:

POSTGRES_USER: postgres

POSTGRES_DB: demo_test

POSTGRES_PASSWORD: postgres

working_directory: ~/app

steps:

-checkout

-run: mix local.hex --force

-run: mix local.rebar --force

-run: mix archive.install --force hex phx_new

-run: mix do deps.get, compile

-run: mix test

CI pipelineを実行するコンテナ

→ elixir(+nodejs)とpostgres

CI pipelineのコンテナで実行するコマンド

→ mixをセットアップして、testを実行

config/test.exsを以下の様に設定して、DBのhostを環境変数MIX_TEST_DB_HOSTから取得するよう修正しておく

17 of 17

まとめ

  • docker/docker-composeの概要について紹介しました
  • elixir/phxアプリのdocker環境構築手順を紹介しました
  • CircleCIのセットアップ手順を紹介しました

  • 以上の情報を元にハンズオンで実際に環境を構築してみてください