はじめに
ハッカソンでフロントエンドにVue.js、バックエンドにFlaskを採用してSPA開発する機会があったが、その両者をDockerで連携する記事が少なかったため、ここにまとめることにする。
なお、今回はフロントエンドとバックエンドを1つのリポジトリで実装する。
前提知識:Docker/Docker-composeの概念をある程度理解している
実行環境:Windows10, DockerHub
到達レベル:Dockerでフロントエンドとバックエンドを連携したSPA開発を理解できる
Dockerfile
まず、フロントエンドのVue.jsとバックエンドのFlaskのDockerコンテナを立ち上げるために、それぞれのDockerfileを定義する。
FROM python:3.9
WORKDIR /usr/src/app
COPY ./ /usr/src/app
RUN pip install --upgrade pip && \
pip install flask && \
pip install flask-cors
ここでは、バックエンドのDockerfile名はDocker_pythonにしているが、任意のファイル名でも問題ない。
また、今回はPython3.9のDockerイメージを基に作成し、後の開発のためflask-cors
をインストールしている。
同様にフロントエンドのDockerfileも定義する。
FROM node:16.13.0
WORKDIR /usr/src/app
COPY ./ /usr/src/app
RUN npm install && \
npm install -g @vue/cli && \
npm install axios
node16.13.0のDockerイメージを基に作成した。
後の開発のためにaxios
をインストールしている。
docker-compose.yml
今回は2つのDockerコンテナを立ち上げるため、docker-compose.ymlファイルを記述し、複数個のコンテナを起動するように設定する。
version: '3'
services:
flask:
build:
context: .
dockerfile: Dockerfile_python
container_name: flask_container
tty: true
volumes:
- ./:/usr/src/app
ports:
- "5000:5000"
vue:
build:
context: .
dockerfile: Dockerfile_node
container_name: vue_container
tty: true
volumes:
- ./:/usr/src/app
ports:
- "8080:8080"
service
は起動するコンテナを記述する。(今回はflaskとvue)
この後にローカルサーバをフロントエンドとバックエンドから起動するが、両者のポート番号が重複しないように予め指定しておく。
flaskとvueのデフォルトポート番号は決まっているため、今回は必要ないが明確にするためにも...
コンテナ起動
Dockerfileとdocker-compose.ymlを定義したのでさっそくコンテナを起動してみる。
docker-compose up -d
※ -dは--detachの略記
-d
オプションをつけることでバックグラウンドでコンテナを起動できる。(デタッチモード)
docker-compose ps
でコンテナの起動状態を確認することができる。
ディレクトリ構造
今の状態のディレクトリ構造は以下のようになる。
.
├── Dockerfile_node
├── Dockerfile_python
├── README.md
├── docker-compose.yml
今回はフロントエンド側とバックエンド側を1つのリポジトリで管理するため、それぞれのフォルダを作成する必要がある。
最終的に以下のディレクトリ構造になる。
.
├── Dockerfile_node
├── Dockerfile_python
├── README.md
├── backend
├── docker-compose.yml
├── frontend
├── node_modules
├── package-lock.json
└── package.json
frontendディレクトリ
まずは、フロントエンド側から実装する。
vue create frontend
上記のコマンドでVueのプロジェクトを作成する。
対話形式で必要なモジュールなどを聞かれるが基本Yesで問題ない。
今回はSPA開発なのでVuexやRouterなどを追加した。
完了すると以下のようなディレクトリ構造になる。
.
├── Dockerfile_node
├── Dockerfile_python
├── README.md
├── docker-compose.yml
├── frontend
├── node_modules
├── package-lock.json
└── package.json
それではフロントエンド側のローカルサーバを起動してみよう。
cd frontend
frontendディレクトリに移動し、
npm run build
でサーバに反映するためにビルドする。
すると、dist
ディレクトリが作成される。
それではローカルサーバを起動してみよう。
PS C:\Users\〇〇〇\〇〇〇〇\frontend> npm run serve
> frontend@0.1.0 serve
> vue-cli-service serve
INFO Starting development server...
DONE Compiled successfully in 4126ms 19:17:14
App running at:
- Local: http://localhost:8081/
- Network: http://192.168.10.162:8081/
Note that the development build is not optimized.
To create a production build, run npm run build.
backendディレクトリ
バックエンド側も実装する。
mkdir backend
でbackendディレクトリを作成し、その中にapp.py
ファイルを作成する。
# render_template:参照するテンプレートを指定
# jsonify:json出力
from flask import Flask, render_template, jsonify
# CORS:Ajax通信するためのライブラリ
from flask_cors import CORS
from random import *
# static_folder:vueでビルドした静的ファイルのパスを指定
# template_folder:vueでビルドしたindex.htmlのパスを指定
app = Flask(__name__, static_folder="../frontend/dist/static", template_folder="../frontend/dist")
app.config.from_object(__name__)
CORS(app)
# 任意のリクエストを受け取った時、index.htmlを参照
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def index(path):
return render_template("index.html")
# app.run(host, port):hostとportを指定してflaskサーバを起動
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
Flaskでは、render_template
でレンダリングするファイルを指定するが、今回はbackendディレクトリではなく、frontendディレクトリの内容をレンダリングする必要がある。
そのため、static_folder="../frontend/dist/static", template_folder="../frontend/dist"
の記述を加えることで、デフォルトのレンダリングするディレクトリを変更する。
また、今回はSPA開発なので
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def index(path):
return render_template("index.html")
とする。
詳細は以下の公式ドキュメントを参照されたい。
static系のファイルをstatic
フォルダに参照するように変更しているが、
デフォルトではstatic
フォルダは生成されないので、自分で作成して、その配下にstatic系のファイルを生成するように設定する必要がある。
そのため、frontend
フォルダ直下にvue.config.js
を作成する。
module.exports = {
assetsDir: "static",
};
ディレクトリを構造を変更したので、
npm run build
を実行してサーバに反映させるのを忘れずに!
それでは、バックエンド側でサーバを起動してみよう。
PS C:\Users\〇〇〇\〇〇〇〇\backend> flask run
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000
Press CTRL+C to quit
上記のようにVueが表示されれば連携完了である。
参考記事
まとめ
今回はVue.jsとFlaskを1つのリポジトリで連携させた。
以降の開発では、cors
やaxios
を使用して、Ajax通信でフロントエンドとバックエンドを連携させ、SPA開発をする。