目的
Azure上のコンテナサービスは複数ありますが、今回は複数のインスタンスを(恐らく)一つのホスト上にデプロイし、Web APサーバからDBサーバへのデータ追加をテストしてみたいと思います。
作業の流れ
Dockerfileの作成
コンテナ単体で起動できるDockerfileを作成します。ここにはプログラムソースや必要なコンポーネントのインストールが含まれます。
ローカル用のYAMLファイルの作成
複数のDockerfileからYAMLファイルを使用して、一度にプロビジョニングを行ったり、環境情報(特にDB周りの初期設定)を登録します。
ローカルデプロイと検証
ローカル上での動作検証をします。
コンテナレポジトリの作成
Azure上のコンテナレポジトリを作成し、ローカルで作成したイメージをタグごとに保管する場所とします。
イメージビルドとコンテナレポジトリへのアップロード
イメージビルドを行い、一度起動し、その後止めます。止まっているイメージに対して、イメージの取得、Azureコンテナレポジトリへイメージのアップロードを行います。
ACI用のYAMLファイルの作成
Azure Container Instances(ACI)用のYAMLファイルを作成する。
Azureへのデプロイ
作成したACI用のYAMLファイルを引数として、Azure上にコンテナを作成する。
検証
Azure上のコンテナの動作検証する。
私の環境
自分のPCはMacですので、Dockerは動くものの、少し特殊な設定が一部で必要となるので、VMにUbuntuを入れて、Dockerを動かしています。MacからVS Codeを使って、SSHリモートアクセスを有効にして、対象のファイルをVS Codeで編集しつつ、各種コマンドをSSHで実行しています。
フォルダ構成は以下のとおりです。
./
├── ap
│ ├── Dockerfile
│ ├── form.html
│ ├── list.php
│ ├── phpinfo.php
│ └── submit.php
├── azure_compose
│ └── docker-compose.yml
├── compose.yml
└── db
├── Dockerfile
└── script
└── create_db.sql
1.Dockerfileの作成
ここは特に悩みませんでした。
ただ、the PHP Groupが提供しているコンテナイメージでmysqliモジュールがオフとなっていたことに検証まで気が付きませんでした。
ap-Dockerfile
FROM php:8.3-apache
RUN apt update -y
RUN docker-php-ext-configure mysqli && docker-php-ext-install mysqli
COPY ./form.html /var/www/html
COPY ./list.php /var/www/html/
COPY ./submit.php /var/www/html
COPY ./phpinfo.php /var/www/html
db-Dockerfile
FROM mysql:latest
2.ローカル用のYAMLファイルの作成
ここでは、主にMySQL向けの初期設定をしています。MySQLコンテナはオフィシャルイメージを使っています。必要なスクリプトを/docker-entrypoint-initdb.dに置くと初回起動時に自動的に実行してくれます。
services:
ap:
build:
context: ./ap
dockerfile: ./Dockerfile
ports:
- 8000:80
db:
build:
context: ./db
dockerfile: Dockerfile
restart: always
environment:
MYSQL_ROOT_PASSWORD: xxxxx
MYSQL_DATABASE: xxxx
MYSQL_USER: xxxx
MYSQL_PASSWORD: xxxx
TZ: 'Asia/Tokyo'
volumes:
- ./db/script:/docker-entrypoint-initdb.d
3.ローカルデプロイと検証
特にここまでの中で大きな問題はなかったので、以下のようにイメージをビルドしてからローカル環境にデプロイします。
docker-compose build
docker-compose up -d
ローカル内の各コンテナはコンテナ名で通信ができるので、サーバ名($servername)部分はdbで問題ありません。
$conn = new mysqli($servername, $username, $password, $dbname);
4.コンテナレポジトリの作成
ここは特に考えずにコンテナレポジトリをCLIで作っています。
az login
az acr create --resource-group xxx --name ${コンテナレポジトリ名}
az acr login -n ${コンテナレポジトリ名}
Login Succeeded
5.イメージビルドとコンテナレポジトリへのアップロード
コンテナレポジトリーにイメージをアップするために、ローカル上でイメージをデプロイし、止めたものを再イメージ化する必要があります。「3.ローカルデプロイと検証」で、既にイメージを起動しているので、その後を受けて以下のように行います。
commitする際に、docker ps等で停止させたコンテナ名を取得することと、レポジトリを指定して置くことが大切です。
# コンテナの停止
docker-compose stop
# 止めているコンテナから再イメージを作成する
docker commit php-test_db_1 ${コンテナレポジトリ名}.azurecr.io/php-test_db:1.0.0
docker push ${コンテナレポジトリ名}.azurecr.io/php-test_db:1.0.0
docker commit php-test_ap_1 ${コンテナレポジトリ名}.azurecr.io/php-test_ap:1.0.0
docker push ${コンテナレポジトリ名}.azurecr.io/php-test_ap:1.0.0
6.ACI用のYAMLファイルの作成
ここで、ローカル環境との違いを認識しました。docker-entrypoint-initdb.dのマッピング先がローカルと違うので、AzureFilesに共有フォルダを作成し、そこに開発資源を置くことにしました。
name: xxxx
properties:
containers:
- name: db
properties:
image: ${コンテナレポジトリ名}.azurecr.io/php-test_db:1.0.0
resources:
requests:
cpu: 1
memoryInGb: 1.5
volumeMounts:
- name: script
mountPath: /docker-entrypoint-initdb.d
- name: ap
properties:
image: ${コンテナレポジトリ名}.azurecr.io/php-test_ap:1.0.0
resources:
requests:
cpu: 1
memoryInGb: 1.5
ports:
- port: 80
osType: Linux
ipAddress:
type: Public
dnsnameLabel: xxx
ports:
- protocol: tcp
port: 80
imageRegistryCredentials:
- server: ${コンテナレポジトリ名}.azurecr.io
username: ${コンテナレポジトリ名}
password: xxxx
volumes:
- name: script
azureFile:
sharename: script
storageAccountName: xxxx
storageAccountKey: xxxx
7.Azureへのデプロイ
Azureデプロイ用に用意したYAMLファイルを引数として、ACIを作成します。今回はそれほど大きくないので、2,3分ほどで終わった印象です。
az container create --resource-group ccf-container-service --file azure_compose/docker-compose.yml --location "Japan East"
8.検証
実はここまででやって、うまく行きませんでした。
原因は、「3.ローカルデプロイと検証」でも考慮が必要だったdbコンテナ$servernameです。ローカル環境では、dbでも問題なかったのですが、やはりうまく接続できません。
そこで、色々調べていると、この2つのコンテナは1つのサーバで動いているということがわかりました。そこで、「localhost」としたのですが、これでもだめでした。
結論、「127.0.0.1」でうまくいきました。
つまり、apもdbも同じサーバで動いているので、apからdbにアクセスする場合も「127.0.0.1」で良かったようです。
コメント