Dockerfileでexpectする

はじめに

皆さんはDocker使っていますか?

私は使い捨て環境に色々入れてみて動きを確認したりして遊ぶ用途で使っています。

そんなとき、毎回これやってるなってやつを纏めておくと便利なのがDockefileです。

今回はDockerfileで対話が必要なツールを含む環境を用意するためにexpectをインストールする方法を共有できればと思います。

兎にも角にもこうやってます

以下の各ファイルを作成してcreate_docker_image.shを実行します。

以下では例としてadduserしたときに発生する対話をexpectで突破しています。

※全体的にサンプルで書いたものです。本当にテキトーなのは許してください。

Ex)

Dockerfile.base

FROM ubuntu:latest
RUN apt update && apt upgrade -y
ENV USER_NAME=dummyUsername
ENV PASS_WORD=dummyPassword
# expectをインストールするときに聞かれるタイムゾーンをスキップするためのリンクを生成
ENV TIME_ZONE=Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/$TIME_ZONE /etc/localtime && echo $TIME_ZONE > /etc/timezone
# 好きなツールを入れる
RUN apt install vim curl git expect fish sudo tmux -y
# 追加したユーザーをsudoグループに入れる
COPY ./adduser.sh /tmp/adduser.sh
RUN /bin/bash /tmp/adduser.sh $USER_NAME $PASS_WORD
RUN usermod -aG sudo $USER_NAME

adduser.sh

#!/bin/bash
expect -c "
set timeout 3
spawn adduser $1
expect \"password\"
send \"$2\n\"
expect \"password\"
send \"$2\n\"
expect \"Name\"
send \"\n\"
expect \"Num\"
send \"\n\"
expect \"Work\"
send \"\n\"
expect \"Home\"
send \"\n\"
expect \"Other\"
send \"\n\"
expect \"correct\"
send \"\n\"
interact
"

create_docker_image.sh

read -p "作成するイメージの名前を入力してください :" dockerImageName
read -p "コンテナで使用するユーザー名を入力してください :" containerUserName
read -p "コンテナで使用するユーザーのパスワードを入力してください :" containerUserPassword
sed s/dummyUsername/$containerUserName/ Dockerfile.base > tmp
sed s/dummyPassword/$containerUserPassword/ tmp  > Dockerfile
rm tmp
docker build . -t $dockerImageName
docker run -it -u $containerUserName $dockerImageName
sleep 1
rm Dockerfile

重要なのはDockerfile.baseのところに書かれているタイムゾーン周りのリンクを貼っているところです。

これによりexpectをインストールすることができるので幅が広がってすごかったという共有でした。