使用 docker compose 轻松创建 React + FastAPI + MySQL 试用本地环境
动机
- 我想尝试使用 React 进行静态托管。
- 我想用 FastAPI 创建动态内容并相应地调用它。
- 我想把 FastAPI 和数据库连接起来,将来让 FastAPI 服务器无服务器。
本文的目的
在 React 生成的页面中,使用 FastAPI 制作的 API 在浏览器上查看 MySQL 中的数据。
初始目录结构
- docker-compose.yml
- 客户端
- Dockerfile
- 服务器
- Dockerfile
- requirements.txt
- 代码
- db.py
- main.py
- 模型.py
- mysql
- conf.d
- my.cnf
- initdb.d
- schema.sql
- testdata.sql
- 日志
- mysql
- conf.d
泊坞窗文件
码头工人-compose.yml
码头工人-compose.yml
version: "3"
services:
db:
container_name: back_db
image: mysql:5.7
restart: always
tty: true
environment:
MYSQL_DATABASE: sample_db
MYSQL_USER: user
MYSQL_PASSWORD: password
MYSQL_ROOT_PASSWORD: password
ports:
- 3306:3306
command: --port 3306
volumes:
- ./mysql/initdb.d:/docker-entrypoint-initdb.d
- ./mysql/conf.d:/etc/myaql/conf.d
- ./mysql/log/mysql:/var/log/mysql
server:
links:
- db
build: ./server/
tty: true
container_name: back_fastapi
working_dir: /usr/src/server
ports:
- 8080:8080
volumes:
- ./server/code/:/usr/src/server
client:
build: ./client/
container_name: front_react
ports:
- 3000:3000
volumes:
- ./server/:/var/www/server/
- ./client/:/var/www/client/
tty: true
stdin_open: true
command: sh -c "cd test_app && npm start"
- 点
- 每次启动容器时,客户端命令都会启动 React 服务器。
- 服务器实际上可能是通过命令启动的,但是这次我是用后面会出现的FastAPI Dockerfile启动的。
- 我认为将 MySQL 环境变量设置项放在 .env 或其他文件中并 gitignore 会更好。
服务器/Dockerfile
Dockerfile
FROM python:3.8
WORKDIR /usr/src/server
ADD ./requirements.txt .
RUN pip install --trusted-host pypi.python.org -r requirements.txt
CMD ["uvicorn", "main:app", "--reload", "--host", "0.0.0.0", "--port", "8080"]
- 点
- 清楚地写WORKDIR似乎很重要。
- 将 requirements.txt 添加到容器中以构建环境。
- CMD 命令可能与 docker-compose 命令相同(不确定)
客户端/Dockerfile
Dockerfile
FROM node:latest
WORKDIR /var/www/client/
RUN npm install -g create-react-app
RUN npm install --save react-router-dom
RUN npm install --save prop-types
- 点
- 我还建了一个Dockerfile来搭建环境
服务器内容
要求.txt
需求.txt
mysqlclient
sqlalchemy
uvicorn
fastapi
- 点
- 以上两个是用SQL连接的
- 底部两个用于设置 FastAPI 服务器
代码/main.py
矿。 py
from fastapi import FastAPI
from typing import List # ネストされたBodyを定義するために必要
from starlette.middleware.cors import CORSMiddleware # CORSを回避するために必要
from db import session # DBと接続するためのセッション
from model import UserTable, User # 今回使うモデルをインポート
app = FastAPI()
# CORSを回避するために設定
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# ----------APIの実装------------
@app.get("/")
def read_root():
return {"Hello": "World!!!!"}
# テーブルにいる全ユーザ情報を取得 GET
@app.get("/users")
def read_users():
users = session.query(UserTable).all()
return users
- 点
- 在 root 中点击 FastAPI 会返回 {"Hello": "World!!!!"}。点击
- /users 将返回数据库中用户的键查询。
代码/db.py
D B。 py
# -*- coding: utf-8 -*-
# DBへの接続設定
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session
# 接続したいDBの基本情報を設定
user_name = "user"
password = "password"
host = "db" # docker-composeで定義したMySQLのサービス名
database_name = "sample_db"
DATABASE = 'mysql://%s:%s@%s/%s?charset=utf8' % (
user_name,
password,
host,
database_name,
)
# DBとの接続
ENGINE = create_engine(
DATABASE,
encoding="utf-8",
echo=True
)
# Sessionの作成
session = scoped_session(
# ORM実行時の設定。自動コミットするか、自動反映するか
sessionmaker(
autocommit=False,
autoflush=False,
bind=ENGINE
)
)
# modelで使用する
Base = declarative_base()
# DB接続用のセッションクラス、インスタンスが作成されると接続する
Base.query = session.query_property()
代码/model.py
藻湖py
# -*- coding: utf-8 -*-
# モデルの定義
from sqlalchemy import Column, Integer, String
from pydantic import BaseModel
from db import Base
from db import ENGINE
# userテーブルのモデルUserTableを定義
class UserTable(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(30), nullable=False)
age = Column(Integer)
# POSTやPUTのとき受け取るRequest Bodyのモデルを定義
class User(BaseModel):
id: int
name: str
age: int
def main():
# テーブルが存在しなければ、テーブルを作成
Base.metadata.create_all(bind=ENGINE)
if __name__ == "__main__":
main()
mysql内容
conf.d/my.cnf
我的.cnf
[mysqld]
character-set-server=utf8
skip-character-set-client-handshake=utf8
default-storage-engine=INNODB
explicit-defaults-for-timestamp=1
general-log=1
general-log-file=/var/log/mysql/mysqld.log
[mysqldump]
default-character-set=utf8
[mysql]
default-character-set=utf8
[client]
default-character-set=utf8
- 点
- 主要是字符代码设置
initdb.d/schema.sql
架构.sql
CREATE TABLE user (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(30) NOT NULL,
age INT,
PRIMARY KEY (id)
);
initdb.d/testdata.sql
测试数据.sql
INSERT INTO user (name, age) VALUES ("saburo", 15);
INSERT INTO user (name, age) VALUES ("jiro", 18);
INSERT INTO user (name, age) VALUES ("taro", 20);
引导命令
docker compose run --rm client sh -c "create-react-app test_app"
docker compose up -d --remove-orphans
第一行只是开始。为反应创建初始文件夹的命令。
从第二次开始,只有第二行是可以的
最初
在 localhost:3000 反应初始屏幕
{"Hello": "World!!!!"} 在 localhost:8080
您应该能够在 localhost:8080/users 看到 testdata.sql 中用户集的内容。
从 React 调用 API
模块安装
docker compose exec client bash
root@xxxxxxxxxxxx:/var/www/client# cd app_test
root@xxxxxxxxxxxx:/var/www/client/app_test# npm install --save axios
更新 App.js
客户端/test_app/App.js
import React from "react";
import axios from "axios";
function App() {
const [data, setData] = React.useState();
const url = "http://127.0.0.1:8080";
const GetData = () => {
axios.get(url).then((res) => {
setData(res.data);
});
};
const url_users = "http://127.0.0.1:8080/users";
const GetData_users = () => {
axios.get(url_users).then((res) => {
setData(res.data);
});
};
return (
<div>
{/* <div>8080</div>
{data ? <div>{data.Hello}</div> : <button onClick={GetData}>データを取得 Hello</button>} */}
<div>8080/users</div>
{data ? <div>{data[1].name}</div> : <button onClick={GetData_users}>データを取得 Users</button>}
</div>
);
}
export default App;
- 点
- 如果出现 jiro 则确定。达到的目的
- 熟悉 React 的人应该可以做得更好
退出命令
docker compose stop
参考文章
https://qiita.com/KWS_0901/items/684ac71e728575b6eab0
https://qiita.com/ikeikeda/items/eeed5abb2230bf031ba5
https://qiita.com/A-Kira/items/d2f9c8cef9346cb32229
原创声明:本文系作者授权爱码网发表,未经许可,不得转载;
原文地址:https://www.likecs.com/show-308622615.html