補章3 DockerとSplash
はじめに
JavaScriptで動的にHTMLページが生成されるサイトをスクレイピングする場合、Splashを使う必要があります。その際にDockerを使うことが推奨されていますが、Dockerとは何なのでしょうか。ここではDockerの基本的な説明と使い方をまとめておきます。
ログインしてHello Worldする
まずはDockerにログイン(docker login)して、hello-worldというイメージを取得(docker pull <image>)します。
$ docker login
Username:****
Password:****
$ docker pull hello-world
Using default tag: latest
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:d58e752213a51785838f9eed2b7a498ffa1cb3aa7f946dda11af39286c3db9a9
Status: Downloaded newer image for hello-world:latest
docker.io/library/hello-world:latestホストにあるDockerのイメージの一覧(docker images)を確認します。第12章で利用したsplashと今回取得したhello-worldがあることがわかります。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
scrapinghub/splash latest 4ddd2efcb0df 5 months ago 2.17GB
hello-world latest bf756fb1ae65 5 months ago 13.3kBそれではhello-worldというイメージを使ってコンテナを作ります。hello-worldは、テキストを出力してコンテナから抜けるだけのものです。
Dockerのイメージの一覧(docker ps)を確認すると、hello-worldのステータスはExitedになっています。
これだとコンテナというのがよくわからないので、scrapinghub/splashイメージを使って、コンテナを起動してみます。
コンテナの状況を確認します。ステータスがUPになっていることがわかります。
この状況で作業なりを行って、必要なくなればコンテナを停止(docker stop <CONTAINER ID>)します。
これらの一連の作業をhello-worldでは、一瞬で作業しているので、コンテナというもののイメージが掴みにくいですが、Dockerイメージから、コンテナを作る、コンテナ環境で作業する、このコンテナをイメージにして他者も使えるようにすることで、環境を統一するというのが、Dockerの役割になるかと思います。
コンテナで作業
ここではDcokerイメージから、コンテナを作り、コンテナで作業したものをDocker Hubにアップロードし、そのイメージをもう一度、取得することで、環境を統一するというイメージを体験してみます。
まずはDocker HubにアップされているUbuntuのOSイメージを取得します。ここでは、いきなりdocker runしてみます。docker pullは必要ないのかというと、docker runしてホストにイメージがなければ、docker pullしてからdocker runしてくれます。ログの出力を確認すると、ローカルにイメージがないので、プルしておきますね、というメッセージが出力されています。
最後の部分では、ubuntuのbashが使える状態になっています。-itというオプションは、ubuntuを起動した際に、標準入力(stdin)のチャネルを開くことでインプット可能になる-i、表示を整える-tというオプションです。
コンテナ内で起動しているubuntuのbashを使って、バージョンを確認してみます。問題なくコンテナ内のubuntuを操作できるようになっています。
ここでイメージレイヤーについて少し補足をします。例えば、centOSのイメージでコンテナを作ると、このようにイメージレイヤーは1つ(6910e5a164f7)です。
ubuntuの場合は、a4a2a29f9ba4、127c9761dcba、d13bf203e905、4039240d2e0bの4つが取得されています。このイメージレイヤーを使ってコンテン内にubuntuを構築しています。
そのため、何らかの修正を加えた場合、新しい5個目のイメージレイヤが追加されることになります。ルートディレクトリにテキストファイルを追加し、コンテナから抜けておきます。
再度コンテナに入り、先程のテキストファイルが残っているか確認します。ステータスがexitedの場合は、コンテナに入ることができないので、リスタート(docker restart <CONTAINER ID>)してから、コンテナIDを使って入ります(docker exec -it <CONTAINER ID> bash)。
さきほど作ったサンプルファイルは消えずに残っていることが確認できます。
では更新されたコンテナをDockerファイル(docker commit <CONTAINER ID>)にしていきます。
Dockerイメージを確認します。新しいタグで先程コミットしたイメージが作られていることがわかります。
更新されたイメージをプッシュするためにタグ付けを行っておきます。
タグ付けしたイメージをプッシュするには、リポジトリが必要です。このリポジトリをDocker Hubに作っておきます。Docker Hubの「Create a Repository」を押して、

必要な情報を記入します。

これでプッシュするためのリポジトリが作られました。

ここに先程更新したイメージをプッシュ(docker push <REPOSITORY>)していきましょう。プッシュされたのは880a502881dcだけで、他のはlibrary/ubuntuからマウントされています。これは、DockerHubにあるUbuntuのイメージレイヤを共有しているためです。
Docker Hubを確認すると、問題なくプッシュされていることがわかります。

先程プッシュしたイメージは、他人が使うことになるので、この作業は必要ないですが、イメージがあるとDoker Hubから取得できないので、イメージを削除しておきます。
イメージを取得(docker pull)して、コンテナを作り(docker run)、更新されたイメージが取得できているか確認(cat)します。
更新されたイメージを取得できていることがわかります。このようにして、環境を統一することで、再現性を担保することになります。
Dockerファイル
Dockerイメージを作る元になるDockerファイルについて、簡単にまとめておきます。役割としては、DockerファイルからDockerイメージを作り、Dockerイメージからコンテナを作るための、大本の設計図となるのがDockerファイルです。ビルドの方法までは扱いませんが、Dockerファイルがどんなものなのかをまとめておきます。
DockerファイルをDockerインストラクションで構成されます。主なインストラクションとして、FROM、RUN、CMD、ADD、COPYなどがあります。DockerファイルはFROMから始まります。FROMでは基本的にはOSのイメージを指定します。RUNでは実行するLinuxコマンドを記載します。また、RUNごとにイメージレイヤーが作られます。Dockerファイルの末尾には、コンテナを立ち上げた際に実行したいコマンドを記載します。
このすごくシンプルなDockerファイルをイメージビルド(docker build)して、コンテナを構築すると、ubuntuのイメージからコンテナ内にubuntuを構築(ubuntu:latest)して、インストール可能なパッケージ一覧を更新(apt-get update)し、hoge、fuga、piyoをインストール(apt-get install)して、bashが使える状態(/bin/bash)でコンテナが立ち上がります。
DockerとScrapy
DockerでScrapyを動かすための最低限のDockerFile。
最終更新
役に立ちましたか?