概要

……のだってさ。それが特別なことであるなどと知らなくて、何も考えず ubuntu:latest の中に docker コマンドをインストールしてみたのだが動かなくて困ったよ。具体的には

Cannot connect to the Docker daemon at unix:///var/run/docker.sock.
Is the docker daemon running?

こんなエラーが出ちまう。 docker-in-docker ではいつも使っている docker daemon を起動できないようなんだよな。 docker-in-docker は特殊なことであり、基本的には出来ないと思ってよさそう。ただ、やろうと思えばできるようなのでやってみよう。

やり方はふたつある。特別な docker image を --privileged オプションで使う方法と、いつも使っているホストマシン側の docker daemon を、 container から使わせてもらう方法。今回は後者を使う。

 

後者を使う理由

今回は、 “ubuntu の中で docker を使う” というのを再現してみたい。なので image として ubuntu を選択できるのでなければ意味がないんだ。あと、前者のやり方では、 container を作るたびにホストマシン側に不要なデータが溜まってしまうらしいよ。

 

緑さんなりに docker-in-docker を実現してみる

とりあえず Dockerfile を用意しよう。

FROM ubuntu:latest

WORKDIR /

RUN apt update
# lsb-release は ubuntu のバージョンを簡単に見るツールです。
RUN apt install -y lsb-release
# デフォルトで sudo は入っていなかったので。
RUN apt install -y sudo

# 以下、 docker の公式ドキュメント
# "Install Docker Engine on Ubuntu" 通りのコマンドを書いていく。
# いまここで記事に書いていくよりも、
# これを見たときの最新のコマンドを使ったほうがいいと思うから、
# 公式ドキュメントの URL だけ記しておく。ここを参照してくれ。
# https://docs.docker.com/engine/install/ubuntu/

# ただし、一番最後 docker のインストール確認の hello-world は書かないこと。
# これのことね↓
# RUN sudo docker run hello-world

こんな感じ↑で用意した。ホストマシンで docker をインストールするだけなら hello-world 出来るのだけど docker-in-docker では、このままでは、不可。

用意した Dockerfile で image を用意 (build) するぞ。

# 一応、ホストマシンに docker があることを確認。
docker --version

# Build an image from ./Dockerfile
docker build -t my-image .

これで、 “docker engine がインストールされた ubuntu“ という image が “my-image” という名前で完成したぞ。

そして、 “ホストマシン側の docker daemon を、 container から使わせてもらう” という設定を入れつつ container を作る。

# Create container from the image.
docker run -it -d \
    --name my-container \
    -p 8888:80 \
    -e FOO=foo \
    -v /var/run/docker.sock:/var/run/docker.sock \
    my-image

-p とか -e とかは何となく入れているだけなので気にしなくていいぞ。大切なのは -v だ。ホストマシンの docker.sock を、 container と共有する設定だ。ホストマシンが Windows の場合でも同じ場所にあるのかは知らん。

こうすりゃ、我々の container の中で docker コマンドが使えるようになるぜ。

# Enter in the container.
docker exec -it my-container sh

# なんとホストマシン側にある image 一覧が出てくる。
# 面白い。
docker images

# ホストマシン側に hello-world image が DL されて、
# docker コマンドのインストールテストが完了する。
docker run hello-world

以上だ。 docker-in-docker を実現できたぞ! あと一応、コンテナを片付けるコマンドも載せておくか。

docker stop my-container && docker rm my-container

 

おしまい

Docker image 構築の作業をするときは、前回の記事に書いたような、 image 育成方法を使ったぜ。