Include app.Dockerfile for deploying to container hosting platform (#2784)

This commit is contained in:
Masen Furer 2024-03-05 09:28:32 -08:00 committed by GitHub
parent fc190c8c8f
commit e4c32e3edf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 73 additions and 2 deletions

View File

@ -11,7 +11,7 @@ RUN pip install -r requirements.txt
# Deploy templates and prepare app
RUN reflex init
# Download all npm dependencies and compile and frontend
# Download all npm dependencies and compile frontend
RUN reflex export --frontend-only --no-zip
# Needed until Reflex properly passes SIGTERM on backend.

View File

@ -116,4 +116,18 @@ to deploy these services if they are not in active use.
```bash
DOMAIN=example.com docker compose -f compose.yaml -f compose.prod.yaml -f compose.tools.yaml up -d
```
```
# Container Hosting
Most container hosting services automatically terminate TLS and expect the app
to be listening on a single port (typically `$PORT`).
To host a Reflex app on one of these platforms, like Google Cloud Run, Render,
Railway, etc, use `app.Dockerfile` to build a single image containing a reverse
proxy that will serve that frontend as static files and proxy requests to the
backend for specific endpoints.
If the chosen platform does not support buildx and thus heredoc, you can copy
the Caddyfile configuration into a separate Caddyfile in the root of the
project.

View File

@ -0,0 +1,57 @@
# This Dockerfile is used to deploy a single-container Reflex app instance
# to services like Render, Railway, Heroku, GCP, and others.
# It uses a reverse proxy to serve the frontend statically and proxy to backend
# from a single exposed port, expecting TLS termination to be handled at the
# edge by the given platform.
FROM python:3.11
# If the service expects a different port, provide it here (f.e Render expects port 10000)
ARG PORT=8080
# Only set for local/direct access. When TLS is used, the API_URL is assumed to be the same as the frontend.
ARG API_URL
ENV PORT=$PORT API_URL=${API_URL:-http://localhost:$PORT}
# Install Caddy server inside image
RUN apt-get update -y && apt-get install -y caddy && rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Create a simple Caddyfile to serve as reverse proxy
RUN cat > Caddyfile <<EOF
:{\$PORT}
encode gzip
@backend_routes path /_event/* /ping /_upload /_upload/*
handle @backend_routes {
reverse_proxy localhost:8000
}
root * /srv
route {
try_files {path} {path}/ /404.html
file_server
}
EOF
# Copy local context to `/app` inside container (see .dockerignore)
COPY . .
# Install app requirements and reflex in the container
RUN pip install -r requirements.txt
# Deploy templates and prepare app
RUN reflex init
# Download all npm dependencies and compile frontend
RUN reflex export --frontend-only --no-zip && mv .web/_static/* /srv/ && rm -rf .web
# Needed until Reflex properly passes SIGTERM on backend.
STOPSIGNAL SIGKILL
EXPOSE $PORT
# Apply migrations before starting the backend.
CMD [ -d alembic ] && reflex db migrate; \
caddy start && reflex run --env prod --backend-only --loglevel debug