Skip to content

Instantly share code, notes, and snippets.

@epoz
Created November 19, 2021 15:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save epoz/6ca453441582b8a1062979474071880d to your computer and use it in GitHub Desktop.
Save epoz/6ca453441582b8a1062979474071880d to your computer and use it in GitHub Desktop.
Demo of running a REACT SPA using Starlette/FASTAPI in a Dockerfile
FROM node:10 as build
WORKDIR /usr/src
COPY package*.json ./
RUN npm install
COPY . ./
RUN npm run build
FROM python:3.7.9-alpine
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
ARG REACT_APP_URL_PATH="/"
COPY --from=build /usr/src/build /var/www
COPY spa.py spa.py
CMD ["python", "spa.py"]
from starlette.applications import Starlette
from starlette.routing import Route, Mount
from starlette.responses import PlainTextResponse, Response
from starlette.staticfiles import StaticFiles
from starlette.types import Scope
import uvicorn
import os
async def ping(request):
return PlainTextResponse("pong")
async def index(request):
return PlainTextResponse("Hello")
class SPAStaticFiles(StaticFiles):
async def get_response(self, path: str, scope: Scope) -> Response:
response = await super().get_response(path, scope)
if response.status_code == 404:
response = await super().get_response("index.html", scope)
return response
routes = [
Route("/ping", ping),
Route("/", index),
Mount(
os.environ.get("REACT_APP_URL_PATH"),
app=SPAStaticFiles(
directory=os.environ.get("REACT_APP_LOCAL_PATH") or "/var/www"
),
),
]
app = Starlette(routes=routes)
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000, log_level="debug")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment