docker runコマンドが長いのでaliasで簡略してみた話

Linux環境でdockerを使おうと思った時の話です。 docker runを実行するときってたいていこんなふうに書きますよね?

$ sudo docker run -it --rm IMAGE COMMAND

IMAGE:イメージ名
COMMAND:実行したいコマンド

オプション抜きにしてもコマンドがそこそこ長くて、毎回docker...と書くのが面倒だなと思いました。 そこでいい感じに簡潔に表現できないかを考えました。

簡潔に表現してみる

このブログでは、rubyを例に扱います。 rubyのバージョンを表示するスクリプトsample.rbをコンテナで実行してみます。イメージはruby:2.7.1を使います。

$ cat sample.rb
#!/usr/bin/env ruby

p ENV['RUBY_VERSION']

特に工夫せずに実行するとこうなります。ちなみに /path/to/dirsample.rbがあるディレクトリです。

$ sudo docker run -it --rm --name ruby_sample -v /path/to/dir:/usr/src/myapp -w /usr/src/myapp ruby:2.7.1 ruby sample.rb
"2.7.1"

コマンドが非常に長いですね。。。Dockerfiledocker-compose.ymlを利用すれば多少は短く出来ますが、それでもまぁまぁ長いコマンドになります。

aliasを使ってみる

パッと思いついたのはaliasを設定すること。 この方法に関しては先行事例もあるようです。
ref:Dockerのコマンドが長いのでalias設定した - Qiita

例えば~/.bash_profileにこう書きます。 exec_sampleというaliasを設定しています。

alias exec_sample="docker run -it --rm --name ruby_sample -v /path/to/dir:/usr/src/myapp -w /usr/src/myapp ruby:2.7.1 ruby sample.rb"

aliasを設定したら実行してみます。 permission deniedが出てしまいました。 sudo権限がないとdockerコマンドの実行が出来ません。

$ exec_sample
docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.40/containers/create?name=ruby_sample: dial unix /var/run/docker.sock: connect: permission denied.
See 'docker run --help'.

ですがsudoをつけて実行してもcommand not foundになってしまいます。 sudoコマンドのあとに続くコマンドはaliasかどうかチェックされないためですね。

$ sudo exec_sample
sudo: exec_sample: command not found

sudoでaliasを効かせてみる

どうしたもんかと考えてたところ、こんな記事を見つけました。
ref:sudoコマンドでaliasを使えるようにする - Qiita

bashには「aliasの最後にブランクを含めると、次のコマンドもaliasかどうかを判定してくれる」という仕様があることを知りました。 以下はman bashより抜粋したものです。

 If the last character of the alias value is a blank, then the next command word following the alias is also checked for alias expansion. 

なので、"sudo "でaliasを設定してみました。ブランクを含めて設定するのがポイントです。

alias sudo="sudo "  # sudoに続くコマンドもaliasかどうか判定できるようにする
alias exec_sample="docker run -it --rm --name ruby_sample -v /path/to/dir:/usr/src/myapp -w /usr/src/myapp  ruby:2.7.1 ruby sample.rb"

もう一度sudoをつけて実行してみます。

$ sudo exec_sample
"2.7.1"

無事に実行できました。

ちなみに(未検証)

上記をやってから気づいたのですが、dockerコマンドをrootユーザ以外で実行できるようにする方法もありましたね。 これと組み合わせればsudoのaliasを設定しなくても実行できるかもしれません。

ref:Post-installation steps for Linux | Docker Documentation

最後に

rubyのコンテナを例に、docker run ...を簡潔に表現することを試してみました。運用上、何度も実行する必要がある場合に使ってみると良さそうです。 また、bashの「aliasの最後にブランクを含めると、次のコマンドもaliasかどうかを判定してくれる」という仕様は、dockerに限らず色んな場面で応用できるのではないかと思います。