デプロイについてまったく知らないのでAzureを使ってDocker+Railsのデプロイに奮闘した話
はじめに
こんにちは
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は記事が少ないような気がするのですが、どうなのでしょうか。調べていて記事があまり見つからずはじめに理解するのが大変でした。
今後は、ローカルファイルとのマウントや他のサービスを使ったサーバーありのデプロイなどもやっていきたいと思います。
Discussion
イメージの確認は
docker ps
でなく、docker images
の間違いです。