Dockerfileでオリジナルのubuntu環境を作る

今回は、Dockerでオリジナルのubuntu18.04の環境を作るためにDockerfileというものを作成します。
Dockerfile リファレンスには、様々なコマンドの情報がありますが、今回は必要最小限の説明をしています。

まずは、不要なイメージ等を削除しておくと容量の節約になるので実施しておきましょう。
Dockerfileを作成するために作業する場所を準備します。

$ mkdir test-ubuntu
$ cd test-ubuntu

現在、ログインしているID情報を取得します。

$ id
id=1000(hoge) gid=1000(hoge) groups=1000(hoge),....

UIDとGIDは1000でした。
いよいよ、Dockerfileを作成します。

$ nano Dockerfile

Dockerfileには、下記の内容を記述します。

FROM ubuntu:18.04

ARG USERNAME=hoge
ARG GROUPNAME=hoge
ARG UID=1000
ARG GID=1000
RUN groupadd -g $GID $GROUPNAME && \
    useradd -m -s /bin/bash -u $UID -g $GID $USERNAME
USER $USERNAME
WORKDIR /home/$USERNAME/

簡単にDockerfileの説明を行います。

FROMはベースイメージを指定します。今回はubuntu:18.04としています。
ARGは構築時にユーザが渡せる変数を定義します。
RUNは新しいレイヤでコマンドを実行し、その結果を コミットします。
USERは実行ユーザを指定します。
WORKDIRは作業ディレクトリを指定します。

今回は、先ほど確認したidの情報を元にログインできるubuntu環境を構築してみます。
作成したDockerfileを元にイメージを作成するにはbuildコマンドを使用します。

使い方は

$ docker build [オプション] パス | URL | -

です。

今回、使用したオプションは

オプション 機能
-t 名前と、オプションでタグを 名前:タグ の形式で指定します
-f Dockerfileの名前を指定します

となっています。

それでは、実際にビルドしてみます。

$ sudo docker build -t ubuntu:test -f Dockerfile .
Sending build context to Docker daemon  2.048kB
Step 1/8 : FROM ubuntu:18.04
 ---> f5cbed4244ba
Step 2/8 : ARG USERNAME=hoge
 ---> Running in 8f006087f68a
Removing intermediate container 8f006087f68a
 ---> 0a0c8eb79848
Step 3/8 : ARG GROUPNAME=hoge
 ---> Running in 8052811701f1
Removing intermediate container 8052811701f1
 ---> c15cd6079941
Step 4/8 : ARG UID=1000
 ---> Running in aa430ccd72fd
Removing intermediate container aa430ccd72fd
 ---> 40cca9f05bc6
Step 5/8 : ARG GID=1000
 ---> Running in 998f03184de8
Removing intermediate container 998f03184de8
 ---> 37303fe82b6e
Step 6/8 : RUN groupadd -g $GID $GROUPNAME &&     useradd -m -s /bin/bash -u $UID -g $GID $USERNAME
 ---> Running in 4e7e2d71a8b8
Removing intermediate container 4e7e2d71a8b8
 ---> 79535674a7ac
Step 7/8 : USER $USERNAME
 ---> Running in 1934c709261a
Removing intermediate container 1934c709261a
 ---> bac3b576d779
Step 8/8 : WORKDIR /home/$USERNAME/
 ---> Running in 1381448a7d43
Removing intermediate container 1381448a7d43
 ---> 616d5dca1cf2
Successfully built 616d5dca1cf2
Successfully tagged ubuntu:test

ステップが8段階になっているのは、先ほどのDockerfileの中の命令が8つだったためです。

イメージを実行する

ビルドしたイメージを実行してみたいと思います。
実行はrunコマンドを使用します。

$ sudo docker run -d -it --name ubuntu-test ubuntu:test
8fbe8264de818356d3cdfcfb4e21c08e639f31783e5c661dff40856cb322fc76

無事に起動できたのか、コンテナを一覧表示してみます。
コンテナを一覧表示するには、psコマンドを使用します。

$ sudo docker ps
CONTAINER ID   IMAGE          COMMAND   CREATED              STATUS              PORTS     NAMES
8fbe8264de81   ubuntu:test    "bash"    About a minute ago   Up About a minute             ubuntu-test
614a7bee3e8c   ubuntu:18.04   "bash"    3 days ago           Up 3 days                     ubuntu-18.04

無事にコンテナが起動していることができました。

実行中のコンテナ内でコマンドを実行する

今回はバッググランドで実行中のubuntuのコンテナに対してログインします。

実行中のコンテナ内でコマンドを実行するにはexecコマンドを使用します。

$ sudo docker exec -it ubuntu-test bash
hoge@8fbe8264de81:~$ 

無事にログインが確認できました。プロンプトにはユーザー名が表示されています。

hoge@8fbe8264de81:~$ pwd
/home/hoge

ログイン後のディレクトリはユーザーディレクトリとなっています。

hoge@8fbe8264de81:~$ touch test
hoge@8fbe8264de81:~$ ls -l
total 0
-rw-r--r-- 1 hoge hoge 0 Apr 24 15:17 test

ファイルをタッチしてみます。
ファイルの属性は644の所有者は自分となっていました。

一旦、終了します。

hoge@8fbe8264de81:~$ exit
exit

psコマンドを使用してコンテナを一覧表示してみます。

$ sudo docker ps
CONTAINER ID   IMAGE          COMMAND   CREATED         STATUS         PORTS     NAMES
8fbe8264de81   ubuntu:test    "bash"    7 minutes ago   Up 7 minutes             ubuntu-test
614a7bee3e8c   ubuntu:18.04   "bash"    3 days ago      Up 3 days                ubuntu-18.04

コンテナの状態を確認するとログインしたshellを終了しても動作中であることが判ります。

コンテナを停止する

実行中のコンテナを停止するにはstopコマンドを使用します。

$ sudo docker stop ubuntu-test
ubuntu-test

psコマンドを使用して再びコンテナを一覧表示してみます。

$ sudo docker ps
CONTAINER ID   IMAGE          COMMAND   CREATED      STATUS      PORTS     NAMES
614a7bee3e8c   ubuntu:18.04   "bash"    3 days ago   Up 3 days             ubuntu-18.04

さきほど作成したコンテナは無事に停止したようです。

コンテナを再起動する

先ほど停止させたコンテナを再起動します。

$ sudo docker run -d -it --name ubuntu-test ubuntu:test
docker: Error response from daemon: Conflict. The container name "/ubuntu-test" is already in use by container "8fbe8264de818356d3cdfcfb4e21c08e639f31783e5c661dff40856cb322fc76". You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.

エラー表示を出して怒られてしまいました。

psコマンドを使用して再びコンテナを一覧表示してみます。

$ sudo docker ps -a
CONTAINER ID   IMAGE          COMMAND    CREATED          STATUS                     PORTS     NAMES
8fbe8264de81   ubuntu:test    "bash"     13 minutes ago   Exited (0) 3 minutes ago             ubuntu-test
614a7bee3e8c   ubuntu:18.04   "bash"     3 days ago       Up 3 days                            ubuntu-18.04

stopコマンドで停止したコンテナは存在したままだということが分かります。
コンテナを再実行するにはrestartコマンドを使用するのが正解です。

使い方は

$ docker restart [OPTIONS] CONTAINER [CONTAINER...]

です。

$ sudo docker restart ubuntu-test
ubuntu-test

再度、psコマンドで確認してみます。

$ sudo docker ps -a
CONTAINER ID   IMAGE          COMMAND   CREATED       STATUS                     PORTS     NAMES
8fbe8264de81   ubuntu:test    "bash"    6 hours ago   Up 19 seconds                        ubuntu-test
614a7bee3e8c   ubuntu:18.04   "bash"    3 days ago    Exited (0) 7 minutes ago             ubuntu-18.04

それでは、再度、ログインしてみます。

$ sudo docker exec -it ubuntu-test bash
hoge@8fbe8264de81:~$

さきほどタッチしたファイルを確認してみます。

hoge@8fbe8264de81:~$ ls -l
total 0
-rw-r--r-- 1 hoge hoge 0 Apr 24 15:17 test

ちゃんとファイルはありましたね。
再度終了します。

hoge@8fbe8264de81:~$ exit
exit

さて、一般ユーザーでログインできるのは良いのですが、実は多くのシーンでrootになる必要がでてきます。ということで、このままでは不便なので改良します。

sudoを追加してルートになる

先ほど作成したコンテナイメージを一度削除して、Dockerfileを改良します。

下記の内容を追加します。

RUN apt-get update && apt-get install -y sudo

ARG PASSWORD=${USERNAME}
RUN echo "${USERNAME}:${PASSWORD}" | chpasswd && \
    echo "${USERNAME} ALL=(ALL) ALL" >> /etc/sudoers.d/${USERNAME} && \
    chmod 0440 /etc/sudoers.d/${USERNAME}

追加する場所は、

USER $USERNAME
WORKDIR /home/$USERNAME/

の前に追加します。

これは、USER命令の後に追加すると、ユーザー権限で動作することになるためです。

再度ビルドを行いログインしてみます。

hoge@b3370ac94e3b:~$ cat /etc/sudoers.d/hoge
cat: /etc/sudoers.d/hoge: Permission denied
hoge@b3370ac94e3b:~$ sudo cat /etc/sudoers.d/hoge
hoge ALL=(ALL) ALL

先ほど同様に、ユーザーアカウントでログインし、/etc/sudoers.d/hogeを確認するとPermission deniedで怒られますが、sudoコマンドで無事に確認できることが確認できました。

日本語環境でもっと便利に

コンテナ内で日本語を使用したいシーンは多いはず。そこで、先ほどの環境を日本語環境化してみます。

下記の内容を追加します。

# 日本語関連のパーケージをインストール
RUN apt-get install -y language-pack-ja-base language-pack-ja

# ロケールを日本語に設定する
RUN update-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja" && \
    echo "export LANG=ja_JP.UTF-8" >> /home/$USERNAME/.bashrc

最終的なDockerfileはこのようになります。

FROM ubuntu:18.04

ARG USERNAME=hoge
ARG GROUPNAME=hoge
ARG UID=1000
ARG GID=1000
RUN groupadd -g $GID $GROUPNAME && \
    useradd -m -s /bin/bash -u $UID -g $GID $USERNAME

# sudoを追加してルートになる
RUN apt-get update && apt-get install -y sudo

ARG PASSWORD=${USERNAME}
RUN echo "${USERNAME}:${PASSWORD}" | chpasswd && \
    echo "${USERNAME} ALL=(ALL) ALL" >> /etc/sudoers.d/${USERNAME} && \
    chmod 0440 /etc/sudoers.d/${USERNAME}

# 日本語関連のパーケージをインストール
RUN apt-get install -y language-pack-ja-base language-pack-ja

# ロケールを日本語に設定する
RUN update-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja" && \
    echo "export LANG=ja_JP.UTF-8" >> /home/$USERNAME/.bashrc

USER $USERNAME
WORKDIR /home/$USERNAME/

実行結果はこのようになります。

hoge@84f24d954410:~$ cat /etc/sudoers.d/hoge
cat: /etc/sudoers.d/hoge: 許可がありません
hoge@84f24d954410:~$ sudo cat /etc/sudoers.d/hoge
hoge ALL=(ALL) ALL

これで、自分だけのオリジナルのubuntu環境ができました。

Linux

前の記事

Dockerでubuntu18.04を動かす
Linux

次の記事

ラズパイでapache