The Go Blog

Docker を使用した Go サーバーのデプロイ

Andrew Gerrand
2014 年 9 月 26 日

はじめに

今週、Docker は Go およびその他の主要言語向けの公式ベースイメージを発表しました。これにより、プログラマーは信頼性が高く簡単な方法で Go プログラム用のコンテナを構築できます。

この記事では、シンプルな Go ウェブアプリケーション用の Docker コンテナを作成し、そのコンテナを Google Compute Engine にデプロイするための手順を説明します。Docker に慣れていない場合は、読み進める前にDocker の理解を読む必要があります。

デモアプリ

デモンストレーションでは、Go のサンプルリポジトリにあるoutyetプログラムを使用します。これは、次のバージョンの Go がリリースされたかどうかを報告するシンプルなウェブサーバーです (例: isgo1point4.outyet.org のようなサイトを動かすように設計されています)。標準ライブラリ以外に依存関係はなく、実行時に追加のデータファイルは必要ありません。ウェブサーバーとしては、これ以上ないほどシンプルです。

「go get」を使用して、outyet をワークスペースにフェッチしてインストールします。

$ go get golang.org/x/example/outyet

Dockerfile を記述する

outyet ディレクトリにある Dockerfile という名前のファイルを次の内容に置き換えます。

# Start from a Debian image with the latest version of Go installed
# and a workspace (GOPATH) configured at /go.
FROM golang

# Copy the local package files to the container's workspace.
ADD . /go/src/golang.org/x/example/outyet

# Build the outyet command inside the container.
# (You may fetch or manage dependencies here,
# either manually or with a tool like "godep".)
RUN go install golang.org/x/example/outyet

# Run the outyet command by default when the container starts.
ENTRYPOINT /go/bin/outyet

# Document that the service listens on port 8080.
EXPOSE 8080

この Dockerfile は、outyet を実行するコンテナを構築する方法を指定しています。基本的な依存関係 (Go がインストールされた Debian システム、公式 golang Docker イメージ) から開始し、outyet パッケージソースを追加し、ビルドし、最後に実行します。

ADDRUN、および ENTRYPOINT ステップは、Go プロジェクトに共通のタスクです。これを簡素化するために、golang イメージにはonbuild バリアントがあります。これは、パッケージソースを自動的にコピーし、アプリケーションの依存関係をフェッチし、プログラムをビルドし、起動時に実行するように構成します。

onbuild バリアントを使用すると、Dockerfile ははるかにシンプルになります。

FROM golang:onbuild
EXPOSE 8080

イメージをビルドして実行する

outyet パッケージディレクトリから Docker を呼び出して、Dockerfile を使用してイメージをビルドします。

$ docker build -t outyet .

これにより、Docker Hub から golang ベースイメージがフェッチされ、パッケージソースがコピーされ、内部でパッケージがビルドされ、結果のイメージに outyet というタグが付けられます。

結果のイメージからコンテナを実行するには

$ docker run --publish 6060:8080 --name test --rm outyet

--publish フラグは、コンテナのポート 8080 を外部ポート 6060 で公開するように Docker に指示します。

--name フラグは、作業を容易にするために、コンテナに予測可能な名前を付けます。

--rm フラグは、outyet サーバーが終了したときにコンテナイメージを削除するように Docker に指示します。

コンテナが実行されたら、ウェブブラウザで https://:6060/ を開き、次のような画面が表示されるはずです。

(Docker デーモンが別のマシン (または仮想マシン) で実行されている場合は、localhost をそのマシンのアドレスに置き換える必要があります。boot2docker を OS X または Windows で使用している場合は、boot2docker ip でそのアドレスを見つけることができます。)

イメージが動作することを確認したので、別のターミナルウィンドウから実行中のコンテナをシャットダウンします。

$ docker stop test

Docker Hub にリポジトリを作成する

以前 golang イメージをプルしたコンテナレジストリであるDocker Hubは、GitHub または BitBucket リポジトリからイメージをビルドする自動ビルドという機能を提供しています。

Dockerfileをリポジトリにコミットし、それ用の自動ビルドを作成することで、Docker がインストールされている誰もが単一のコマンドで私たちのイメージをダウンロードして実行できます。(この有用性は次のセクションで説明します。)

自動ビルドを設定するには、Dockerfile をGitHubまたはBitBucketのリポジトリにコミットし、Docker Hub でアカウントを作成し、自動ビルドの作成の手順に従ってください。

完了したら、自動ビルドの名前を使用してコンテナを実行できます。

$ docker run goexample/outyet

(goexample/outyet を作成した自動ビルドの名前に置き換えてください。)

コンテナを Google Compute Engine にデプロイする

Google は、任意の Docker コンテナを実行する仮想マシンを簡単に起動できるコンテナ最適化 Google Compute Engine イメージを提供しています。起動時に、インスタンスで実行されているプログラムは、実行するコンテナを指定する構成ファイルを読み取り、コンテナイメージをフェッチして実行します。

実行する Docker イメージと公開するポートを指定する containers.yaml ファイルを作成します。

version: v1beta2
containers:
- name: outyet
  image: goexample/outyet
  ports:
  - name: http
    hostPort: 80
    containerPort: 8080

(コンテナのポート 8080 を外部ポート 80 (HTTP トラフィックを処理するためのデフォルトポート) として公開していることに注意してください。そして、再度、goexample/outyet を作成した自動ビルドの名前に置き換えてください。)

gcloud ツールを使用して、コンテナを実行する VM インスタンスを作成します。

$ gcloud compute instances create outyet \
    --image container-vm-v20140925 \
    --image-project google-containers \
    --metadata-from-file google-container-manifest=containers.yaml \
    --tags http-server \
    --zone us-central1-a \
    --machine-type f1-micro

最初の引数 (outyet) は、インスタンス名を指定します。これは管理目的の便利なラベルです。

--image および --image-project フラグは、使用する特別なコンテナ最適化システムイメージを指定します (これらのフラグはそのままコピーしてください)。

--metadata-from-file フラグは、containers.yaml ファイルを VM に提供します。

--tags フラグは、VM インスタンスを HTTP サーバーとしてタグ付けし、パブリックネットワークインターフェースでポート 80 を公開するようにファイアウォールを調整します。

--zone および --machine-type フラグは、VM を実行するゾーンと実行するマシンの種類を指定します。(マシンの種類とゾーンのリストを確認するには、gcloud compute machine-types list を実行します。)

これが完了すると、gcloud コマンドはインスタンスに関する情報を出力するはずです。出力で、インスタンスの外部 IP アドレスを見つけるには、networkInterfaces セクションを見つけてください。数分以内に、Web ブラウザでその IP にアクセスし、「Has Go 1.4 been released yet?」ページが表示されるはずです。

(新しい VM インスタンスで何が起こっているかを確認するには、gcloud compute ssh outyet で SSH 接続します。そこから、sudo docker ps を試して、どの Docker コンテナが実行されているかを確認してください。)

さらに詳しく

これは氷山の一角にすぎません。Go、Docker、Google Compute Engine を使用してできることはもっとたくさんあります。

Docker の詳細については、広範なドキュメントを参照してください。

Docker と Go の詳細については、公式 golang Docker Hub リポジトリと Kelsey Hightower の静的 Go バイナリ用の Docker イメージの最適化を参照してください。

Docker と Google Compute Engine の詳細については、コンテナ最適化 VM ページgoogle/docker-registry Docker Hub リポジトリを参照してください。

次の記事: Go at Google I/O and Gopher SummerFest
前の記事: 定数
ブログインデックス