4. Dockerのおさらいとコンテナ起動
この章では Cloud Shell のエディタとターミナルを行き来しながら、Docker の要点をおさらいし、実際に Web サーバーのコンテナイメージを作って・動かして・ブラウザで見るところまでやってみましょう。
3章で用意した ~/cloudrun-handson/app が、今日ずっと作業する場所です。ここで作ったイメージを、次章以降で Cloud Run にデプロイしていきます。
Docker をしっかり学びたい人は introduction-docker にまとまっています。今日は Cloud Run に必要な分だけ、駆け足で。
おさらい: 3つの登場人物
| 用語 | 一言でいうと | AWSでの馴染み |
|---|---|---|
| Dockerfile | イメージの設計図(テキストファイル) | CodeBuild でビルドしていたアレ |
| イメージ | アプリ+依存関係+OSライブラリを固めたスナップショット | ECR に push していたアレ |
| コンテナ | イメージを実行したプロセス | ECS タスクの中で動いていたアレ |
ポイントは1つだけです: イメージは不変(immutable)。
「環境ごと固めて配る」からこそ、ローカルでも Cloud Run でも ECS でも同じように動きます。
この不変性が、後でやるロールバックやカナリアリリースの土台になります。
エディタとターミナルの基本
Cloud Shell エディタを開くと、3つの領域に分かれています。
- 左側: ファイルツリー —
$HOME(~/cloudrun-handson/など)配下のファイル・フォルダ一覧 - 中央: エディタ — VS Code ベースで、拡張機能・シンタックスハイライトなど一通り揃っています
- 下部: ターミナル — コマンドを実行する画面。タブで複数開けます
ファイル・フォルダを操作する
ファイルツリーを右クリックすると、新規ファイル・新規フォルダ・リネーム・削除ができます。
ファイルの保存は自動ではありません。編集後は Cmd+S(macOS)/ Ctrl+S(Windows/Linux)で保存してください。
詰まったら: 「ファイルを書き換えたのにコマンドの結果が変わらない」と感じたら、エディタのタブ名の横に丸印(●)が出ていないか確認してください。丸印は未保存の印で、保存すればファイル名だけの表示に変わります。
ターミナルを使う
下部パネルの + ボタンで、新しいターミナルタブを追加できます。
複数のターミナルは同じ Cloud Shell 環境(同じ $HOME)を共有するので、たとえば片方でログを流しっぱなしにしながら、もう片方でコマンドを打つ、という使い方ができます。
ターミナルとエディタは同じファイルシステムを見ているため、エディタで保存した変更は即座にターミナルから見えます。
一方で、Cloud Shell が切断されると新しいターミナルセッションになり、export した環境変数はすべて消えます(ファイルは $HOME に残るため消えません)。環境変数を設定し直す方法は、5章の「0. 環境変数の準備」でまとめて扱います。
覚えておくと速いショートカット
必須ではありませんが、知っておくと操作が速くなります。
| 操作 | ショートカット |
|---|---|
| コマンドパレットを開く | Cmd+Shift+P / Ctrl+Shift+P |
| ファイルを名前で開く | Cmd+P / Ctrl+P |
| ファイル内を検索 | Cmd+F / Ctrl+F |
| プロジェクト全体を検索 | Cmd+Shift+F / Ctrl+Shift+F |
今日の基本サイクルは、ここからずっとこの繰り返しです。
- エディタでファイルを編集する
- 保存する(
Cmd+S/Ctrl+S) - ターミナルでコマンドを実行する(
docker build、gcloud run deployなど) - 結果をブラウザやターミナルの出力で確認する
手が止まったら、まず「保存し忘れていないか」を疑ってください。
ハンズオン: Webサーバーのイメージを作る
アプリは TypeScript + Hono で書かれています。
Hono は Web 標準 API ベースの軽量な Web フレームワークです(Hono 自体は Cloudflare Workers や Deno などマルチランタイム対応ですが、今回は Node.js アダプタと Node.js API を使います)。
実行には Node.js 24 の組み込み type stripping ——型注釈を剥がして実行する機能——を使い、この教材で使う範囲の TypeScript をビルドステップなしで動かします。
ビルドを1段消すことで、今日の主役である Cloud Run に集中するためです。
type stripping は型注釈を空白に置き換えるだけで、型チェックは行いません(
tscの代替ではありません)。tsconfig.jsonも読まれないため、enum や parameter properties のように「変換が必要な構文」は使えません。この教材のコードはすべて対応範囲内です。
TypeScript に詳しくなくても大丈夫です。書き換えるのは定数2行だけで、あとはコピー&ペーストで進められます。
1. サンプルコードを開く
エディタの左のファイルツリーから cloudrun-handson/app を開きます。直下に package.json・Dockerfile・.dockerignore の3ファイルと src/ フォルダがあり、src/ の中に index.ts が入っています。
cd ~/cloudrun-handson/app
src/index.ts — 小さなWebサーバーです。アクセスすると「メッセージ・リビジョン名・インスタンスID」を表示します(インスタンスは、リクエストを処理するコンテナの実体です。8章で扱います)。
Dockerfile を上から読んでみましょう。 ベースイメージ(
FROM)に依存関係を重ね(RUN npm install)、コードを載せ(COPY)、起動コマンドを決める(CMD)。この積み重ねがそのままイメージのレイヤーになります。package.jsonだけ先に COPY しているのは、コードを変更してもnpm installのレイヤーキャッシュが効くようにするテクニックです(この後の章で効いてきます)。1点だけ Cloud Run 固有の約束があります: 環境変数
PORTで渡されたポートを listen すること。ECS でいうタスク定義のポートマッピングにあたる取り決めが、この環境変数1つに集約されています。
2. イメージをビルドする
docker build -t handson-app:v1 .
手元に Node.js がなくても(npm install を一度も打っていなくても)ビルドできることに注目してみましょう。
依存解決も実行環境も、すべてイメージの中で完結しています。docker images で handson-app ができていることを確認してみましょう。
3. コンテナを起動する
docker run --rm -p 8080:8080 handson-app:v1
4. ブラウザで見る
Cloud Shell の右上にある[ウェブでプレビュー]ボタン(ウィンドウの中に目が描かれたアイコン)→[ポート 8080 でプレビュー]をクリックします。
青い画面に「Hello, Cloud Run!」と表示されれば成功です。
Revision と Service が local になっていることも確認してみましょう——Cloud Run にデプロイすると、ここが自動で埋まります。
確認できたらターミナルで Ctrl+C を押してコンテナを止めます。
5. (余裕があれば)コンテナの中に入ってみる
docker run --rm -it handson-app:v1 bash
ls # 自分の書いたコードと node_modules が /app に入っている
node -v # イメージに焼き込まれた Node.js 24
exit
まとめ
- エディタで編集 → 保存 → ターミナルで実行 → ブラウザで確認、の往復が今日の基本サイクル
- Dockerfile → イメージ → コンテナ、の流れを一周した
- イメージは不変。だから「どこでも同じに動く」し「前のバージョンに戻せる」
- Cloud Run との約束は「環境変数
PORTを listen する」だけ
今、あなたの手元(Cloud Shell)には動くイメージがあります。
次の5章で、これをそのまま Cloud Run にデプロイします。