使用 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

泊坞窗文件

码头工人-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

相关文章:

  • 2021-12-21
  • 2022-12-23
  • 2021-07-31
  • 2021-06-21
  • 2022-01-05
  • 2021-11-03
  • 2021-07-14
猜你喜欢
  • 2021-07-16
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-07-03
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案