LoginSignup
7
9

More than 3 years have passed since last update.

【Docker】チュートリアル(Python+php)

Last updated at Posted at 2020-02-25

はじめに

Dockerを勉強するにあたり、素晴らしいチュートリアル動画があったのでそれを元に自分で手を動かして見ました。リンク先の動画は英語ですので、日本語で少し補足をしながら進めていきます。初心者のため認識の誤りがあるかもしれませんので、その際はコメント頂けると幸いです。

事前にdocker、docker-composeのインストールが必要です。

元動画

Docker Compose in 12 Minutes

最終的なフォルダ構成は以下のようになります。
スクリーンショット 2020-02-25 21.50.11.png

productディレクトリにはjsonを返すAPIをpythonで用意します。
websiteディレクトリには画面を描画するphpを用意します。

product

まずはdocker_tutorial配下にproductディレクトリを作成します。

$ mkdir product

そしてシンプルなPythonコードを作成します。flaskとflask_restfulというライブラリを使用します。

api.py

from flask import Flask
from flask_restful import Resource, Api

app = Flask(__name__)
api = Api(app)

class Product(Resource):
    def get(self):
        return{
            'products': [
                'Ice cream',
                'Chocolate',
                'Fruit'
            ]
        }

api.add_resource(Product, '/')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80, debug=True)

ローカル環境にpythonをインストールしている場合は、pip installなどでライブラリをインストールしますが、Dockerを使用した場合は個別にインストールする必要はありません。その代わりにコンテナ起動時に必要となるライブラリなどを以下のテキストファイルに記載するか、後述のDockerfile内にpip installのコマンドを記載します。バージョンはライブラリの公式サイトなどを参照して使用したいバージョンを記載します。

requirements.txt
Flask==0.12
flask-restful==0.3.5

次にDockerfileを作成します。
DockerfileはDocker上で動作させるコンテナの構成情報を記述するためのファイルです。

FROM python:3-onbuild
COPY . /usr/src/app
CMD ["python", "api.py"]

FROM
FROMにはベースとするDockerイメージを指定します。また「onbuild」を記載することで、Dockerfile を使って docker build をするとき、Dockerfile 内で pip install を書かなくても Dockerfile と同じディレクトリに requirements.txt があると自動的にインストールをするようになっています。

COPY
COPYにはローカルファイルをDockerイメージのどこにコピーするかを記載します。今回の場合はproductディレクトリをDocker上の/usr/src/app内にコピーします。

CMD
CMDにはコンテナ起動時に実行するコマンドを記載します。

次にdocker-compose.ymlを作成します。docker-composeには

  • Dockerイメージをビルドするための情報(使用するDockerfile、イメージ名など)
  • コンテナ起動するための情報(ホストとの共有ディレクトリ設定やポートフォワードなどの起動オプションなど)
  • 使用するDockerネットワーク

などを記載します。

docker-compose.yml
version: '3'
services:
    product-service:
        build: ./product
        volumes: 
            - ./product:/usr/src/app
        ports: 
            - 5001:80

version
docker-composeで使用するバージョンを記載します。現在はバージョン3が最新ですので、3を指定します。

services
アプリケーションを動かすための各要素をServiceと読んでいます。各サービスをネストしてこちらに記載します。今回の場合は「product-service」というサービスを起動します。

build
指定したディレクトリにあるDockerfileでコンテナを起動します。今回の場合はproductディレクトリのDockerfileでコンテナを起動します。

volumes
ローカリのディレクトをコンテナのディレクトにマウントします。今回の場合はproductディレクトリをコンテナ上の/usr/src/appディレクトリにマウントします。

ports
Dockerを立ち上げるポート番号を記載します。今回は5001番ポートで立ち上げます。

それではDockerを起動

$ docker-compose up

起動が完了したら、localhost:5001にアクセスします。
以下のような画面が表示されたら問題なく起動しています。
ここまでで、簡単にPython、Flaskの環境ができることが分かります。

スクリーンショット 2020-02-25 21.18.20.png

この状態でapi.pyを以下のように変更し、保存します。

api.py
class Product(Resource):
    def get(self):
        return{
            'products': [
                'Ice cream',
                'Chocolate',
                'Fruit',
                'Eggs'
            ]
        }

再読み込みを行うと、表示内容も更新されます。コンテナを再起動しなくてもマウントしてくれます。

スクリーンショット 2020-02-25 21.21.04.png

ここまできたらコンソール上で「control+C」を押して、dockerを一旦停止します。

website

次はdocker_tutorial配下にwebsiteというディレクトリを作成します。こちらにはphpのファイルを作成します。

http://product-serviceの結果をループして表示する処理です。
ここでいうproduct-serviceはdocker-composeに記載したサービス名が該当します。

index.php
<html>
    <head>
        <title>My Shop</title>
    </head>

    <body>
        <h1>Welcome to my shop</h1>
        <ul>
            <?php
                $json = file_get_contents('http://product-service');
                $obj = json_decode($json);

                $products = $obj->products;
                foreach($products as $product) {
                    echo "<li>$product</li>";
                }
            ?>
        </ul>
    </body>

次にdocker-compose.ymlを以下のように変更します。

docker-compose.yml
version: '3'

services:
    product-service:
        build: ./product
        volumes: 
            - ./product:/usr/src/app
        ports: 
            - 5001:80

    website:
        image: php:apache
        volumes: 
            - ./website:/var/www/html
        ports: 
            - 5000:80
        depends_on: 
            - product-service

website
servicesにwebsiteというサービスを追加します。

image
imageを記載することで、Docker Hub上に用意されている既存のイメージを使用することができます。buildとimageは同時に指定することはできません。

depends_on
サービス同士の依存関係を記載します。今回の場合、websiteが実行されるより前にproduct-serviceが実行されるようになります。docker-compose.ymlにproduct-serviceがない場合はエラーになります。

再度Dockerを起動します。

$ docker-compose up

起動が完了したらlocalhost:5000にアクセスします。
以下のような画面が表示されていれば成功です。

スクリーンショット 2020-02-25 21.38.12.png

さいごに

Dockerを使用することで、簡単にPython+phpの環境を作ることができました。私もDocker初心者のためこれからも引き続き学習していきたいと思います。

おまけ

-dをつけることでバックグラウンドでコンテナを立ち上げることができます。

$ docker-compose up -d

Starting docker_tutorial_product-service_1 ... done
Starting docker_tutorial_website_1         ... done

psコマンドで起動中のコンテナの一覧が確認できます。

$ docker ps

CONTAINER ID        IMAGE                             COMMAND                  CREATED             STATUS              PORTS                  NAMES
24de043f94d9        php:apache                        "docker-php-entrypoi…"   10 minutes ago      Up About a minute   0.0.0.0:5000->80/tcp   docker_tutorial_website_1
da62924c1154        docker_tutorial_product-service   "python api.py"          32 minutes ago      Up About a minute   0.0.0.0:5001->80/tcp   docker_tutorial_product-service_1

stopでコンテナを停止することができます。

$ docker-compose stop
Stopping docker_tutorial_website_1         ... done
Stopping docker_tutorial_product-service_1 ... done

$ docker ps
ONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

参考

7
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
9