概要
……のだってさ。それが特別なことであるなどと知らなくて、何も考えず 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 育成方法を使ったぜ。