Go言語はワークスペースの単位でGOPATHを設定が必要で、コードのリポジトリは、その遥かにしたのレベルで管理することになります。従って、Go言語のコードを一つのリポジトリの階層構造の中で、管理できないという事を意味している様に思います。 それでは、依存するパッケージを集めて、設定ファイルやデータと合わせて、全体をビルドするには、どうしたら良いのでしょうか?
2回目の学習結果を基に、もっとスマートで簡単に、Go言語のウェブ・アプリを IBM Cloud CloudFoudry アプリとして、構築してデプロイするにはどうすれば良いか、学んで見たいと思います。
GitリポジトリとGo言語のワークスペース
Go言語はワークスペースの単位でGOPATHを設定が必要なので、複数のパッケージを統合してアプリをビルドする場合に、考慮が必要となります。 例えば、GitHubのリポジトリで管理する範囲は、ワークスペースのsrcの下の go_util や go_webserver のそれぞれのディレクトリのレベルで、独立して管理することになります。
これらのソースからビルドされた実行モジュールは、binの下に入るため、実行モジュール、ここでは go_webserverが読取る設定ファイルなどスタティックなファイルやサンプルデータなどは、どうやって、独立性を失わず、統合的にリポジトリを管理して、デプロイできる様にしたら良いのでしょうか?
.
├── bin
│ └── go_webserver <--- 実行形式のファイル
├── pkg
│ └── linux_amd64
│ └── github.com
│ ├── takara9
│ └── tools
├── src
│ └── github.com
│ ├── takara9
│ │ ├── go_util <--- 一つのリポジトリ (https://github.com/takara9/go_util)
│ │ └── go_webserver <--- これも独立のリポジトリ (https://github.com/takara9/go_webserver)
複数のリポジトリを統合するアプリをどの様に?
言い方を変えると、Go言語で書かれた2つのリポジトリを利用するアプリを開発するには、どうするか? という課題でもあります。
整理すると、以下3個のリポジトリになります。
- スタティック・コンテンツ、Cloud Foundry へデプロイするためのYAMLファイルなどのリポジトリ
- Go言語で記述したウェブサーバー、RESTサーバーのリポジトリ
- 2回目で開発した共通的な処理 go_util のリポジトリ
いきなり結論!?
パッケージマネージャーの機能などを調べて、いろいろ試行錯誤した結果、次の2つの動作で、3つのリポジトリの独立性を失わずに、Go言語のアプリを開発できる事がわかりました。
- git clone https://github.com/takara9/go_webpages --recursive
- bx cf push
複数のパッケージを統合するリポジトリの作り方
スタティックコンテンツや設定ファイルのリポジトリ作成
ワークスペース(プロジェクト)ディレクトリをつくって、移動します。
mkdir ~/go/go_webpages
cd ~/go/go_webpages
GOPATH環境変数をセットします。
export GOPATH=`pwd`
このGOPATHのルートには、以下の静的なファイルをセットされているものとします。 これをGitHubのリポジトリに登録して、必要なモジュールを関連づけていきます。
.
├── config.json <-- go_webserverの設定ファイル
├── manifest.yml <-- Cloud Foundry用のYAMLファイル
├── public <-- 公開用の任意のスタティック・コンテンツ
│ ├── gopher.png
│ ├── index.html
│ ├── style.css
│ ├── test_doc_1.html
│ └── tokyotower.jpg
└── README.md <-- 説明資料
Go言語で書いたコードのリポジトリから、マスタープロジェクトを取得して、パッケージマネージャのgodepを取得します。
この時、マスタープロジェクトである go_webserver2の中で、go_utilが参照されていれば、一回の go get
で一緒に取得されます。なんと便利ですよね。
godep により依存関係を解決する情報の追加
go get github.com/takara9/go_webserver2
go get github.com/tools/godep
コマンドのサーチパスを追加しておきます。godepは $GOPATH/bin にインストールされるので、動作いない時はパスを確認して見ましょう。
上記のコマンドを実行すると、以下の様に bin, pkg, srcが作成され、必要なモジュールがインストールされます。
$ tree -L 3
.
├── bin
│ ├── godep
│ └── go_webserver2
├── config.json
├── manifest.yml
├── pkg
│ └── linux_amd64
│ └── github.com
├── public
│ ├── gopher.png 以下省略
│
├── README.md
└── src
└── github.com
├── takara9
└── tools
export PATH=$GOPATH/bin:$PATH
マスタ・プロジェクトを指定して、godepで設定やコードを取得します。取得したコードはvendorディレクトリに配置されます。そして、パッケージマネージャの定義ファイルは、Godepsに置かれます。
godep save github.com/takara9/go_webserver2
コマンド godep の実行によって、Godeps のJSON定義ファイルが作成され、vendor ディレクトリ下にソースコードがコピーされます。
vagrant@vagrant-ubuntu-trusty-64:~/go/webapp03$ tree -L 3
.
├── bin
│ ├── godep
│ └── go_webserver2
├── config.json
├── Godeps <--- Godeps が作成
│ ├── Godeps.json
│ └── Readme
├── manifest.yml
├── pkg
│ └── linux_amd64
│ └── github.com
├── public
│ ├── gopher.png 以下省略
│
├── README.md
├── src
│ └── github.com
│ ├── takara9
│ └── tools
└── vendor <-- vendor が作成 srcがコピーされている
└── github.com
└── takara9
CloudFoundryにデプロイするために不要なというか、問題の原因となるファイルを削除しておきます。
rm -fr bin pkg src
GitHubへの登録
gitリポジトリとして初期化します。
git init
vender のしたのgo_utilやgo_webserver2は、削除して、GitHub でサブモジュールとして登録します。
rm -fr vender/github.com/takara9/go_util
rm -fr vender/github.com/takara9/go_webserver2
GitHubのサブモジュールとして、go_webserver2 と go_util を登録します。
$ git submodule add https://github.com/takara9/go_util.git go_util
$ git submodule add https://github.com/takara9/go_webserver2.git go_webserver2
この状態で、git add
、git commit
、git push
して、GitHubへ登録すれば完了です。
実行例
上記で作成したリポジトリから オプション --recursive
を付与して、submodule も含めてローカルにコピーします。
vagrant@vagrant-ubuntu-trusty-64:~/go$ git clone https://github.com/takara9/go_webpages --recursive
Cloning into 'go_webpages'...
remote: Counting objects: 27, done.
remote: Compressing objects: 100% (22/22), done.
remote: Total 27 (delta 6), reused 24 (delta 3), pack-reused 0
Unpacking objects: 100% (27/27), done.
Checking connectivity... done.
Submodule 'vendor/github.com/takara9/go_util' (https://github.com/takara9/go_util.git) registered for path 'vendor/github.com/takara9/go_util'
Submodule 'vendor/github.com/takara9/go_webserver2' (https://github.com/takara9/go_webserver2.git) registered for path 'vendor/github.com/takara9/go_webserver2'
Cloning into 'vendor/github.com/takara9/go_util'...
remote: Counting objects: 16, done.
remote: Compressing objects: 100% (14/14), done.
remote: Total 16 (delta 2), reused 15 (delta 1), pack-reused 0
Unpacking objects: 100% (16/16), done.
Checking connectivity... done.
Submodule path 'vendor/github.com/takara9/go_util': checked out '38ff0221e206b57cd7ea242e4f1238fb8f613b8a'
Cloning into 'vendor/github.com/takara9/go_webserver2'...
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 0), reused 6 (delta 0), pack-reused 0
Unpacking objects: 100% (6/6), done.
Checking connectivity... done.
Submodule path 'vendor/github.com/takara9/go_webserver2': checked out '25d39c2700995e71dbb9a3b9c80891cec437ffd5'
ここで、必要に応じて、YAMLファイルのホスト名が一意になる様に編集します。 そして、bx cf push
でデプロイ開始です。
vagrant@vagrant-ubuntu-trusty-64:~/go/go_webpages$ bx cf push
Invoking 'cf push'...
Using manifest file /home/vagrant/go/go_webpages/manifest.yml
Updating app go-webserver2 in org takara@jp.ibm.com / space dev as takara@jp.ibm.com...
OK
Using route go-webserver2.mybluemix.net
Uploading go-webserver2...
Uploading app files from: /home/vagrant/go/go_webpages
Uploading 24.5K, 23 files
Done uploading
OK
Stopping app go-webserver2 in org takara@jp.ibm.com / space dev as takara@jp.ibm.com...
OK
Starting app go-webserver2 in org takara@jp.ibm.com / space dev as takara@jp.ibm.com...
Creating container
Successfully created container
<途中省略>
Successfully destroyed container
1 of 1 instances running
App started
OK
App go-webserver2 was started using this command `go_webserver2`
Showing health and status for app go-webserver2 in org takara@jp.ibm.com / space dev as takara@jp.ibm.com...
OK
requested state: started
instances: 1/1
usage: 128M x 1 instances
urls: go-webserver2.mybluemix.net
last uploaded: Wed Jan 17 05:06:57 UTC 2018
stack: cflinuxfs2
buildpack: https://github.com/cloudfoundry/go-buildpack.git
state since cpu memory disk details
# 0 running 2018-01-17 05:08:15 AM 0.0% 4.8M of 128M 9.1M of 1G
最後のstate が、running となっていれば、デプロイ成功です。 urlsにあるアドレスをブラウザからアクセスします。
これで、ウェブページが表示されたら、成功です。
まとめ
個別の機能単位のgolangパッケージ、そして、アプリとして統合するリポジトリ、それらの依存関係を定義するgodepパッケージマネジャーの機能の関係が、これで全部繋がった様に思います。
さらに、Dockerコンテナにして、k8sでデプロイするには、どうするんでしょうね?