[小ネタ] Dockerコンテナを実行可能ファイルのように扱ってAWS CLIやREPLを実行する

Dockerコンテナを実行可能ファイル化しAWS CLIやREPLを実行する例をご紹介します。
2020.10.15

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、CX事業本部のうらわです。

DockerfileのENTRYPOINTにaws clits-node等の実行ファイルを指定すれば起動時にそのファイルを実行するコンテナを作成することができるため、Dockerコンテナをコマンドのように扱うことができます。

任意のコマンドをDockerで実行できるようにすれば使用しているPCにはDockerさえインストールされていれば良いため、PCに余計なものをインストールすることなくクリーンな状態を維持できます。

本記事では私のようにあまりグローバルにインストールしたくない派の方向けに、いくつかのDockerによるコマンド化の例をご紹介します。

※ 本記事ではDockerのインストール手順やdockerコマンドの細かい説明は割愛します。

※ いちいちDockerコンテナで実行するのは面倒では、と感じる方もいると思いますが、その通りだと思います。

AWS CLI v2

AWS公式でDockerイメージが管理されており、使用方法の詳細もユーザーガイドに記載されています。

認証情報と現在のディレクトリをコンテナにマウントしてaws cliを実行する場合のaliasは以下の通りです。

.zshrc

alias aws='docker run --rm -it -v ~/.aws:/root/.aws -v $(pwd):/aws amazon/aws-cli'

AssumeRoleして実行する場合はホストの環境変数の値をコンテナにセットします。

.zshrc

alias aws='docker run --rm -it -v ~/.aws:/root/.aws -v $(pwd):/aws -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN amazon/aws-cli'
$ aws --version
aws-cli/2.0.45 Python/3.7.3 Linux/4.19.76-linuxkit docker/x86_64.amzn.2

gore

GoのREPLです。さくっとGoのコードを試したいときに便利です。こちらはDockerfileが提供されています。

$ git clone https://github.com/motemen/gore.git
$ cd gore
$ docker build -t gore .
$ docker run -it --rm gore

.zshrc

alias gore="docker run -it --rm gore"

deno

deno入りのalpineイメージを利用します(非公式)。

$ docker run -it --rm --init hayd/alpine-deno:1.4.4
Download https://deno.land/std/examples/welcome.ts
Warning Implicitly using latest version (0.74.0) for https://deno.land/std/examples/welcome.ts
Download https://deno.land/std@0.74.0/examples/welcome.ts
Check https://deno.land/std@0.74.0/examples/welcome.ts
Welcome to Deno ?

REPLを起動します。

$ docker run -it --rm --init hayd/alpine-deno:1.4.4 repl
Deno 1.4.4
exit using ctrl+d or close()
>

.zshrc

alias deno="docker run -it --rm --init hayd/alpine-deno:1.4.4"

Dockerでの実行とは直接関係ありませんが、最近のリリースでトップレベルawaitを用いることでREPLでもmoduleのインポートができるようになったようです。

denoをさくっと試してみたい方には便利かと思います。

$ deno repl
Deno 1.4.4
exit using ctrl+d or close()
> const log = await import("https://deno.land/std/log/mod.ts")
Download https://deno.land/std/log/mod.ts
Warning Implicitly using latest version (0.74.0) for https://deno.land/std/log/mod.ts
Download https://deno.land/std@0.74.0/log/mod.ts
Download https://deno.land/std@0.74.0/log/logger.ts
Download https://deno.land/std@0.74.0/log/handlers.ts
Download https://deno.land/std@0.74.0/_util/assert.ts
Download https://deno.land/std@0.74.0/log/levels.ts
Download https://deno.land/std@0.74.0/fmt/colors.ts
Download https://deno.land/std@0.74.0/fs/exists.ts
Download https://deno.land/std@0.74.0/io/bufio.ts
Download https://deno.land/std@0.74.0/bytes/mod.ts
Check https://deno.land/std@0.74.0/log/mod.ts
undefined
> log.info('aaaa')
INFO aaaa
"aaaa"
>

ts-node

こちらは自作の例です。以下のようなDockerfileを用意します。

なるべくサイズを小さくしたいためベースイメージのOSはalpineを使っています。

実行時にtscのバージョンを出力したいのでENTRYPOINTにはシェルスクリプトを指定しています。

Dockerfile

FROM alpine:latest

RUN apk add --no-cache nodejs npm && apk add --update npm
RUN npm i -g typescript ts-node
COPY ./ts-node/init.sh /init.sh

ENTRYPOINT ["/init.sh"]

init.sh

#!/bin/sh

echo "tsc -v" && tsc -v
ts-node

ビルドします。

$ docker build -t d-ts-node .

aliasに設定します。

.zshrc

alias d-ts="docker run --rm -it d-ts-node:latest"

npmでグローバルにtypescriptとts-nodeをインストールしていなくてもts-nodeが使えるようになりました。

$ d-ts
tsc -v
Version 4.0.3
>

evcxr

Googleが開発しているRustのREPLを実行できるようにします。

Dockerfile

FROM rust:latest

RUN cargo install evcxr_repl

ENTRYPOINT ["evcxr"]
$ docker build -t d-rust .

.zshrc

alias d-rust="docker run --rm -it d-rust:latest"
$ d-rust
Welcome to evcxr. For help, type :help
>> println!("hello, world!");
hello, world!
>>

まとめ

ts-nodeと RustのREPLは以下のGitHubリポジトリにDockerfileを格納してあります。

REPLはローカルにインストールして実行するより遅いかもしれません。

業務でMacOS、プライベートでUbuntuと複数OSやPCを使っているとそれぞれにツールやコマンドをインストールするのが面倒になってくるので、Dockerコンテナで実行できるようにしておくと少し便利です。

参考

https://docs.docker.jp/engine/reference/commandline/run.html