2
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

1歩ずつカスタマイズしながら作るDocker + Nginx + Flask リモートデバッグ環境(後半)

Last updated at Posted at 2019-09-29

目標

  • 簡単なウェブサービスの構成を仮想環境で作成する
  • ウェブサービスの構成は
    • フロント: nginx
    • バックエンド: WSGI(mod_wsgi) + Flask
  • 仮想環境はDockerを利用してgitを通じて他の開発者と共有できるようにする
  • ホストPCのOSに依存しないPythonのデバッグ環境を実現する
    • デバッグにはVSCodeのリモートデバッグを利用

このドキュメントを読んで出来る事

目標を前半と後半にわけます。このページでは後半部分を書いています。

  • 前半: 投稿済
    • 仮想環境のセットアップ(Hyper-V, Docker)
    • nginxコンテナ作成
    • apacheコンテナ作成
    • ウェブサービスの骨組みを作成
  • 後半: ← ここ
    • ウェブアプリ作成(Flask)
    • リモートデバッグの設定

必要な環境

  • Windows10 Pro
  • Hyper-V
  • Docker for Windows

新規にインストールするパッケージ

  • VSCode拡張機能
    • Python
    • Japanese Language Pack for VS Code(任意)

ウェブアプリ作成(Flask)

ウェブアプリを作成していきます。全体の流れは以下の通りです。まずコンテナ内で必要なファイルを作成・修正して動作確認後、Dockerfile等に内容を反映します。

全体の流れ

  1. コンテナ内でセットアップ
  2. ブラウザで動作確認
  3. Dockerfile にセットアップ内容を記述

コンテナ内でセットアップ

別ターミナルで実行
PS> docker container exec -it wbb3 bash
必要なパッケージをインストール
root# apt update
root# apt install -y libapache2-mod-wsgi-py3 python3.6 python3.6-dev python3-pip
Pythonモジュールのインストール
root# mkdir /var/www/flask
root# cd /var/www/flask
root# pip3 install pipenv
root# pipenv install flask
...
This system supports the C.UTF-8 locale which is recommended.
You might be able to resolve your issue by exporting the
following environment variables:

    export LC_ALL=C.UTF-8
    export LANG=C.UTF-8

インストール中にエラーが出たので対応してインストールを続ける :point_down:

エラー対応とPythonモジュールのインストール(続き)
root# export LC_ALL=C.UTF-8
root# export LANG=C.UTF-8
root# pipenv install flask
root# pipenv install --system --dev
WSGIアプリ作成
root# mkdir /var/www/flask/wsgi
root# vi /var/www/flask/wsgi/app.py

ファイルの中身は :point_down:

/var/www/flask/wsgi/app.py
from datetime import datetime
from flask import Flask

app = Flask(__name__)

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

@app.before_first_request
def before_first_request():
    print('### Restarted, first request @ {} ###'.format(datetime.utcnow()))

application = app
Apacheの設定変更(WSGI対応)
root# vi /etc/apache2/mods-available/wsgi.conf

ファイルの中身は :point_down:

/etc/apache2/mods-available/wsgi.conf
<IfModule mod_wsgi.c>
    WSGIScriptAlias /wsgi /var/www/flask/wsgi/app.py
</IfModule>

動作確認

WSGIの動作確認
root# apachectl graceful

以下のURLにアクセス → :ok_hand: :ok:
http://localhost/app/wsgi/

Dockerfile に変更内容を反映

flask/Dockerfile
FROM ubuntu

# Avoid warnings by switching to noninteractive
ENV DEBIAN_FRONTEND=noninteractive

# Apache
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_PID_FILE /var/run/apache2.pid
ENV APACHE_RUN_DIR /var/run/apache2
ENV APACHE_LOG_DIR /var/log/apache2
ENV APACHE_LOCK_DIR /var/lock/apache2

# Python pipenv
ENV LC_ALL C.UTF-8
ENV LANG C.UTF-8

# Install packages
RUN apt-get update \
    && apt-get install -y --no-install-recommends apt-utils dialog 2>&1 \
    && apt-get install -y git iproute2 procps lsb-release \
    && apt-get install -y apache2 libapache2-mod-wsgi-py3 \
    && apt-get install -y python3.6 \
    && apt-get install -y python3.6-dev \
    && apt-get install -y python3-pip \
    && pip3 install pipenv

# Apache
RUN  echo ServerName $HOSTNAME > /etc/apache2/conf-available/fqdn.conf \
    && a2enconf fqdn
COPY ./etc/apache2 /etc/apache2

# Install other packages
RUN apt-get install -y vim curl

# Install Python modules
WORKDIR /var/www/flask
COPY ./Pipfile Pipfile
COPY ./Pipfile.lock Pipfile.lock
RUN set -ex && pipenv install --system --dev

# Clean up
RUN apt-get autoremove -y \
    && apt-get clean -y \
    && rm -rf /var/lib/apt/lists/*

EXPOSE 80
CMD ["apachectl", "-D", "FOREGROUND"]
WSGI関連ファイルのコピー
PS> docker container cp wbb3:/var/www/flask/Pipfile flask
PS> docker container cp wbb3:/var/www/flask/Pipfile.lock flask
PS> docker container cp wbb3:/var/www/flask/wsgi flask
PS> mkdir flask\etc\apache2\mods-available
PS> docker container cp wbb3:/etc/apache2/mods-available/wsgi.conf flask\etc\apache2\mods-available
docker-compose.yml
# 略
    ports:
      - 5000:80
# --- 追加 ---
    volumes:
      - ./flask/wsgi:/var/www/flask/wsgi
# --- ここまで ---

動作確認

再ビルドとコンテナの起動
PS> docker-compose down
PS> docker-compose up --build

:bangbang: 多くのパッケージをインストールするので初回はコンテナの起動まで時間がかかります。

リモートデバッグの設定

VSCode からデバッグ出来るようにセットアップします。全体の流れは今までとほぼ同じですが、リモートデバッグ用のポート設定だけ先にします。

全体の流れ

  1. ポート設定(リモートデバッグ用)
  2. 再ビルドとコンテナの起動
  3. セットアップ(コンテナ内)
    1. Pythonモジュールのインストール
    2. VSCodeのセットアップ
    3. デバッグの動作確認
  4. Dockerfile にセットアップ内容を記述
  5. 動作確認

ポート設定(リモートデバッグ用)

変更前flask/Dockerfile
EXPOSE 80
変更後flask/Dockerfile
EXPOSE 80 5678
変更前docker-compose.yml
ports:
  - 5000:80
変更後docker-compose.yml
ports:
   - 5000:80
   - 5678:5678

再ビルドとコンテナの起動

再ビルドとコンテナの起動
PS> docker-compose down
PS> docker-compose up --build

セットアップ(コンテナ内)

起動中のコンテナのシェルに接続してリモートデバッグ用のセットアップをします。

別ターミナル
PS> docker container exec -it wbb3 bash

Pythonモジュールのインストール

開発用モジュールなので--dev オプションをつける。
:bangbang: ptvsdの最新バージョン(4.3.2)で、Flask + mod_wsgi環境下のリモートデバッグが正常に開始できなかったので、ネットで動作報告があった4.1.4にバージョンを固定しています。リモートデバッグはVSCodeとptvsdのバージョンにセンシティブかも :frowning2:

リモートデバッグのセットアップ
root# pipenv install --dev ptvsd==4.1.4
root# pipenv install --system --dev
root# vi wsgi/app.py

ファイルの中身は :point_down:

flask/wsgi/app.py
from datetime import datetime
from flask import Flask
import ptvsd

app = Flask(__name__)

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

@app.before_first_request
def before_first_request():
    print('### Restarted, first request @ {} ###'.format(datetime.utcnow()))

application = app

try:
    ptvsd.enable_attach()
except OSError as e:
    print(e)

ブレークポイントが正常に動作するように、アタッチ先を単一プロセス/スレッドにする。

root# vi /etc/apache2/mods-available/mpm_event.conf

ファイルの中身は :point_down:

/etc/apache2/mods-available/mpm_event.conf
<IfModule mpm_event_module>
        StartServers             1
        MinSpareThreads          1
        MaxSpareThreads          1
        ThreadLimit              1
        ThreadsPerChild          1
        MaxRequestWorkers        1
        MaxConnectionsPerChild   0
</IfModule>

動作確認

デバッグ用コード以外は正常に動作している事を確認する。

Apacheの再起動
root# apachectl graceful

ブラウザで確認。http://localhost/app/wsgi/:ok:

VSCodeのセットアップ

下記コマンドを実行しVSCodeの拡張機能をインストール。(すでにインストールしている場合は不要)

  • Pythonモジュール
  • Japanese Language Pack for VS Code(※任意)
VSCode拡張機能のインストール
PS> code --install-extension ms-python.python
PS> code --install-extension ms-ceintl.vscode-language-pack-ja

リモートデバッグの設定

下記コマンドを実行して、webapp-docker フォルダをVSCodeで開く。(GUIからwebapp-dockerフォルダを右クリック→Open with CodeでもOK)

PS> code .

VSCode内でサイドバーに表示されているapp.pyを開く
vscode-remote-debug-oepn-app-screenshot.jpg
アクティビティバーのデバッグアイコンを選択
vscode-remote-debug-screenshot.jpg

歯車アイコンをクリック
vscode-remote-debug-add-setting.jpg

メニューのRemote Attachを選択
vscode-remote-debug-add-attach.jpg

Enterキーを入力。(デフォルト値を使用)
vscode-remote-debug-attach-step1.jpg

Enterキーを入力。(デフォルト値を使用)
vscode-remote-debug-attach-step2.jpg

設定ファイルが開くのでをファイルの内容を修正し保存。ファイルの中身は :point_down:

.vscode/launch.json
{
    // IntelliSense を使用して利用可能な属性を学べます。
    // 既存の属性の説明をホバーして表示します。
    // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: アタッチ",
            "type": "python",
            "request": "attach",
            "port": 5678,
            "host": "localhost",
            "pathMappings": [
                {
                    "localRoot": "${workspaceFolder}",
                    "remoteRoot": "/var/www"
                }
            ]
        }
    ]
}

デバッグの動作確認

ブレークポイントを設定後、リモートのデバッグサーバーにアタッチ。
:bangbang:アタッチ出来ない時はブラウザをリロード後に再挑戦

vscode-remote-debug-add-breakpoint.png

ブラウザでアクセスして、ブレークポイントで停止する事を確認する。
http://localhost/app/wsgi/

vscode-remote-debug-break.png

Dockerfile に変更内容を反映

WSGI関連ファイルのコピー
PS> docker container cp wbb3:/var/www/flask/Pipfile flask
PS> docker container cp wbb3:/var/www/flask/Pipfile.lock flask
PS> docker container cp wbb3:/var/www/flask/wsgi flask
PS> docker container cp wbb3:/etc/apache2/mods-available/mpm_event.conf 
 flask\etc\apache2\mods-available

動作確認

再ビルドとコンテナの起動
PS> docker-compose down
PS> docker-compose up --build

下記URLにブラウザでアクセス。
http://localhost/
http://localhost/app/wsgi/

VSCodeからリモートデバッグを実行して動作確認する。
http://localhost/app/wsgi/

まとめ

最終的なフォルダ構成は以下になります。

フォルダ構成
PS> tree /F
C:.
  docker-compose.yml

├─.vscode
      launch.json

├─flask
    Dockerfile
    Pipfile
    Pipfile.lock
  
  ├─etc
    └─apache2
        └─mods-available
                mpm_event.conf
                wsgi.conf
  
  └─wsgi
          app.py

└─nginx
      Dockerfile
    
    └─etc
        └─nginx
            └─conf.d
                    default.conf

作成した内容はBitbucketにアップしています。
リポジトリ
https://bitbucket.org/glarpycat/docker-remote-debugging-with-vscode/src/master/

2
6
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
2
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?