はじめに
こんにちは!masa-asaです。
クラウドサービスを用いて開発を行っていると、手元で開発したコードをDockerイメージにビルドしてそれをクラウド上のサーバーで実行したい。というニーズはよく出てくることと思います!
そこで今回はGoogle Cloud(GC)でコンテナイメージを管理し、どのようにクラウド上でデプロイするかについて見ていきたいと思います!
Artifact Registry と Container Registry
GCではコンテナイメージを管理するためのサービスとしてArtifact Registry(AR) と Container Registry(CR)の2つがあります。従来利用されていたものがContainer Registryで、このサービスを拡張したものがArtifact Registryです。
そのため、今から利用する場合はArtifact Registryを利用します。
Container Registryは非推奨で、2025 年 3 月 18 日以降サービスが終了します。
Artifact Registry はアーティファクトという名前が示すように、Dockerコンテナイメージのみを管理するサービスではなく、Dockerイメージを含めた多種多様な(何らかの成果物としての)モノを保存・管理できるサービスです。Dockerコンテナイメージはもちろん、npmやaptで管理するパッケージなどを保存・管理できます。
前提条件
- Dockerの導入:DockerをWSLに導入している必要があります
- Node.jsとnpmの導入:asdfでNode.js 20.18.0を導入しています
- サンプルアプリの準備:次のコマンドで、サンプルのプロジェクトを作成しました
npx create-react-app my-react-app
Artifact Registryの作成
terraformを使ってArtifact Registryの作成を行います。コードは次通りです。
# ./modules/artifact_registry/main.tf
resource "google_artifact_registry_repository" "docker-repo" {
location = "asia-northeast1"
repository_id = "ar-repo-asa-poc"
description = "example docker repository"
format = "DOCKER"
docker_config {
immutable_tags = true
}
}
# ./main.tf
module "artifact_registry" {
source = "./modules/artifact_registry"
}
# ./provider.tf
provider "google" {
project = "my-sandbox"
}
Dockerコンテナイメージのプッシュ
Artifact Registryが作成できたら、手元のDockerイメージをARにプッシュします。
ARにアップロードするソースイメージに対して、アップロード先のARの情報を含んだイメージ名を付けてあげる必要があります。また、識別のためにタグも付けます。そのために次のようなコマンドを実行します。
docker tag mytest asia-northeast1-docker.pkg.dev/my-sandbox/ar-repo-asa-poc/docker-image-asa-poc:latest
上記コマンドについて、ARでDockerのリポジトリを扱う場合には、対象のARのリポジトリ名を用いる必要があります。命名は次のような形式で表されます。
-
LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY
- LOCATION:ARのリソースが存在するロケーションです。ここでは上のコマンドでは「asia-northeast1」が相当します
- PROJECT-ID:ARのリソースが存在するプロジェクトのDです。GCのホーム画面から確認できます。注意すべきは数字で構成されたプロジェクト番号ではないということです。コマンドの「my-sandbox」に相当します
- REPOSITORY:ARのリポジトリ名で、作成したARの名前です。コマンドの「ar-repo-asa-poc」に相当します
また、このリポジトリにあるコンテナイメージ名は以下のようなパターンの命名で表されます。
-
LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY/IMAGE
LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY/IMAGE:TAG
LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY/IMAGE@IMAGE-DIGEST
- IMAGE:イメージはリポジトリ内のコンテナイメージ名です。コマンドの「docker-image-asa-poc」に相当します
- TAG:イメージのタグです。コマンドの「latest」に相当します
- IMAGE-DIGEST:イメージのsha256ハッシュ値です。今回は使用していません
DockerイメージのARへのプッシュ
手元にあるDockerイメージをARにプッシュするには以下のコマンドを実行します。
docker push asia-northeast1-docker.pkg.dev/my-sandbox/ar-repo-asa-poc/docker-image-asa-poc:latest
Cloud Runにアップロードする
アップロードしたイメージのURLを取得します。画面から簡単にデプロイすることもできますが、せっかくですのでterraformから作成したいと思います。
作成イメージからCloud Runにデプロイするを選択します。
「コンテナイメージのURL」からイメージのURLを取得できます。
template:containers:imageに取得したコンテナイメージのを指定します
resource "google_cloud_run_v2_service" "default" {
name = "crun-sandbox-asa"
location = "asia-northeast1"
deletion_protection = false
ingress = "INGRESS_TRAFFIC_ALL"
template {
max_instance_request_concurrency = 20
scaling {
max_instance_count = 1
}
containers {
image = "asia-northeast1-docker.pkg.dev/my-sandbox/ar-repo-asa-poc/docker-image-asa-poc:latest"
resources {
limits = {
cpu = "1"
memory = "512Mi"
}
}
}
}
}
data "google_iam_policy" "noauth" {
binding {
role = "roles/run.invoker"
members = [
"allUsers",
]
}
}
resource "google_cloud_run_service_iam_policy" "noauth" {
location = google_cloud_run_v2_service.default.location
project = google_cloud_run_v2_service.default.project
service = google_cloud_run_v2_service.default.name
policy_data = data.google_iam_policy.noauth.policy_data
}
terraformを実行し、Cloud Runが作成できました!
Cloud RunのURLをたたいてみると以下のように表示されます。うまく動いていそうです!
まとめ
今回はGoogle CloudでDockerコンテナイメージを管理する方法を見ました。内容としては以下のようなものでした。
- イメージの保存・管理にはArtifact Registryを用いる
- ARからCloud RunをはじめとするGCサービスに簡単にデプロイできる
これらのサービスはCI/CDと組み合わせることでビルド~デプロイまでをより効率的に行うことができるようになりそうです!機会があればCI/CDとの連携についても書けたらと思います。
お読みいただきありがとうございました!
おまけ1:ARへのイメージプッシュ時の権限エラー
イメージをプッシュしようとした際に以下のようなエラーが出ました。権限が不足しているようです。
denied: Unauthenticated request. Unauthenticated requests do not have permission "artifactregistry.repositories.uploadArtifacts"
以下のコマンドを実行することで解決できました。指定したリージョンに対して、Dockerの認証を構成します。
gcloud auth configure-docker asia-northeast1-docker.pkg.dev
おまけ2 サンプルのDockerfile
今回のサンプルプロジェクトのDockerイメージを作成するために用いたDockerFileです。
FROM node:23-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
EXPOSE 8080
CMD [ "npm" , "start" ]