Dockerを使うことになりました。Docker初心者&Dockerを実際に触った経験が少ない、というのがあって、不安が多いです。
こういう不安は、とりあえず触ってみると解消されることが多いので、簡単にDockerを触りつつ、不安を解消しました。
環境
僕の手元の環境はmacOSです。Sierraです。
予備知識
以下のあたりが参考になります。
用語
- Docker
- Widows, Mac, Linuxで動く仮想マシンを管理するソフトウェアです。
- Dockerイメージ
- Dockerで作成する仮想マシンの元です。ここにOSのイメージとかミドルウェアが入ってます。
- Dockerコンテナ
- Dockerイメージを使って、作った仮想マシンのことです。インスタンスみたいなもので、揮発性です。
- DockerFile
- Dockerイメージを使って、Dockerイメージを作る設計ファイルです。Dockerイメージは、公式のものを使って、DockerFileでファイルを読み込みつつ、自分が使うDockerイメージを作ったりできます。
Dockerのインストール
Dockerを使うために、Dockerをインストールします。
繰り返しになりますが、Dockerは、仮想マシンを管理する仕組みなので、まずは管理するヤツをインストールする必要あります。
公式から、Docker for MacをDLして、適当にインストールします。dmgでした。
バージョンも確認できました。
$ docker -v Docker version 18.03.1-ce, build 9ee9f40
手元のDockerイメージの一覧を確認
また、繰り返しになりますが、Dockerには、仮想マシンを作る元になるDockerイメージというものがあります。
docker images
を打つと、手元にあるDockerイメージの一覧が見れます。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE
まあ、今は何もないんですが。
Dockerイメージを検索
DockerイメージはDockerのリポジトリで多数公開されているらしいです。
で、Dockerのリポジトリにどんなイメージがあるかは、 docker search
コマンドで確認することができます。
今回は、Pythonに関係するDockerイメージを探して見ます。
$ docker search python NAME DESCRIPTION STARS OFFICIAL AUTOMATED python Python is an interpreted, interactive, objec… 2762 [OK] django Django is a free web application framework, … 656 [OK] pypy PyPy is a fast, compliant alternative implem… 134 [OK] kaggle/python Docker image for Python scripts run on Kaggle 91 [OK] centos/python-35-centos7 Platform for building and running Python 3.5… 20 amazon/aws-eb-python AWS Elastic Beanstalk Python Image 19 resin/raspberrypi3-python The Python buildpack image for Python apps f… 17 arm32v7/python Python is an interpreted, interactive, objec… 15 iron/python Tiny Python Microcontainer 8 centos/python-27-centos7 Platform for building and running Python 2.7… 8 joyzoursky/python-chromedriver Python with Chromedriver, for running automa… 8 [OK] resin/raspberrypi3-alpine-python The Python buildpack image for Python apps. … 6 circleci/python Python is an interpreted, interactive, objec… 5 centos/python-36-centos7 Platform for building and running Python 3.6… 4 resin/beaglebone-black-python The Python buildpack image for Python apps f… 3 centos/python-34-centos7 Platform for building and running Python 3.4… 2 komand/python-plugin Komand Python SDK 2 [OK] qbtrade/python python 3.5.0 with requirements 0 resin/qemux86-alpine-python The Python buildpack image for Python apps. … 0 resin/artik5-python The Python buildpack image for Python apps f… 0 resin/qemux86-64-python The Python buildpack image for Python apps f… 0 resin/artik10-python The Python buildpack image for Python apps f… 0 openshift/python-33-centos7 DEPRECATED: A Centos7 based Python v3.3 imag… 0 resin/qemux86-python The Python buildpack image for Python apps f… 0 publicisworldwide/python-conda Basic Python environments with Conda. 0 [OK]
結構たくさん出てきました。一番上のやつでいいかな・・・。 Descriptionがもう少しみたいので、ヘルプ見て、データを削らずにアウトプットするオプションを指定して確認しました。
$ docker search --no-trunc python NAME DESCRIPTION STARS OFFICIAL AUTOMATED python Python is an interpreted, interactive, object-oriented, open-source programming language. 2762 [OK] ...
あ、はい。という感じの説明です。
OFFICIAL OKと書いてるからなんとなくよさげな雰囲気を感じつつ、pythonというイメージを使うことにします。
Dockerイメージをダウンロード
Dockerイメージは、docker pull
でダウンロードすることができるようです。
$ docker pull python Using default tag: latest latest: Pulling from library/python f2b6b4884fc8: Pull complete 4fb899b4df21: Pull complete ...略 Status: Downloaded newer image for python:latest
ここでいう、python:latestってなんだろ?という疑問はありますが、まあとりあえず、スルーします。
docker images
で確認すると以下のようになってます。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE python latest 6bf7a4fa2d45 6 days ago 691MB
CREATEDが6 days agoなので、かなり新しそう。
Dockerイメージでコンテナ作成
次は、Dockerイメージを使ってコンテナを作ってみます。
docker run
に対話型のオプション -it
をつけて、Dockerイメージ python
を指定してを実行します。
$ docker run -it python Python 3.6.5 (default, Mar 31 2018, 01:15:58) [GCC 4.9.2] on linux Type "help", "copyright", "credits" or "license" for more information. >>>
すると新しいDockerイメージが起動して、Pythonのインタラクティブシェルが起動しました。
Dockerイメージがあることを確認します。 docker ps -a
を実行します。このコマンドで、起動中のコンテナの一覧が見れます。
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ca7d38f97899 python "python3" About a minute ago Up About a minute nervous_snyder
STATUSが Up About a minute
になっています。 はい。
最初のPythonインタラクティブで、 exit()
を実行します。
$ docker run -it python Python 3.6.5 (default, Mar 31 2018, 01:15:58) [GCC 4.9.2] on linux Type "help", "copyright", "credits" or "license" for more information. >>> exit()
するとSTATUSが変わります。
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ca7d38f97899 python "python3" 3 minutes ago Exited (0) 9 seconds ago nervous_snyder
まあ、ステータスコード0で終わったよ。という話。
この後、dockerコンテナは削除しましょう。消えます。
$ docker rm ca7d38f97899 ca7d38f97899 $ docker ps -al CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
要するに、Dockerというのは、簡単に使い捨ての実行環境を作る仕組みです。
Pythonのインタラクティブシェルだけだと面白くないし、何が嬉しいのかわからないです。
で、いろいろ調べてると、Dockerコンテナの中で、サーバーを起動するのが、よくあるパターンのようです。
というわけでやってみます。
DockerコンテナでWebアプリを起動する
Pythonで動くWebアプリを用意する
まずは、Python3.6で動くhttpserverを用意します。
$ echo Flask > requirements.txt $ cat requirements.txt Flask $ python3 -m venv venv --prompt flask $ . venv/bin/activate (flask) $ pip install -r requirements.txt (flask) $ vim app.py
app.py
from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "<h1>Hello Flask in Docker!</h1>" \ if __name__ == "__main__": app.run(host='0.0.0.0', port=8000)
(flask) $ python app.py * Serving Flask app "app" (lazy loading) * Environment: production WARNING: Do not use the development server in a production environment. Use a production WSGI server instead. * Debug mode: off * Running on http://0.0.0.0:8000/ (Press CTRL+C to quit)
$ curl http://localhost:8000/ <h1>Hello Flask in Docker!</h1>
はい。とりあえず、できました。
これを、Dockerコンテナの中で動かしていきます。
Dockerコンテナの中で、指定したコマンドを実行
Dockerコンテナの中で、指定したコマンドを実行するのは、以下ではダメです。
(flask) $ docker run python app.py docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec: \"app.py\": executable file not found in $PATH": unknown. ERRO[0000] error waiting for container: context canceled
まあ、当たり前なんですが。
で、それを実現するために出てくるのが、DockerFileです。 DockerFileにいろいろ書くと、実現できます。
というわけで、以下のDockerFileを用意します。
Dockerfile
FROM python # 作業ディレクトリを /myapp に設定 WORKDIR /myapp # 必要なファイルをコンテナ内の /myapp にコピー ADD requirements.txt /myapp ADD app.py /myapp # requirements.txt でインストール RUN pip install -r requirements.txt # 8000ポートを外に見せる EXPOSE 8000 CMD ["python", "app.py"]
そして、以下を実行すると hello_myapp
というDockerイメージが作成されます。
$docker build -t hello_myapp .
以下を実行して、きちんとできていることを確認します。
$ docker images | grep hello_myapp hello_myapp latest f87e05b52f04 About a minute ago 701MB
次は、dockerコンテナを作ってみます。-p
でホストOSの8010ポートをDocker上のコンテナの8000にポートフォワーディングしています。
$ docker run -p 8010:8000 hello_myapp * Serving Flask app "app" (lazy loading) * Environment: production WARNING: Do not use the development server in a production environment. Use a production WSGI server instead. * Debug mode: off * Running on http://0.0.0.0:8000/ (Press CTRL+C to quit)
httpでアクセスできます。
$ curl http://0.0.0.0:8010/ <h1>Hello Flask in Docker!</h1>
はい。ここまできたら、大体のことはできそうな予感がしてきました。 次は、docker-composeを触ってみたいですね。
皆様も、よいDockerライフを。