(前回の記事)
docker-machine + さくらのクラウドでお手軽リモートdockerするよ
(今回使うソースコード)
github:docker-machine-sakuracloud
(時間がない人へ)この記事の結論
リモートDockerコンテナをビルドサーバにするには以下のようにすればOK
- Dockerfile内で
ADD . [コンテナ内パス]
でソースコードなどをコンテナへコピー -
docker run
実行時にmakeなどのビルドコマンドを指定 - ビルド後に
docker cp
コマンドで成果物をローカルPCにコピー
docker-machine-sakuracloudをバージョンアップした
docker-machineからさくらのクラウド上の仮想サーバを使えるようにするプラグイン
docker-machine-sakuracloudをv0.0.3へバージョンアップしました。
今回のバージョンから、
- docker-machineでさくらのクラウド上にサーバを作り、
- そのサーバ上でリモートDockerコンテナを動かして、
- 手元のPCにあるソースコードをビルド
が行えるようになりました。
ビルドシステムは親元であるdocker-machineを参考にしています。
docker-machine-sakuracloud自身もこの方法、いわゆるセルフホスティング?というやつをやってます。
本記事タイトルの「ビルドサーバ作るよ」はこの3手順で終わっちゃいます。
、、、が、これだけだと「じゃあ自分のプロジェクトではどうすりゃいいのよ!?」という声が聞こえそうですので、以下でdocker-machine-sakuracloudで実際にビルドをしてみながら仕組みを解説していこうかと思います。
docker-machine-sakuracloudをdocker上でビルドしてみる
docker-machine-sakuracloudをdocker上でビルドするには以下の環境が必要です。
(詳細はコントリビューションガイドを参照ください。)
- dockerコマンド(docker-toolboxをインストールしておけばOK)
- makeコマンド
- bash
なお、windowsでdocker-toolboxをインストールした際に一緒にインストールされる
MinGWではmakeコマンドが使えないため別途msys2などmakeできる環境を用意しておきます。
下準備
- 前回の記事を参考にdocker-machine-sakuracloudを使えるようにしておいてください
- サーバ作成時のコマンド入力を楽にするために以下のように環境変数を設定しておきます。
$ export SAKURACLOUD_ACCESS_TOKEN=[さくらのクラウドのアクセストークン]
$ export SAKURACLOUD_ACCESS_TOKEN_SECRET=[アクセストークンシークレット]
これらの環境変数を設定しておくことでdocker-machine create
時に
トークンとシークレットの入力を省略できます。
ソース取得からビルドまでの流れ
- さくらのクラウド上にサーバをつくる(こちらを参考に)
- githubからソース一式を取得
- makeする時にDockerコンテナを使うように環境変数$USE_CONTAINERを設定
- make build実行
これだけです。以下に実行例を示します。
1. さくらのクラウド上にサーバをつくり、dockerから使えるようにする
$ docker-machine create -d sakuracloud sakura-dev
$ eval "$(docer-machine env sakura-dev)"
2. githubからソース取得
$ git clone https://github.com/yamamoto-febc/docker-machine-sakuracloud.git
$ cd docker-machine-sakuracloud
3. make時にDockerコンテナを使うように環境変数でフラグを立てておく
$ export USE_CONTAINER=true
4. ビルド実施
$ make build
$ ls bin/ # docker-machine-driver-sakuracloudバイナリができてるよ!
あら不思議、dockerコンテナはさくらのクラウド上にあるはずなのに
ローカルPCのソースがGoでコンパイルされてカレントディレクトリ/bin
に出力されています。
どうやってリモートでビルドしてるの?
ポイントは以下2点です。
- 環境変数
USE_CONTAINER
でローカル/リモートどちらでの処理か判定 - リモートでの処理の場合はdockerコマンドでリモートサーバ上で処理
dockerコマンドを実行している箇所を見てみましょう。
script/build_in_container.sh(抜粋)
#!/bin/bash
#〜中略〜
# 1. カレントディレクトリでDockerイメージのビルド
docker build -t $DOCKER_IMAGE_NAME .
# 2. ビルドしたイメージからコンテナ実行
docker run --name $DOCKER_CONTAINER_NAME \
-e DEBUG \
# 〜中略:各種環境変数の設定〜
$DOCKER_IMAGE_NAME \
make "$@"
#〜中略〜
# 3. makeターゲットが"build"を含む場合コンテナからローカルPCへディレクトリコピー
if [[ "$@" == *"build"* ]]; then
docker cp $DOCKER_CONTAINER_NAME:/go/src/github.com/yamamoto-febc/docker-machine-sakuracloud/bin bin
fi
やっていることは、
- カレントディレクトリの
Dockerfile
を使ってDockerイメージをビルド - ビルドしたイメージからDockerコンテナを実行:環境変数各種を設定しmakeを実行させる
- makeのターゲットが"build"を含む場合はbinディレクトリをDockerコンテナからローカルPCへコピー
ビルド後にローカルPCのbinディレクトリにバイナリが格納されたのは3.の処理のおかげですね!
docker cp
でリモートサーバ上のDockerコンテナとのファイルのやり取りが可能になります。
参考までにdocker cp
のヘルプを記載しておきます。
$ docker help cp
Usage: docker cp [OPTIONS] CONTAINER:PATH LOCALPATH|-
docker cp [OPTIONS] LOCALPATH|- CONTAINER:PATH
Copy files/folders between a container and your host.
Use '-' as the source to read a tar archive from stdin
and extract it to a directory destination in a container.
Use '-' as the destination to stream a tar archive of a
container source to stdout.
ではローカルPCにあるソースコードはどうやってリモートサーバに送られているのでしょうか?
今度はDockerfileを見てみましょう。
Dockerfile(抜粋)
# 1. ベースイメージを指定
FROM golang:1.5.1
# 2. ビルドに必要なライブラリ類の取得
RUN go get github.com/golang/lint/golint \
# 〜中略〜
# 3. コンテナ内でmakeを実行する際の作業ディレクトリを指定
WORKDIR /go/src/github.com/yamamoto-febc/docker-machine-sakuracloud
# 4. !カレントディレクトリをコンテナ内にコピー!
ADD . /go/src/github.com/yamamoto-febc/docker-machine-sakuracloud
このDockerコンテナ内では$GOPATHが/go
に設定されているため、
それに合わせたソース配置にし、カレントディレクトリの内容、つまりソースコードをコピーしています。
これでビルドの流れが追えましたね。
まとめ
まとめると、リモートDockerコンテナでビルドするには
- Dockerfile内で
ADD . [コンテナ内パス]
でソースコードなどをコンテナへコピー -
docker run
実行時にmakeなどのビルドコマンドを指定 - ビルド後に
docker cp
コマンドで成果物をローカルPCにコピー
を行えば良いです。
私の開発環境がOSXであるためmakeを使いましたが、dockerコンテナ上で実行できれば
バッチでもなんでも構いませんので色々応用できますね!
以上です。
11/15 コマンド誤りを修正
修正前:
$ cd docker-machine-sakuracloud.git
修正後:
$ cd docker-machine-sakuracloud