DockerでReactとFlaskAPIを実行してみる

 

はじめに

最近アサインされた案件で、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/
これでhttp://localhost:5173/を実行すると、先程同じよう結果を取得できます。

はまった修正

順調に行く人はここまでで正しく表示されます。
私の場合、先にReact側でポート5173を使用してしまったためなのか、dockerを起動した際、このように別ポートを割り当てられてしまいました。
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
そのため、React側のソースに一手間を加えます。
  • 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()],
})

おわりに

基本環境を整えるのはネットにも記事が多いためそう難しくはありません。
順調に行かなかったときの調査に時間を取られることが多いため、このポートの設定についても備忘録として残したいと思います。
本記事が誰かの助けになれば幸いです。

--------------------------
システム開発のご要望・ご相談はこちらから

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です