🕌

デプロイについてまったく知らないのでAzureを使ってDocker+Railsのデプロイに奮闘した話

2021/05/05に公開約10,200字1件のコメント

はじめに

こんにちは
Watanabe Jin (@Sicut_study)です。

私は新卒で入社して今年で2年目のMLエンジニア?です。普段は自然言語処理の研究開発のお仕事をしています。

普段は本番環境を作るという仕事がなく(あっても先輩がやっていたため)、デプロイをするという経験がありませんでした。

しかし、とある案件でデプロイを自分でする必要が出てきたため、GWでデプロイという言葉くらいしかわからない状態からできるようになろうと奮闘しましたので、やったことや手順などをまとめたいと思います。

今回はRailsの環境構築をしただけのリポジトリをAzureを利用してデプロイしていきたいと思います。

利用するサービスは

  • リソースグループ
  • Azure Container Instances
  • Azure Container Registry
  • Azure ストレージアカウント

です。主にサーバーレスでデプロイしていきたいと思います。

最終的には3000番にアクセスして、この画面が表示されれば成功です。

なぜAzureを使うかというと、Azureを使ってデプロイすることが仕事で決まっているからです。何も知らなかったので、一から調べ始めましたが、思ったよりも記事がまとまっていないなと感じたので、いまできるようになったところまでをまとめていきます。

環境

使用リポジトリ
VScode (terminal: powershell)
Docker

1. Azureのアカウントを作成する

こちらで作成してください。
初めてでお金がかかることや、他の方で忘れていて多くの請求が来たという話がありすこし怖かったですが、2万円分は無料で利用できるので問題ないかと思われます。利用したあとに消せば問題ありません。

2. Azure CLIのダウンロード

Azure CLIをダウンロードすることで、このあと登場するazコマンドが利用できるようになります。

3. リポジトリのダウンロード

Rails + MySQLの環境構築のみで、localhost:3000にアクセスすると「Yay! You're on Rails!」が表示されるだけのアプリです。

# リポジトリのダウンロード
git clone https://github.com/jinwatanabe/rails5_MySQL.git
# リポジトリのディレクトリに移動
cd rails5_MySQL

手順についての大まかな流れ

a. Azure Container Instances (ACI)テキストを作成する

b. Azure Container Registryを作成してdockerイメージを登録する
docker-compose.ymlはrailsを起動するのにbuildでDockerfileを使って起動していますが、ローカルのファイルは読み込めないため、Dockerfileをイメージにしてから、Docker Container Registryに保存しておくことで、buildをせず、保存したimageを使ってcompose upします。

c. ストレージアカウントを作成する
docker-compose.ymlでボリュームをローカルを指定しているので、そこを作成したストレージに変更する。

d. Azure Container Instancesの上でdocker-compose upをする

4. Azure Container Instances (ACI)テキストの作成

ターミナルに以下のコマンドを入れてAzureにログインを行う
外部サイトが開くので、アカウント選択をする。
You have logged into Microsoft Azure!とでれば消してOKです。

docker login azure

# login succeededと表示される

ACIテキストの作成は以下のコマンドで行います

# zennhandsonは任意の名前
docker context create aci zennhandson 

すると以下のように設定について選択しなければなりません。

# サブスクリプションの設定 (よくわからない場合は一番上でOK)
? Select a subscription ID  [Use arrows to move, type to filter]
> Azure サブスクリプション 1 (21a4a898-4058-4b17-85ef-323573ad6823)
  従量課金 (5d77babd-d990-42c8-a100-6b7fda9ddfaa)
# リソースグループについての設定
# 今回はリソースグループを新たに作成するのでcreate a new resource groupを選択します。
? Select a resource group  [Use arrows to move, type to filter]    
> create a new resource group
9403b4f7-7ef6-413e-07e8-7c1d5fb113f9 (eastus)

すると以下が表示されます。

Resource group "867d8938-b73b-0ac4-db94-f8f9ac77c0c9" (eastus) created
Successfully created aci context "zennhandson"

リソースグループ : 867d8938-b73b-0ac4-db94-f8f9ac77c0c9
ACIテキスト : zennhandson
が作成されました。

Azure portalからも確認することができます。

ホーム画面からAzureサービスの項目にあるリソースグループを選択すると、作成されていることが確認できます。

ACIテキストは以下のコマンドをターミナルに入力して確認します。

docker context ls

作成されていることが確認できました。

次に、以下のコマンドを実行して、zennhandsonにスイッチします。

docker context use zennhandson

# 出力
# zennhandson

# 確認を行う    
# docker context ls

*が移動していたら成功しています。

5. Azure Container Registryにimageを保存する

git cloneしてきた状態のdocker-compose.ymlをみるとrailsコンテナの設定は以下のようになっております。

# 一部抜粋
  rails:
    build: .
    command: rails s -p 3000 -b '0.0.0.0'

buildでDockerfileをbuildしているのですが、デプロイの場合ローカルのファイルを利用できません。
そこで、Dockerfileの内容をimageとして保存して、Azure Container Registryに登録します。
デプロイの際にはそこからimageを持ってきてbuildするようにすることでその問題を解決します。

今回はAzure portalから作成を行います。

検索ウィンドウにContainer Registryと入力して、Market PlaceからContainer Registryを選択

コンテナレジストリの作成画面が開くので

  • リソースグループは先ほど作成したたリソースグループを選択
  • レジストリ名は任意 (ここではzennreg)
  • 場所は東日本

確認および作成をクリックして、作成をクリック

デプロイが完了したら、リソースに移動をクリック

左のメニューからアクセスキーをクリックして、管理者ユーザー を有効にします。

では、ここらからはDockerfileからimageを作成して、Container Registryに登録します。

以下のコマンドでimageを作成します。

# コンテキストをdefalutに戻す
# 出力 : default
docker context use default

# buildを行う
docker-compose build rails

# Container Registryにログイン
# 出力: Login Succeeded
az acr login -n zennreg

# railsのimageを作成する
# docker build -t {ログインサーバー名}/{イメージ名}
# ログインサーバー名はレジストリ名.azurecr.io
# イメージの名前 : zennreg.azurecr.io/rails
docker build -t zennreg.azurecr.io/rails .
# 作成したimageを確認する
docker ps

以下のようにイメージ名が表示されれば成功です。

REPOSITORY                     TAG       IMAGE ID       CREATED          SIZE
zennreg.azurecr.io/rails       latest    5f1bae79229e   18 seconds ago   1.02GB

最後に作成したimageをContainer Registryに登録します

# pushで登録する
docker push zennreg.azurecr.io/rails

こんな感じで始まり、エラーがなければうまくできています。

試しにrailsコンテナだけをデプロイしてみる

先ほど作成したzennreg.azurecr.io/railsイメージ(railsイメージ)のみを使って、試しにデプロイをしてみます。

デプロイができれば、正しくContainer Registryに登録されている事が確認できます。

# ACIテキストを変更する (デプロイこのテキストで行う)
docker context use zennhandson

# docker runでイメージからコンテナを立ち上げる
docker run -p 3000:3000 zennreg.azurecr.io/rails  rails s -p 3000 -b '0.0.0.0'

# railsコンテナが動いているか確認
# 別のターミナルを開いてコマンドを実行
docker ps

このように画面がなっていれば大丈夫です。
port番号がでるのでコピーしてGoogle Chromeでアクセスします。

CONTAINER ID        IMAGE                      COMMAND                      STATUS              PORTS
eager-shockley      zennreg.azurecr.io/rails   rails s -p 3000 -b 0.0.0.0   Running             52.186.167.227:3000->3000/tcp

PORTSをみてアクセス先を確認します。
私の場合は52.186.167.227:3000にアクセスします。

エラーになっていますが、これはdbが立ち上がっていないためなので、railsコンテナは起動しています。

この後、複数のコンテナ(railsとdb)を同時にデプロイしていきたいと思います。

dockerコンテナを以下のコマンドで落とします。

# ctrl + C で止める

# コンテナ停止
# docker psの画面からコンテナIDをコピーする
docker stop {コンテナID}
# コンテナ削除
docker rm {コンテナID}

次にdocker-compose.ymlの設定をdockerイメージを読み込むように修正します。

  rails:
    build: .
    command: rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/rails_work
    ports:
      - "3000:3000"
    depends_on:
      - db

を以下のように修正します。

  rails:
    image: zennreg.azurecr.io/rails
    command: rails s -p 3000 -b '0.0.0.0'
    ports:
      - "3000:3000"
    depends_on:
      - db

ボリュームも本番環境では必要ないため、削除しています。
本当はローカルのファイルを共有したいですが、そこは調査中です。

6. ストレージアカウントの登録

DBが必要ということがわかりましたが、DBのvolumeがいまこのようになっており、ローカルと接続しています。

volumes:
  mysql-data:
    driver: local

デプロイの場合はローカルと接続はできないので、それようのストレージを用意します。

以下のコマンドでストレージを作成します。

# ストレージアカウントを作成
# docker volume create {ファイル共有名} --storage-account {ストレージアカウント名}
# ファイル共有名、ストレージアカウント名は任意

docker volume create rails-db-volume  --storage-account zennstr

作成出来たら、docker-compose.ymlを修正します。

version: '3'
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: root
    volumes:
      - mysql-data:/var/lib/mysql
    ports:
      - "3308:3308"

(railsコンテナは省略)

volumes:
  mysql-data:
    driver: local

を以下のように修正します。

version: '3'
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: root
    volumes:
      - dbdata-volume:/var/lib/mysqlimage
    ports:
      - "3308:3308"
 
  rails:
    # build: .
    image: zennreg.azurecr.io/rails
    command: rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/rails_work
    ports:
      - "3000:3000"
    depends_on:
      - db

volumes:
  dbdata-volume:
    driver: azure_file
    driver_opts:
      share_name: rails-db-volume
      storage_account_name: zennstr

volumesのdriver: azure_fileはおまじないらしいです。
share_nameに先ほど設定したファイル共有名、storage_account_nameにストレージアカウント名を入れています。

7. 複数のコンテナをデプロイする

現在のACIテキストが作成したものになっているかを確認します

docker context ls

# もし4で作成したものでない場合は以下のコマンド
docker context zennhandson

ではデプロイを行います。

# デプロイを行う
docker compose up

注意としてはdocker-compose upではないということです。

このようにエラーなく終わればデプロイ成功です。

Azure portalからリソースグループを選択すると、Container Instancesが立ち上がっていることが確認できます。

今回デプロイしたContainer Instancesはrails_mysqlとなっています。
(eager-shockleyは先ほどイメージのみをデプロイした時のもの)

rails_mysqlをクリックして、左メニューからコンテナーをクリックすると、以下の画面になります。

railsとdbのコンテナが動いていることがわかります。

では、実際にアクセスして確かめたいと思います。

# ポートを確認する
docker ps
CONTAINER ID         IMAGE                      COMMAND                      STATUS              PORTS
rails5_mysql_rails   zennreg.azurecr.io/rails   rails s -p 3000 -b 0.0.0.0   Running             40.88.253.210:3000->3000/tcp
rails5_mysql_db      mysql:5.7                                               Running             40.88.253.210:3308->3308/tcp

40.88.253.210:3000にアクセスします。

dbができていないため、エラーがでているので作成します。

# railsコンテナの中に入る
# {Container Instances名}_railsとなるので注意 (railsではない)
docker exec -it rails5_mysql_rails sh

# dbを作成する
rails db:create

40.88.253.210:3000に再びアクセス

成功!お疲れさまでした。

8. 後片付け

このまま放置すると課金が止まらないので、後片付けします。

まずは起動したコンテナを落とします。

docker compose down

Azure portalで作成したリソースグループにアクセスし、上のメニューからリソースグループの削除を選択します。
確認ウィンドウが開くので、リソースグループ名を入力して、削除をクリックします。

おわりに

今回は初めてのデプロイをしてみました。AWSなどに比べるとAzureは記事が少ないような気がするのですが、どうなのでしょうか。調べていて記事があまり見つからずはじめに理解するのが大変でした。

今後は、ローカルファイルとのマウントや他のサービスを使ったサーバーありのデプロイなどもやっていきたいと思います。

GitHubで編集を提案

Discussion

イメージの確認はdocker psでなく、docker imagesの間違いです。

ログインするとコメントできます