cpa*_*age 5 nginx docker reactjs axios fastapi
nginx
我已经使用React 和 FastAPI 来提供服务docker
。当我运行时docker-compose up
,一切都可以使用react应用程序localhost:3000
和api来运行localhost:8000
。例如,get请求localhost:8000/fleets/
返回期望的结果。localhost:3000/api/
不过,我希望能够访问 api 。
当我添加--root-path /api
到 FastAPI时Dockerfile
,React 应用程序仍然在 加载localhost:3000
,并且我能够访问 api localhost:3000/api/
,但我的 React 应用程序在尝试查询 api 时收到 404 错误。当我转到 Chrome 中的“网络”选项卡时,我看到反应查询导致http://127.0.0.1:8000/api/fleets/
404 错误。不过该 API 仍然可用localhoost:8000/fleets/
。
我的反应应用程序应该在localhost:3000/api/
or处查询localhost:8000
吗?我该如何进行此调整?
请注意,我正在使用axios
,但更改axios.defaults.baseURL
似乎没有产生影响。我目前的axios.defaults.baseURL = \'/\';
反应是App.jsx
。
"proxy": "http://127.0.0.1:3000"
我也从我的react中删除了package.json
。\n在FastAPI中,我有origins = ["http://localhost:3000", "http://127.0.0.1:8000"]
处理CORS的能力。
快速API Dockerfile
:
FROM python:3.8-alpine\nENV PYTHONBUFFERED 1\nWORKDIR /api\nCOPY requirements.txt requirements.txt\nRUN pip install -r requirements.txt\nCOPY . .\n
Run Code Online (Sandbox Code Playgroud)\n反应Dockerfile
:
FROM node:15.13-alpine\nWORKDIR /react\nCOPY . .\nRUN yarn run build\n
Run Code Online (Sandbox Code Playgroud)\nnginx-setup.conf
:
upstream api {\n server backend:8000;\n}\n\nserver {\n listen 8080;\n\n location / {\n root /var/www/react;\n }\n\n location /api/ {\n proxy_pass http://api/;\n proxy_set_header Host $http_host;\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\ndocker-compose.yml
:
version: \'3\'\n\nservices:\n backend:\n build:\n context: ./api\n command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --root-path /api\n ports:\n - 8000:8000\n \n frontend:\n build:\n context: ./react\n volumes:\n - react_build:/react/build\n\n nginx:\n image: nginx:latest\n ports:\n - 3000:8080\n volumes:\n - ./nginx/nginx-setup.conf:/etc/nginx/conf.d/default.conf:ro\n - react_build:/var/www/react\n depends_on:\n - backend\n - frontend\n\nvolumes:\n react_build:\n
Run Code Online (Sandbox Code Playgroud)\n编辑(了解更多详细信息)
\n当没有运行时--root-path /api
:
localhost:3000/api/fleets/
确实有效。localhost:3000/api/fleets
被重定向localhost:3000/fleets/
到 nginx 404localhost:3000/api/docs
给出Failed to load API definition
错误。localhost:8000/docs
作品。localhost:8000/fleets/
作品。localhost:8000/fleets
被重定向到localhost:8000/fleets/
并工作。http://127.0.0.1:8000/fleets
并被重定向到http://127.0.0.1:8000/fleets/
有效的位置。当运行时--root-path /api
:
localhost:3000/api/fleets/
作品localhost:3000/api/fleets
被重定向到localhost:3000/api/fleets/
并工作localhost:3000/api/docs
作品localhost:8000/docs
给出加载 API 定义失败错误。http://localhost:8000/fleets/
作品。http://localhost:8000/fleets
被重定向到localhost:8000/api/fleets/ and gives
FastAPI 404
{"detail": "Not Found"}`编辑这里有一个简单的可重现示例:
\n.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 backend\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 main.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Dockerfile\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 requirements.txt\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 docker-compose.yml\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 frontend\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Dockerfile\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package.json\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 App.css\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 App.jsx\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 App.test.js\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 index.css\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 index.js\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 logo.svg\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 reportWebVitals.js\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 setupTests.js\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 yarn.lock\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 nginx\n\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 nginx-setup.conf\n
Run Code Online (Sandbox Code Playgroud)\n./backend/app/main.py
from fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\napp = FastAPI()\n\norigins = [\n "http://localhost:3000"\n]\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=["*"],\n allow_headers=["*"],\n)\n\n@app.get("/day", tags=["Dates"])\nasync def get_day_of_week(day_num: int = 0):\n """\n Get the current day of week\n """\n days = [\'Sun\', \'Mon\', \'Tues\', \'Wed\', \'Thur\', \'Fri\', \'Sat\']\n return days[day_num]\n
Run Code Online (Sandbox Code Playgroud)\n./backend/Dockerfile
FROM python:3.8-alpine\nENV PYTHONBUFFERED 1\nWORKDIR /alpine\nCOPY requirements.txt requirements.txt\nRUN pip install -r requirements.txt\nCOPY . .\n
Run Code Online (Sandbox Code Playgroud)\n./backend/requirements.txt
anyio==3.6.1\nclick==8.1.3\ncolorama==0.4.5\nfastapi==0.78.0\nh11==0.13.0\nidna==3.3\npydantic==1.9.1\nsniffio==1.2.0\nstarlette==0.19.1\ntyping_extensions==4.3.0\nuvicorn==0.18.2\n
Run Code Online (Sandbox Code Playgroud)\n./frontend/src/App.jsx
import React, { useState, useEffect } from \'react\';\nimport \'./App.css\';\n\nfunction App() {\n\n const [error, setError] = useState(null); \n const [day, setDay] = useState(\'Sun\');\n\n useEffect(() => {\n fetch(\'http://localhost:3000/api/day?day_num=3\')\n .then((res) => setDay(res.data))\n .catch((err) => setError(err.message))\n }, []);\n\n return (\n <>\n <>Hello</>\n <>{day}{error}</>\n </>\n );\n}\n\nexport default App;\n
Run Code Online (Sandbox Code Playgroud)\n./frontend/Dockerfile
FROM node:15.13-alpine\nWORKDIR /frontend\nCOPY . .\nRUN yarn run build\n
Run Code Online (Sandbox Code Playgroud)\n./frontend/.dockerignore
#node_modules\nbuild\n
Run Code Online (Sandbox Code Playgroud)\n./frontend/package.json
{\n "name": "frontend",\n "version": "0.1.0",\n "private": true,\n "dependencies": {\n "@testing-library/jest-dom": "^5.14.1",\n "@testing-library/react": "^11.2.7",\n "@testing-library/user-event": "^12.8.3",\n "axios": "^0.27.2",\n "react": "^17.0.2",\n "react-dom": "^17.0.2",\n "react-scripts": "4.0.3",\n "web-vitals": "^1.1.2"\n },\n "scripts": {\n "start": "react-scripts start",\n "build": "react-scripts build",\n "test": "react-scripts test",\n "eject": "react-scripts eject"\n },\n "eslintConfig": {\n "extends": [\n "react-app",\n "react-app/jest"\n ]\n },\n "browserslist": {\n "production": [\n ">0.2%",\n "not dead",\n "not op_mini all"\n ],\n "development": [\n "last 1 chrome version",\n "last 1 firefox version",\n "last 1 safari version"\n ]\n }\n }\n
Run Code Online (Sandbox Code Playgroud)\n./nginx/nginx-setup.conf
upstream api {\n server backend:8000;\n}\n\nserver {\n listen 8080;\n\n location / {\n root /var/www/react;\n }\n\n location /api/ {\n proxy_pass http://api/;\n proxy_set_header Host $http_host;\n proxy_set_header X-Real-IP $remote_addr;\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n./docker-compose.yml
version: \'3\'\n\nservices:\n backend:\n build:\n context: ./backend\n command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --root-path /api\n ports:\n - 8000:8000\n\n frontend:\n build:\n context: ./frontend\n volumes:\n - react_build:/frontend/build\n\n nginx:\n image: nginx:latest\n ports:\n - 3000:8080\n volumes:\n - ./nginx/nginx-setup.conf:/etc/nginx/conf.d/default.conf:ro\n - react_build:/var/www/react\n depends_on:\n - backend\n - frontend\nvolumes:\n react_build:\n
Run Code Online (Sandbox Code Playgroud)\n
我认为你把事情搞混了,通常是这样做的:
您的后端应用程序(FastAPI)在某个端口上运行,让它成为:localhost:8000
您的前端应用程序(React)在某个端口上运行,让它成为:
localhost:3000
另外,你使用Nginx,所以路线是:前端 -> nginx -> 后端
我的 React 应用程序应该在 localhost:3000/api/ 或 localhost:8000 进行查询吗?我该如何进行此调整?
下界。您进行查询的正确http://localhost:8080/api/
地址是(您通过 Nginx 代理所有请求),此指令location /api/
意味着所有请求都localhost:8080/api/
将被代理到localhost:8000
,对于生产,您需要指定端口 80 并配置 SSL。
由于缺少代码,我看不到全貌,但我想这--root-path
不是你想要的。另外请仔细检查 docker-compose 中的端口,您的应用程序(前端)必须仅使用 8080 端口,不要暴露 8000。
归档时间: |
|
查看次数: |
2318 次 |
最近记录: |