オープンソースこねこね

Webプログラミングなどについてあれこれ。

Githubのリポジトリをyumリポジトリとして使う

簡単にできた。手順は後ほど。

背景

普段使っているサーバOSはCentOSなので、自作のOSSツールなどをyumコマンドを使ってさくっとインストールしたい。RPMを作るところまではスクリプト化してあって一発でできるようになっている。yumリポジトリをどうするか。今まではbintrayで個人用のyumリポジトリを立てて使っていました。

bintray.com

ところが、先日このbintrayのyumリポジトリから古くてもう使っていないパッケージを削除しようとしたところ「公開後180日たつと削除できない」とエラーになってしまいました。

結局この後、bintrayのサポートに問い合わせてみたら、わりとすぐに削除してくれたのですが、今後パッケージが要らなくなって消そうとするたびに、問い合わせしなくてはならないのかな、、、と思うとちょっとツライです。

そんなわけで代替となるyumリポジトリをホストしてくれるサービスを探していたりしました。packagecloud.ioなどを見てみましたが、いまひとつ使う気になれず。。。

packagecloud.io

そこで昔yumリポジトリを個人サーバに立てたときのことを思い出してみると、結局必要だったのはただのhttpサーバだけだったはずでは。それならGithub Pagesを使えばGithub上にyumリポジトリも立てられるんじゃないかなと思い至り、ちょっとググったら、かなり前にやっぱり同じことをやっている人がいた。

qiita.com

この記事を参考にして、今はgh-pagesのブランチを切る必要もないし、SSLも対応しているので、その辺をふまえて以下のようにやりました。

作業手順

Githubリポジトリを作る

何でもいいですが、ここではリポジトリ名はyumrepo-exampleとします。作成後リポジトリの設定画面からGithub Pagesの設定をします。Sourceをmasterブランチに設定すれば昔のようにgh-pagesのブランチを切る必要もないです。

f:id:kohkimakimoto:20170721194716p:plain

リポジトリをcloneしてRPMファイルを配置する

上記のリポジトリをローカルにcloneし、サポートするディストリビューションアーキテクチャなどで、適当にサブディレクトリを作成してその中にホストしたいRPMファイルをおきます。試しに拙作であるプロビジョニングツールのcofuのRPM

https://github.com/kohkimakimoto/cofu/releases

からダウンロードしてCentOS6とCentOS7用に配置します

$ mkdir el6-x86_64 el7-x86_64
$ curl -L -o el6-x86_64/cofu-0.6.0-1.el6.x86_64.rpm   https://github.com/kohkimakimoto/cofu/releases/download/v0.6.0/cofu-0.6.0-1.el6.x86_64.rpm
$ curl -L -o el7-x86_64/cofu-0.6.0-1.el7.x86_64.rpm   https://github.com/kohkimakimoto/cofu/releases/download/v0.6.0/cofu-0.6.0-1.el7.x86_64.rpm

createrepoコマンドでリポジトリのメタファイルを作る

createrepoコマンドでyumリポジトリに必要なメタファイルを生成します。Macで直接動作するcreaterepoコマンドはないのですが、dockerを使えばこのあたりも簡単にできます。以下のようにしてbashスクリプトcreaterepoとして作成します。

$ echo '#!/usr/bin/env bash
docker run --rm  -u "$(id -u):$(id -g)" -v $PWD:/build -w /build kohkimakimoto/rpmbuild:el7 createrepo "$@"' > createrepo
$ chmod 755 createrepo

そして、RPMを配置したサブディレクトリを指定して実行します。

$ ./createrepo el6-x86_64
Spawning worker 0 with 1 pkgs
Spawning worker 1 with 0 pkgs
Spawning worker 2 with 0 pkgs
Spawning worker 3 with 0 pkgs
Workers Finished
Saving Primary metadata
Saving file lists metadata
Saving other metadata
Generating sqlite DBs
Sqlite DBs complete

$ ./createrepo el7-x86_64
Spawning worker 0 with 1 pkgs
Spawning worker 1 with 0 pkgs
Spawning worker 2 with 0 pkgs
Spawning worker 3 with 0 pkgs
Workers Finished
Saving Primary metadata
Saving file lists metadata
Saving other metadata
Generating sqlite DBs
Sqlite DBs complete

後はコミットしてpushすれば完了です。なおRPMを更新したら都度同じようにcreaterepoスクリプトを実行してメタファイルも更新します。

yumでインストールしてみる

リポジトリができたのでyumでインストールしてみます。以下の例はCentOS7でやった際のもの。リポジトリのパスなどは適宜読み替えてください。

まずリポジトリの設定をして

$ sudo sh -c 'echo "[github-yumrepo-example-el7-x86_64]
name=github-yumrepo-example-el7-x86_64
baseurl=https://kohkimakimoto.github.io/yumrepo-example/el7-x86_64
gpgcheck=0
enabled=1
" > /etc/yum.repos.d/github-yumrepo-example-el7-x86_64.repo'

あとは普通にyum installする

$ sudo yum install cofu

以上です。サンプルのリポジトリは以下においておきます。

github.com

開発環境用に自己署名SSL証明書をつくるスクリプトを書いた

外部からアクセスできるサーバ環境の場合はLet’s Encryptを使うことで手軽にSSL証明書を設定できるようになったのですが、ローカルマシンにVagrantでたてた開発用VMの場合はそうもいかず、この場合は自己署名のSSL証明書をつかっています。

証明書の発行は普通にopensslコマンドを手作業で叩いてやってたんですが、

  • Chromeだと-extfileオプションで追加のパラメータを指定しないと、Macのキーチェーンにインストールした自己署名証明書がエラーになるので、すこし作業の手間が増えた
  • ローカル環境への名前解決をxip.ioなどのワイルドカードDNSを使うようになって、利用するホスト名がmyapp.192.168.0.10.xip.io,myapp2.192.168.0.10.xip.ioのように多くなった
  • xip.ioで名前解決する構成上、サブドメインへの階層が深くなりワイルドカードの証明書が使えなくなったため、ドメイン名ごとに証明書を発行する必要がある

などの理由で、作業がちょっと煩雑になってきたのでスクリプト化しました。

github.com

Bashスクリプト実装です。引数にドメイン名を指定して(複数指定も可)実行すると

$ selfsigned-crt example.com

以下のように秘密鍵CSR、証明書を吐き出します。有効期限は100年。

example.com-selfsigned.key
example.com-selfsigned.csr
example.com-selfsigned.crt

あとはこの生成した証明書をサーバに配置すればいいのですが、自分の場合、開発環境のプロビジョニングツールに、このスクリプトを実行させるようにレシピを書いておいて、証明書の生成もプロビジョニングツールにやらせてます。自作ツールのcofuを使うと以下のような感じ、

execute "generate-self-signed-ssl" {
    command = [=[
        selfsigned-crt -o /etc/nginx/ssl myapp1.192.168.1.10.xip.io
    ]=],
    not_if = "test -f /etc/nginx/ssl/myapp1.192.168.1.10.xip.io-selfsigned.crt",
}

これで開発環境をセットアップするときに、自動的に証明書も作成できるようなりました。

関連外部リンク

Visual Studio CodeからMacの辞書(Dictionary.app)を開くエクステンションをつくった

kohkimakimoto.hatenablog.com

これのvscode版。LL書く用のエディタをvscodeにしたのでIntelliJatomでやってたように、CTRL+CMD+Kで辞書を起動できるようにしてみました。

marketplace:

marketplace.visualstudio.com

github repository:

github.com

表示名Mac Dictionaryでmarketplaceに公開したので、適当に検索してインストールしてください。vscodeだとCTRL+CMD+Dで簡易辞書がひけるのでそれを使ってもいいのだけど、atomIntelliJで上記プラグインを使ってたせいで、直接辞書をひくのに慣れてしまった。vscodeでもそういうのが欲しくなり、やっぱり作ってみました。

f:id:kohkimakimoto:20170511103121g:plain

SSHラッパーコマンドEsshのv1.0.0をリリースしました

Esshは、zsh補完やLuaスクリプトによる動的なコンフィグレーションなど、便利機能を実装した、sshのラッパーコマンドです。

github.com

ドキュメントをまとめたWebサイトも作成しました。

https://essh.sitespread.net/

上記Webサイトのトップにasciinemaで撮ったターミナルオペレーションのデモを乗せましたので、そちらを見ていただければ、どういったものか大体のことはわかると思います。

開発の経緯

2015/11に以下の記事を書き、Zsshというコマンドを作成しました。

kohkimakimoto.hatenablog.com

その後、CentOSリポジトリzsshというパッケージが存在していたため、コマンド名をzsshからesshに変え、自分の利用にあわせて、適宜、機能の追加や変更を続けていました。そして、自分が使う上で必要十分な機能がそろって、大きな変更もなくなってきたので、この度これをv1.0.0としてリリースすることにしました。なお2015/11時点のものとは仕様が大きく様変わりしており、以下に改めて、機能について説明します。

機能

EsshはGoで書かれたシングルバイナリのCLIツールで多機能sshコマンドとして利用できます。実装的には内部でsshコマンドを実行するラッパーコマンドになっています。標準のsshコマンドでは使えない以下のような機能が利用できます。

  • Luaによる設定ファイル。これによりSSH接続サーバの設定(ssh_config)をより動的に構築することができる。
  • サーバ接続、切断時に発火するフックコマンドを設定できる。
  • サーバにタグをつけられ、一覧をターミナルに出力できる。
  • ZshBash用の強力な補完を組み込みで提供。
  • カレントディレクトリごとに設定ファイルの切り替え。
  • Capistranoのような複数サーバに並行してコマンドを実行できるタスクランナー。
  • 設定用のLuaコードはモジュールとしてGitリポジトリ上で共有できる。

一通りの機能に触れるためのチュートリアルを用意したので、利用の際はここから始めるとよいかと思います。

https://essh.sitespread.net/intro/ja/index.html

利用例

上記のチュートリアルには書いていないが、私個人が使っている機能などを中心にいくつか紹介します。

ログイン時にターミナルの色を変える

接続、切断時のフックコマンドhooks_before_connecthooks_after_disconnectでターミナルの色を変えます。私は本番環境につなぐときは赤にしています。

-- ~/.essh/config.lua

-- 事前にmacのターミナル設定でRedとBlackというプロファイルを作っておく
local red_screen_command    = "osascript -e 'tell application \"Terminal\" to set current settings of first window to settings set \"Red\"'"
local black_screen_command  = "osascript -e 'tell application \"Terminal\" to set current settings of first window to settings set \"Black\"'"

host "webserver-01" {
    HostName = "192.168.56.32",
    Port = "22",
    User = "kohkimakimoto",
    description = "web server-01",
    hooks_before_connect = { red_screen_command },
    hooks_after_disconnect = { black_screen_command },
    tags = {
        "web",
    },
}

host "webserver-02" {
    HostName = "192.168.56.33",
    Port = "22",
    User = "kohkimakimoto",
    description = "web server-02",
    hooks_before_connect = { red_screen_command },
    hooks_after_disconnect = { black_screen_command },
    tags = {
        "web",
    },
}

f:id:kohkimakimoto:20170410083157g:plain

sshrcをつかってbashの設定を送り込む

sshrcという、SSHサーバに.bashrcなどをログイン時にクライアントから送り込むスクリプトがあるのですが、それをesshのフックで使えるようにしたモジュールを書いたので、これを使うとサーバ側の設定なしに、SSHサーバのログインシェル環境をカスタマイズできます。

-- ~/.essh/config.lua
local sshrc = import "github.com/kohkimakimoto/essh/modules/sshrc"

host "webserver-01" {
    HostName = "192.168.56.32",
    Port = "22",
    User = "kohkimakimoto",
    description = "web server-01",
    hooks_after_connect = { sshrc({sshhome = "$HOME/.sshrc"}) },
    tags = {
        "web",
    },
}
# $HOME/.sshrc

# aliases
alias ll='ls -al'

# functions
function foo() {
    echo "foo"
}

f:id:kohkimakimoto:20170410103519g:plain

本当はpecoを使ったスニペット関数などを送り込んでいるのですが、長くなるので割愛します。この辺はまた別の記事でフォローしようかと思います。

アプリケーションのデプロイ

リモートサーバにコマンドを実行します。以下はただのサンプルです。実環境ではもっと複雑なスクリプトを実行させています。

host "webserver-01" {
    HostName = "192.168.56.32",
    Port = "22",
    User = "kohkimakimoto",
    description = "web server-01",
    tags = {
        "web",
    },
}

host "webserver-02" {
    HostName = "192.168.56.33",
    Port = "22",
    User = "kohkimakimoto",
    description = "web server-02",
    tags = {
        "web",
    },
}

task "deploy" {
    backend = "remote",
    targets = {"web"},
    prefix = true,
    parallel = true,
    script = [=[
        echo "deploy app to $ESSH_HOSTNAME"
        
        # your deploy commands...

        echo "Done."
    ]=],
}

f:id:kohkimakimoto:20170410104414g:plain

以上です。日々のSSHライフのお供に、どうぞお使いください。m( )m

ReactNativeのiOSアプリをオフラインの実機で動かす

※2017-04-10現在のメモ。

先に結論。以下の#if !(TARGET_IPHONE_SIMULATOR)で囲った部分のコードをios/AppName/AppDelegate.mに仕込むといいです。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  NSURL *jsCodeLocation;

#if !(TARGET_IPHONE_SIMULATOR)
  jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#else
  jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
#endif

  RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                      moduleName:@"AppName"
                                               initialProperties:nil
                                                   launchOptions:launchOptions];
  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];

  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [UIViewController new];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];
  return YES;
}

経緯

ReactNativeでiOSアプリを作ってみてます。SwiftやObjective-Cで作ったアプリのように、開発中のアプリをUSBケーブルにつないだiPhoneにインストールして、動作確認してみようとしたら、うまくアプリが立ち上がらない。ドキュメントやGithubのissuesをみるとiPhoneが同じwifiにいないと動作しないらしいです。

「react native offline」とかで検索するとstackoverflowやgithubのissuesで、対処法が書いてあるが、今ひとつうまくいかない。というか、ReactNativeの更新が速いせいか、いまでは通用しない古い情報がまじっていてよくわからないです。で、Objective-Cは以前触ったこともあってソースが読めるので、直接ソースを追ってみました。それでわかったこととして

  • 開発中ReactNativeは開発マシン上にhttpサーバを起動し、アプリはこのhttpサーバからJavaScriptコードを取得する。
  • この仕組みのおかげで、開発中再ビルドなしで、変更を反映させられる。実機の場合も同様だが、オフラインだとhttpサーバに到達できず、エラーになる。
  • ビルド時、リリースビルド用にJavaScriptを一つのファイルにまとめてアプリにバンドルするスクリプトが、XCodeのrun scriptで定義されている。
  • リリースビルドの場合のみ、httpサーバからではなくファイルからJavaScriptを読むようにマクロで制御されている。

というわけで冒頭に記載したようにios/AppName/AppDelegate.m内のコードを

#if !(TARGET_IPHONE_SIMULATOR)
  jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif

のようにして「シミュレータ以外のとき」という条件で、JavaScriptのロケーションを設定している変数を、リリースビルドのときと同様に、バンドルされたJavaScriptファイルを読みに行くよう上書きすればOKです。この場合当然、実機上で動かすと、再ビルドなしでコードの変更を反映させることはできなくなるので、それが必要なときは都度この部分を削除やコメントアウトするなりして、対応すればいいかな、と。今のところは。

OmnibusでPHPアプリケーションをRPMにパッケージングする

要約: Omnibusを使うとApachePHPをバンドルしたオールインワンなPHPアプリケーションのRPMパッケージを作れます。

最近CLIツールやAPIサーバなどはGoで書くようになって、PHPをさわる頻度が減ってきているのですが、それでもPHPの実行環境が不必要になることはなく、その個人的な一つの理由にAdminerがあります。これは2012年に一度ブログにも書いたのですが、PHPのシングルファイルをDocumentRootにおくだけで動作する、データベース用のWebUIです。

Adminer - PHPの1ファイルを置くだけで簡単に使えるDB管理ツール - オープンソースこねこね

現在でもメンテは続いているようで、今ではElasticsearchやMongoDBなどにも対応しているそうな。個人的にもずっと使い続けています。

ただ、前述のようにGoの適用範囲が広がってきたので、新しく立ち上げたサーバとかだと、Adminerを使う以外にApachePHPが必要ない環境もあります。後々の運用管理のことも考えてサーバ構築にはプロビジョニングツールを使っていることもあり、これ一つのために、ApachePHPを入れてhttpd.confとphp.iniを書き換えるレシピ書いて。。。てなことがやや面倒くさいです。

Adminerの機能単体でぱっとインストール、アンインストールできればいいかもしれない、と考えたので、omnibusを使ってApachePHPをバンドルしたオールインワンなPHPアプリケーションのRPMを作成してみました。omnibusについては以前ブログに書いたのでそちらを参照してください(CentOS用にSupervisor3.3.0のRPMパッケージを作成した - オープンソースこねこね )。今回の成果物は以下

github.com

Githubのリリースページに生成したRPMをあげたので

$ sudo yum install https://github.com/kohkimakimoto/omnibus-adminer-server/releases/download/v0.3.0/adminer-server-0.3.0-1.el7.x86_64.rpm

でインストールできます。これだけで/opt/adminer-serverApachePHPランタイムを含めたアプリケーションがインストールされます。これらはもちろんシステムワイドにあるApachePHPとは干渉しません。あとは、

$ sudo systemctl start adminer-server

とすればApacheが14200ポートで起動しますのでブラウザでhttp://localhost:14200/adminer.phpにアクセスすると

f:id:kohkimakimoto:20170329115005p:plain

と画面がでます。

補足

  • サービス設定は現状systemdのみの対応なので、このRPMはCentOS7限定です。initスクリプトを書けばCentOS6などにも対応できますが、自分が使わないので書いてません。
  • 設定ファイルは/etc/adminer-server、adminer.phpなどのPHPファイルは/var/lib/adminer-server以下に配置してあります。
  • 今回はやってないがMySQLなどDBもバンドルすれば、いわゆるLAMPアプリケーションがパッケージ配布可能になるんじゃないかと。

あとがき

こんなことしなくても、今はDocker使えばいいかも、とも思いますが、Systemdにサービスを登録するところまでyum installlでできるのでミドルウェア的なものを扱うのなら、RPMも便利ですよと。。。

テストやビルドスクリプトをDockerコンテナで実行させるための便利ツールを作った

ある程度複雑なプログラムだと、ローカル環境やCIサーバ環境など、どこでも動くようにテストを書くのが難しくなったりします。また、昨今のWebアプリケーションだと、デプロイ前に何らかのビルドプロセスが必要になることがほとんどで、依存物をインストールしたり、Webpackを動かしたり、Goのビルドを走らせたりします。こういうタスクもnodeやらGoに依存していて、複数の環境で差異なく動かすことを考えると、いろいろツライものがあります。

そこで、こういったテストやビルド処理はシェルスクリプトを書いて、Dockerコンテナ内で動かすことによって環境に対しての依存を解消していました。 たとえばGo言語の場合以下のようなテスト実行スクリプトtest_run.shを書いておきます。

#!/usr/bin/env bash
set -eu

go test $GOTEST_FLAGS $(go list ./... | grep -v vendor)

そしてこれをDockerコンテナで実行するためのスクリプトとして以下のようなtest.shを書きます。

#!/usr/bin/env bash
set -eu

DOCKER_IMAGE=${DOCKER_IMAGE:-'kohkimakimoto/golang:centos7'}
GOTEST_FLAGS=${GOTEST_FLAGS:--cover -timeout=360s}

repo_dir=$(cd $(dirname $0); pwd)

docker run \
  --env GOTEST_FLAGS="${GOTEST_FLAGS}" \
  -v $repo_dir:/build/src/github.com/username/repo \
  -w /build/src/github.com/username/repo \
  --rm \
  ${DOCKER_IMAGE} \
  bash ./test_run.sh

goコマンドなど、テストに必要な環境は全てDockerイメージとして用意しておきます。あとはリポジトリのルートにいる状態で./test.shを実行すれば、テストが実行されます。TravisCIのようなCIサーバはDockerに対応しているので、同様に./test.shを実行するだけで、ローカル環境と同じようにテストが実行できます。テストコード側で環境の違いを意識する必要はなくなります。

ところで、しばらくこの方式でやっていたところ、以下のような課題が浮き彫りになってきました。

  • 新しいプロジェクトごとにシェルスクリプトをコピペ、修正して使いまわしている。
  • これらのスクリプトはだいたい似たようなコードになりがちだが、利用するDockerイメージやdocker runのオプションなどが微妙にちがう。
  • テストやビルドなど個々のタスクごとに「実際のタスクを実行するスクリプト」と「それをDockerコンテナで実行するスクリプト」の2つのファイルを作る必要があり、数が増えるとファイルがごちゃごちゃしてきた。

ベタに書いたシェルスクリプトによる実装なので、プロジェクトが増えると、共通化などができずコードが冗長になりがちでした。そこで、大雑把に処理を整理してみると

  • カレントディレクトリをDockerコンテナの特定の場所にマウントする
  • --rmオプションをつけて、コンテナ停止後自動でコンテナを削除するようにする
  • スクリプトを実行する。

などが共通な処理であったので、これらをまとめて、いい感じにDockerコンテナを起動してその中でスクリプトを実行するコマンドラインツールを作りました。

github.com

Goで実装したシングルバイナリなので、Githubのリリースページからバイナリをダウンロードして、パスの通ったディレクトリに配置すればすぐに使えます。

使い方

まずは単純に

$ buildsh

を実行してみます。これだけで、デフォルトでDockerイメージkohkimakimoto/buildsh:latest(2Gくらいあります)をダウンロードして、カレントディレクトリをコンテナ内の/buildにマウントした状態でコンテナを起動します。そのままbashでログインした状態になるので、たとえばPHPのテストだったら

$ php phpunit

などを実行すればテストができます。PHPPython,nodeなど主なLLのランタイムを入れてあるので、ホストマシンの環境に関係なくすぐにテストやビルドができます。作業が終わったら

$ exit

すれば、ホストマシンにもどってコンテナが破棄されます。特定の環境でちょっとしたことを動作確認したい場合などに便利に使えます。

そしてテストやビルドのシェルスクリプトを実行させたい場合は

$ buildsh test.sh

のようにスクリプトファイルを指定して実行すれば、そのスクリプトがDockerコンテナ内で実行されます。これで用意するスクリプトはテストを実行する部分のみでよくなり、「それをDockerコンテナで実行するスクリプト」を書く必要がなくなりました。

設定ファイル

使用するDockerイメージを変更したい場合などは、設定ファイルを利用することができます。.buildsh.ymlをカレントディレクトリに配置してください。以下のような設定ができます。

use_cache: true
docker_image: kohkimakimoto/buildsh:latest
additional_docker_options: --net=host -v=/var/run/docker.sock:/var/run/docker.sock
environment:
  FOO: bar
  FOO2: bar2
home_in_container: /build/src/github.com/kohkimakimoto/buildsh

詳細はREADME.mdを参照していただくとして、いくつかピックアップして概要を説明します。

use_cache

use_cacheはtrueにするとカレントディレクトリ配下に.buildsh/cacheディレクトリを作り、コンテナ内でパスを環境変数BUILDSH_CACHEDIRに設定します。これはスクリプト実行ごとに破棄されてしまうコンテナ内のデータを保存するときに使うことができます。たとえばyarn installを以下のようにすれば、キャッシュを保持できて、次回以降の処理の高速化が望めます。

$ yarn install --cache-folder=$BUILDSH_CACHEDIR/yarn

.gitignore.buildshを追加するのを忘れずに。。。

docker_image

docker_imageは利用するDockerイメージです。自分の用途に合わせて好きなイメージを使えます。

additional_docker_options

additional_docker_optionsは内部で実行しているdocker runに付け加えるオプションを指定できます。例のように-v=/var/run/docker.sock:/var/run/docker.sockを利用すればDockerコンテナ内から新しくDockerコンテナを立ち上げることもできたりします。

home_in_container

home_in_containerはコンテナ内でホストのカレントディレクトリがマウントされるパスを変更できます。デフォルトは/buildですが、例えばGoのテストやビルドをおこなうとき、GOPATHの関係上/build/src/github.com/kohkimakimoto/buildshのようにGOの流儀にそったパスに配置したいことがあります。この設定を使うことでそのようなケースに対応できます。

実装について

このツールはつまるところ、テストやビルド目的の使い捨てコンテナである場合docker runにセットするオプションや引数がおおむね共通化できるので、それをまとめたラッパーコマンドというわけです。

もともとはbashスクリプトで書いていたこともあって、実装は単純なdocker runのラッパーコマンドになっているので、メインのコードはbuildsh.goのみです。なのでをこれを見れば何をやっているのか大体わかりますので、細かいことはソースを見たほうが早いかもしれません。