はじめに
最近アサインされた案件で、FrontをReact(Vite)、BackendをPython(Flask)というものがありました。
FrontとBackendを別々のメンバーが開発を行うため、結合して動作確認するためのDocker環境を作成しましたが、思わぬところではまったため備忘録として残しておきたいと思います。
まずはそれぞれのプログラム作成
Flask
事前にpythonのインストールは済んでいるものとします。
Flaskと最低限のライブラリをインストールします。
PS C:\sample\backend> pip install flask
PS C:\sample\backend> pip install -U flask-cors
app.pyを作成し以下を記載します。
※語るまでもないコードのため、ソースコードの中身の解説は割愛します。
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
@app.route('/')
def hello_world():
return 'Hello, World!!'
if __name__ == "__main__":
app.run(debug=True)
app.pyを実行します。
PS C:\sample\backend> python app.py
* Serving Flask app 'app'
* Debug mode: on
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
* Restarting with stat
* Debugger is active!
* Debugger PIN: 613-932-713
コンソールに出力される通りにhttp://127.0.0.1:5000/ をブラウザで表示すると以下の画面が表示されます。
Flask側は一旦ここまでとします。
React
事前に Node.jsとnpmのインストールは済んでいるものとします。
まずは任意のフォルダ(ここではC:\sample)でプロジェクトを作成します。
PS C:\sample> npm create vite@latest
Need to install the following packages:
create-vite@5.4.0
Ok to proceed? (y) y
√ Project name: ... frontend
√ Select a framework: » React
√ Select a variant: » JavaScript
続いて関連ライブラリのインストールです。
PS C:\sample\frontend> npm install
実行すると初期画面を表示できます。
PS C:\sample\frontend> npm run dev
> frontend@0.0.0 dev
> vite
VITE v5.3.5 ready in 489 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h + enter to show help
コンソールに出力される通りにhttp://localhost:5173/ をブラウザで表示すると以下の画面が表示されます。
Flaskと通信をするためにライブラリを追加します。
PS C:\sample\frontend> npm install axios
added 9 packages, and audited 283 packages in 2s
103 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
続いてApp.jsxを修正します。
※語るまでもないコードのため、ソースコードの中身の解説は割愛します。
import React, { useState } from "react";
import axios from 'axios';
function App() {
const [data, setData] = useState(null);
const fetchData = async () => {
const result = await axios.get('http://localhost:5000/');
setData(result.data);
};
return (
<div className="App">
<h1>React Sample</h1>
<button onClick={fetchData}>Push</button>
<p>{data}</p>
</div>
);
}
export default App;
これを画面で表示すると以下の通りとなります。
「Push」ボタンを押すと通信Flaskに通信し、Flask側のレスポンス文字が表示されます。
これで、ReactとFlaskをローカル環境で連携させることができました。
Dockerで連携させるために
事前に Dockerのインストールは済んでいるものとします。
それぞれでDocker起動用のファイルを作成します。
Flask
以下の3ファイルを作成します。
- requirements.txt
Flask==3.0.2
Flask-Cors==4.0.0
- Dockerfile
FROM python:3.8-slim-buster
WORKDIR /app
ADD . /app
RUN pip install --no-cache-dir -r requirements.txt
EXPOSE 5000
CMD python app.py
- docker-compose.yml
version: '3.8'
services:
flask:
build: .
container_name: flask-app
command: flask run --host=0.0.0.0
volumes:
- .:/app
ports:
- "5000:5000"
続いてDocker Compose を利用してコンテナを起動します。
PS C:\sample\backend> docker-compose up
time="2024-08-04T17:04:11+09:00" level=warning msg="C:\\sample\\backend\\docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion"
[+] Running 2/2
✔ Network backend_default Created 0.1s
✔ Container flask-app Created 0.1s
Attaching to flask-app
flask-app | * Debug mode: off
flask-app | WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
flask-app | * Running on all addresses (0.0.0.0)
flask-app | * Running on http://127.0.0.1:5000
flask-app | Press CTRL+C to quit
React
以下の2ファイルを作成します。
- Dockerfile
FROM node:20.12
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 5173
CMD [ "npm", "run", "dev" ]
- docker-compose.yml
version: '3.8'
services:
react:
container_name: react-app
build:
context: .
dockerfile: Dockerfile
ports:
- '5173:5173'
command: npm run dev
続いてDocker Compose を利用してコンテナを起動します。
docker-compose up
time="2024-08-04T17:11:04+09:00" level=warning msg="C:\\sample\\frontend\\docker-compose.yaml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion"
[+] Running 2/2
✔ Network frontend_default Created 0.0s
✔ Container react-app Created 0.1s
Attaching to react-app
react-app |
react-app | > frontend@0.0.0 dev
react-app | > vite
react-app |
react-app | Re-optimizing dependencies because vite config has changed
react-app |
react-app | VITE v5.3.5 ready in 319 ms
react-app |
react-app | ➜ Local: http://localhost:5173/
はまった修正
C:\sample\frontend>netstat -ano | findstr 5173
TCP 0.0.0.0:5173 0.0.0.0:0 LISTENING 42764
TCP [::]:5173 [::]:0 LISTENING 42764
TCP [::1]:5173 [::]:0 LISTENING 43788
- vite.config.js
defineConfig に server の port を加えると固定 React側のポートが固定され、画面が表示されるようになりました。
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
// ここから追加
server: {
host: '0.0.0.0',
port: 5173,
},
// ここまで
plugins: [react()],
})