ラベル dockerfile の投稿を表示しています。 すべての投稿を表示
ラベル dockerfile の投稿を表示しています。 すべての投稿を表示

2020年9月23日水曜日

VSCode + Python + Flask + Docker で環境構築 #03. 運用環境を構築してみる

どうも、最近うちの娘(3歳)が「アレクサ、テレビ付けて」と
リモコンを使わなくなったことに一抹の不安を覚える
もりもりです。

今回はFlaskアプリやサービスを作って公開する場合の運用環境についてです。

#01. Flaskアプリをdocker上で動かしてみる
#02. vscodeのRemote Developmentでデバッグしてみる
今回はこちら → #03. 運用環境を構築してみる

まずは

第1回、第2回で作ったコンテナをそのままどこかのクラウドサービスへ
デプロイしたらダメなの?というところですが
公式ドキュメントでは以下のように書かれています。

When running publicly rather than in development,
you should not use the built-in development server (``flask run``).
The development server is provided by Werkzeug for convenience,
but is not designed to be particularly efficient, stable, or secure.

Instead, use a production WSGI server.

ということのようです。
flask runで実行した開発サーバーを本番環境で使用するべきではないと。
効率性、安定性、セキュリティを意識して設計してはいないよと。

代わりに本番環境ではWSGIサーバーを使ってねと。

てなわけで、WebサーバーとAppサーバーを用意し
WebサーバーとFlaskを繋ぐインターフェース
WSGI (Web Server Gateway Interface) を利用して
通信する環境をコンテナで作成していきます。

今回使用するWSGIサーバーはuWSGIです。
Flask + Docker + Nginx + uWSGI で環境を作っていきたいと思います。

ちなみにWSGIの読み方は「ウィズギー」だそうです。

ディレクトリ構成


flask-product
  ├── app
  │ ├── Dockerfile
  │ ├── requirements.txt
  │ ├── run.py
  │ └── uwsgi.ini
  ├── web
  │ ├── Dockerfile
  │ └── nginx.conf
  └── docker-compose.yml

ソースコードはGithubにあります。


app/Dockerfile


WORKDIRを変更し、CMDを追加します。

# base image
FROM python:3.8.5

ARG project_dir=/var/www/

# workdir にファイル等追加
COPY requirements.txt $project_dir

# workdir
WORKDIR $project_dir

# upgrade pip
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt

CMD ["uwsgi","--ini","/var/www/uwsgi.ini"]

追加したCMDですが、 docker-compose.ymlに下記を追加しても問題ないと思います。(また試しときます。)
command: uwsgi --ini /var/www/uwsgi.ini

app/equirements.txt & run.py


uwsgiをインストールするので追加します。
Flask
uwsgi

app/uwsgi.ini


uWSGIの設定ファイルです。
[uwsgi]
wsgi-file = run.py
callable = app
master = true
processes = 1
socket = :3031

web/Dockerfile


公式イメージをベースとします。
# base image
FROM nginx:latest

CMD ["nginx", "-g", "daemon off;", "-c", "/etc/nginx/nginx.conf"]

web/nginx.conf


Nginxの設定ファイルです。
user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    upstream uwsgi {
        server app-server:3031;
    }

    server {
        listen 80;
        charset utf-8;

        location / {
            include uwsgi_params;
            uwsgi_pass uwsgi;
        }

    }
}

31行目のホスト名にはdocker-compose.ymlで指定したapp側のホスト名を指定します。

docker-compose.yml


コンテナをapp-serverとweb-serverの2つに分けます。
ホスト名も忘れずに設定しておきます。
version: "3"

services:
    app:
        container_name: app-server
        hostname: app-server
        build: ./app
        volumes:
            - "./app:/var/www/"
        ports:
            - "3031:3031"
        environment:
            TZ: Asia/Tokyo
  
    web:
        container_name: web-server
        hostname: web-server
        build: ./web
        volumes:
            - "./web/nginx.conf:/etc/nginx/nginx.conf"
            # nginxのログをホストOS側に出力
            - "/tmp/nginx_log:/var/log/nginx"
        links:
            - app
        ports:
            - "4231:80"
        environment:
            TZ: Asia/Tokyo

コンテナを起動して動作確認


$ docker-compose up -d

コンテナが起動すればブラウザから下記にアクセスするだけです。

http://localhost:4231


はい、運用環境用のコンテナができました。
あとはNginxやuWSGIの設定を本番用にちゃんと設定してから
どこかのクラウドサービスへデプロイしてあげればよさそうですね。



以上、もりもりでした。

2020年9月13日日曜日

VSCode + Python + Flask + Docker で環境構築 #02. vscodeのRemote Developmentでデバッグしてみる

どうも、もりもりです。

今回はPython + Flaskの開発環境をDocker上に持っていき
コンテナ上にあるソースをvscodeでデバッグしてみます。

#01. Flaskアプリをdocker上で動かしてみる
今回はこちら → #02. vscodeのRemote Developmentでデバッグしてみる
#03. 運用環境を構築してみる

拡張機能「Remote Development」をインストール


まずは拡張機能をインストールします。


Extension Packとなっており、インストールすると下記の3つがインストールされます。

・Remote - WSL
・Remote - Containers
・Remote - SSH

今回はコンテナ上のソースをデバッグするので「Remote - Containers」を使用。

ディレクトリ構成


flask-dev
  ├── .devcontainer
  │ └── devcontainer.json
  ├── .vscode
  │ └── launch.json
  ├── docker-compose.yml
  ├── Dockerfile
  ├── requirements.txt
  └── run.py

ソースコードはGithubにあります。


Dockerfile


前回と違い、今回はproject_dirは宣言するだけで、値を指定しません。

# base image
FROM python:3.8.5

ARG project_dir

# workdir にファイル等追加
ADD requirements.txt $project_dir

# workdir
# なければ新規作成
WORKDIR $project_dir

# upgrade pip
RUN pip install --upgrade pip
RUN pip install -r requirements.txt

docker-compose.yml


project_dirをここで設定します。
volumesで作業場にマウントします。

version: '3'

services:
    web:
        container_name: dev_flask
        build:
            context: .
            args:
                project_dir: "/work/"
        ports:
            - "5000:5000"
        volumes:
            - ".:/work"
        environment:
            TZ: Asia/Tokyo
            FLASK_ENV: "development"
        command: "sleep infinity"

requirements.txt & run.py


前回のファイルそのままです。

devcontainer.json を追加


ウィンドウ左下の赤枠をクリックし、
「Remote-container: Add Development Container Configuration Files...」を選択
docker-compose.ymlから設定ファイルを作成するため
「From 'docker-compose.yml'」を選択
これでdevcontainer.jsonが作成されるので編集します。
dockerComposeFileにyamlファイルが2つ指定されていますが、
一つ上の階層にあるファイルのみ使用するため、
設定ファイルと同階層にあるdocker-compose.ymlは削除します。

{
    "name": "RemoteDevFlask",
    "dockerComposeFile": [
        "../docker-compose.yml",
        // "docker-compose.yml"
    ],
    "service": "web",
    "workspaceFolder": "/work",
    "settings": {
        "terminal.integrated.shell.linux": "/bin/bash"
    },
    "extensions": [
        "ms-python.python",
        "ms-python.vscode-pylance"
    ]
}

また、vscodeでPythonの開発するために必要な拡張機能を
コンテナにインストールするため、extensionsにPython関連の拡張機能を指定します。
指定する値は下記の赤枠のように、拡張機能名の右に表示されているIDです。

コンテナを開く


再度ウィンドウ左下にある赤枠部分をクリックし、
「Remote-Containers: Reopen in Container」を選択します。
無事にコンテナ上のProjectDir「work」を開くことができました。
vscodeの拡張機能を確認すると、コンテナ上には下記二つがインストールされていることがわかります。
(アイコン右下にリモートだと認識できるマークが付いている)
インストールされていないようであれば、通常と同様にコンテナに対して
画面から拡張機能をインストールすることが可能です。

デバッグ用設定ファイルを作成


vscodeのデバッグメニューを選択すると、まだデバッグするための設定ファイルがないため
下記のような表示になっています。
※ run.pyを開いた状態でデバッグメニューを選択する必要あり。

まずはlaunch.jsonを作成します。
今回はFlaskアプリのため「Flask」を選択
「run.py」を入力


ソースコードの任意の場所にブレークポイントをはり
いざデバッグ実行。
無事にデバッグできるようになりました。

開発環境をDocker化してしまえば、以下のようなメリットがありますね。
・自分のPCに無駄なものをインストールする必要がない
・メンバー全員が同じ環境で開発できる
・環境構築の手間が省ける
・運用環境と同じ環境でデバッグができる

ただイイことばかりではなく、WindowsPCだとDocker環境の構築が少しややこしそう?
Windows10のバージョン2004からはWSL2(Windows subsystem for linux 2)のおかげで
Hyper-VなしでもLinuxコンテナを動かせるようになったとか?
まだ2004にアップデートしてないのでアップデートしたら試してみようと思います。


以上、もりもりでした。

2020年9月8日火曜日

VSCode + Python + Flask + Docker で環境構築 #01 : Flaskアプリをdocker上で動かしてみる

どうも、もりもりです。

最近Dockerとか触ってみてるので開発環境作ったり運用環境を作ったりといったところで
連載したいと思います。

こんな感じで。

今回はこちら → #01. Flaskアプリをdocker上で動かしてみる
#02. vscodeのRemote Developmentでデバッグしてみる
#03. 運用環境を構築してみる

まずはDocker上にPythonやらFlaskやらをインストールし、
ソースを置いて実行してホストPCからアクセスしてみる。

環境


・ macOS Catalina 10.15.6
・ VSCode 1.48
・ Docker 19.03.12
・ Docker Compose 1.26.2

ディレクトリ構成


flask_hello_world
  ├── docker-compose.yml
  ├── Dockerfile
  ├── requirements.txt
  └── run.py

ソースコードはGithubにあげてます。



Dockerfile


Python公式のイメージからDockerイメージを作成します。
# base image
FROM python:3.8.5

ARG project_dir=/work/

# workdir にファイル等追加
ADD run.py $project_dir
ADD requirements.txt $project_dir

# workdir
# なければ新規作成
WORKDIR $project_dir

# upgrade pip
RUN pip install --upgrade pip
RUN pip install -r requirements.txt

# port
EXPOSE 5000

ENV PYTHONPATH "${PYTHONPATH}:/code/"
ENV FLASK_APP "/run.py"

docker-compose.yml


こちらはDockerイメージのビルド情報やコンテナ起動時の情報などを
定義するファイルです。

version: '3'

services:
    web:
        container_name: hello_flask
        build: .
        ports:
            - "5000:5000"
        tty: true
        environment:
            TZ: Asia/Tokyo
        command: flask run --host 0.0.0.0 --port 5000

requirements.txt


インストールしたいパッケージやバージョンを指定します。
flask

# バージョンまで指定する場合
# flask == 1.1.2

pip freeze で現在の環境にインストールされたパッケージと
バージョンを確認することができます。
よって下記を実行してそのままファイルへ書き出し。

$ pip freeze > requirements.txt

run.py


from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "Hello Flask!"

@app.route("/hello/<name>")
def hello_someone(name):
    return "Hello " + name + " !"

コンテナを起動

下記コマンドでコンテナを起動します。
$ docker-compose up -d

動作確認


コンテナが起動すればブラウザから下記にアクセスするだけです。

http://localhost:5000

http://localhost:5000/hello/{name}
※ {name} の部分はご自由に置き換えてください。

コンテナを停止

コンテナを停止する際は下記コマンドを実行してください。
コンテナの起動や停止はDocker Desktopから行ってもOKです。
$ docker-compose stop


うん、とりあえず動きましたね。

次回は開発環境としてソースなどをコンテナにのせて
デバッグ実行できるようにしたいと思います。


以上、もりもりでした。