15
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

CircleCIでmix testする、Gigalixirへデプロイする(Elixir/Phoenix)

Last updated at Posted at 2020-12-07

この記事はElixir その2 Advent Calendar 2020 8日目です。
前日は、WindowsでIExで日本語を使う(iex --werl) (Elixir) でした。

はじめに

  • Phoenixプロジェクトで、CircleCIを使ってみました
  • アカウント登録とかGitHubBitbucketリポジトリとの連携はなんとな〜くやればできます
  • mix testが自動で行われるようにします
  • ついでにGigalixirへのデプロイも行います
  • プロジェクトのルートに.circleci/config.ymlを置きます

スクリーンショット 2020-12-07 20.02.43.png

.circleci/config.yml

.circleci/config.yml
version: 2
jobs:
  build:
    parallelism: 1
    docker:
      - image: circleci/elixir:1.10.4
        environment:
          MIX_ENV: test
      - image: circleci/postgres:10.1-alpine
        environment:
          POSTGRES_USER: postgres
          POSTGRES_DB: my_app_test
          POSTGRES_PASSWORD: postgres

    working_directory: ~/app

    steps:
      - checkout

      - run: mix local.hex --force
      - run: mix local.rebar --force

      - restore_cache:
          keys:
            - v1-mix-cache-{{ .Branch }}-{{ checksum "mix.lock" }}
            - v1-mix-cache-{{ .Branch }}
            - v1-mix-cache
      - restore_cache:
          keys:
            - v1-build-cache-{{ .Branch }}
            - v1-build-cache
      - run: mix do deps.get, compile
      - save_cache:
          key: v1-mix-cache-{{ .Branch }}-{{ checksum "mix.lock" }}
          paths: "deps"
      - save_cache:
          key: v1-mix-cache-{{ .Branch }}
          paths: "deps"
      - save_cache:
          key: v1-mix-cache
          paths: "deps"
      - save_cache:
          key: v1-build-cache-{{ .Branch }}
          paths: "_build"
      - save_cache:
          key: v1-build-cache
          paths: "_build"

      - run:
          name: Wait for DB
          command: dockerize -wait tcp://localhost:5432 -timeout 1m

      - run: mix test

      - store_test_results:
          path: _build/test/lib/my_app

  deploy:
    docker:
      - image: circleci/elixir:1.10.4
    steps:
      - add_ssh_keys
      - checkout
      - run: sudo apt-get update
      - run: sudo apt-get install -y python-pip
      - run: sudo pip install gigalixir --ignore-installed six
      - run:
          name: my_app
          command: |
            echo 'export SUFFIX=$(echo $CIRCLE_BRANCH | tr "[:upper:]" "[:lower:]" | tr -cd "[a-z0-9-]")' >> $BASH_ENV
            echo 'export APP_NAME="$GIGALIXIR_APP_NAME-$SUFFIX"' >> $BASH_ENV
            source $BASH_ENV
      - run: gigalixir login -e "$GIGALIXIR_EMAIL" -p "$GIGALIXIR_PASSWORD" -y
      - run: gigalixir git:remote $GIGALIXIR_APP_NAME
      - run: git push -f gigalixir HEAD:refs/heads/main

      - run: printf "Host *\n StrictHostKeyChecking no" > ~/.ssh/config
      - run: gigalixir ps:migrate

workflows:
  version: 2
  deploy:
    jobs:
      - build
      - deploy:
          requires:
            - build
          filters:
            branches:
              only: main

プロジェクト固有の設定

mix release

  1. config/prod.secret.exsconfig/releases.exsにリネーム
  2. config/releases.exsの先頭のほうにあるuse Mix.Configimport Configに書き換える
  3. config/prod.exsの中でimport_config "prod.secret.exs"を呼び出しているところはもはやいらないので消す
  4. config/releases.exsに、config :my_app, MyAppWeb.Endpoint, server: trueを足す
  5. config/prod.exsurl:のところを変更する
  6. lib/my_app/release.exをつくる
config/prod.exs
@@ -10,7 +10,7 @@ use Mix.Config
 # which you should run after static files are built and
 # before starting your production server.
 config :yubaba, YubabaWeb.Endpoint,
-  url: [host: "example.com", port: 80],
+  url: [host: "gigalixir-app-name.gigalixirapp.com", port: 443],
   cache_static_manifest: "priv/static/cache_manifest.json"

 # Finally import the config/prod.secret.exs which loads secrets
 # and configuration from environment variables.
-import_config "prod.secret.exs"
+# import_config "prod.secret.exs"
  • gigalixir-app-name.gigalixirapp.comは適宜読み替えてください
lib/my_app/release.ex
defmodule MyApp.Release do
  @app :my_app

  def migrate do
    load_app()

    for repo <- repos() do
      {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true))
    end
  end

  def rollback(repo, version) do
    load_app()
    {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :down, to: version))
  end

  defp repos do
    Application.fetch_env!(@app, :ecto_repos)
  end

  defp load_app do
    Application.load(@app)
  end
end
  • MyApp:my_appは適宜読み替えてください

CircleCI

  • プロジェクトの設定で設定します

Environment Variables

  • GIGALIXIR_APP_NAME
    • gigalixir appsして、unique_nameを指定します
  • GIGALIXIR_EMAIL
  • GIGALIXIR_PASSWORD
    • Gigalixirのログインパスワードです
    • Circle CIのコンテナからGigalixirにログインするために教えてあげます

SSH Key

  • 秘密鍵
    • passphraseは空2
  • Hostnameは空

たとえば

cd ~/.ssh
ssh-keygen -b 4096 -f gigalixir

で作った場合、~/.ssh/gigalixir の中身を登録します。
CircleCIのコンテナからGigalixirのアプリコンテナへデプロイをしますので、CircleCIが秘密鍵を知っておく必要があるというわけです。

Gigalixir

Wrapping Up :lgtm: :santa: :santa_tone1: :santa_tone2: :santa_tone3: :santa_tone4: :santa_tone5: :lgtm:

  1. masterブランチではなく、mainブランチにしています 2

  2. メモ: SSH 鍵を作成する際は必ず空のパスワードを設定してください。 CircleCI ではパスワードを使った SSH 鍵の復号はできません。

15
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?