113 lines
3.9 KiB
Markdown
113 lines
3.9 KiB
Markdown
# production-app-platform
|
|
|
|
This example deployment is intended for use with App hosting platforms, like
|
|
Azure, AWS, or Google Cloud Run.
|
|
|
|
## Architecture
|
|
|
|
The production deployment consists of a few pieces:
|
|
* Backend container - built by `Dockerfile` Runs the Reflex backend
|
|
service on port 8000 and is scalable to multiple instances.
|
|
* Redis container - A single instance the standard `redis` docker image should
|
|
share private networking with the backend
|
|
* Static frontend - HTML/CSS/JS files that are hosted via a CDN or static file
|
|
server. This is not included in the docker image.
|
|
|
|
## Deployment
|
|
|
|
These general steps do not cover the specifics of each platform, but all platforms should
|
|
support the concepts described here.
|
|
|
|
### Vnet
|
|
|
|
All containers in the deployment should be hooked up to the same virtual private
|
|
network so they can access the redis service and optionally the database server.
|
|
The vnet should not be exposed to the internet, use an ingress rule to terminate
|
|
TLS at the load balancer and forward the traffic to a backend service replica.
|
|
|
|
### Redis
|
|
|
|
Deploy a `redis` instance on the vnet.
|
|
|
|
### Backend
|
|
|
|
The backend is built by the `Dockerfile` in this directory. When deploying the
|
|
backend, be sure to set REDIS_URL=redis://internal-redis-hostname to connect to
|
|
the redis service.
|
|
|
|
### Ingress
|
|
|
|
Configure the load balancer for the app to forward traffic to port 8000 on the
|
|
backend service replicas. Most platforms will generate an ingress hostname
|
|
automatically. Make sure when you access the ingress endpoint on `/ping` that it
|
|
returns "pong", indicating that the backend is up an available.
|
|
|
|
### Frontend
|
|
|
|
The frontend should be hosted on a static file server or CDN.
|
|
|
|
**Important**: when exporting the frontend, set the API_URL environment variable
|
|
to the ingress hostname of the backend service.
|
|
|
|
If you will host the frontend from a path other than the root, set the
|
|
`FRONTEND_PATH` environment variable appropriately when exporting the frontend.
|
|
|
|
Most static hosts will automatically use the `/404.html` file to handle 404
|
|
errors. _This is essential for dynamic routes to work correctly._ Ensure that
|
|
missing routes return the `/404.html` content to the user if this is not the
|
|
default behavior.
|
|
|
|
_For Github Pages_: ensure the file `.nojekyll` is present in the root of the repo
|
|
to avoid special processing of underscore-prefix directories, like `_next`.
|
|
|
|
## Platform Notes
|
|
|
|
The following sections are currently a work in progress and may be incomplete.
|
|
|
|
### Azure
|
|
|
|
In the Azure load balancer, per-message deflate is not supported. Add the following
|
|
to your `rxconfig.py` to workaround this issue.
|
|
|
|
```python
|
|
import uvicorn.workers
|
|
|
|
import reflex as rx
|
|
|
|
|
|
class NoWSPerMessageDeflate(uvicorn.workers.UvicornH11Worker):
|
|
CONFIG_KWARGS = {
|
|
**uvicorn.workers.UvicornH11Worker.CONFIG_KWARGS,
|
|
"ws_per_message_deflate": False,
|
|
}
|
|
|
|
|
|
config = rx.Config(
|
|
app_name="my_app",
|
|
gunicorn_worker_class="rxconfig.NoWSPerMessageDeflate",
|
|
)
|
|
```
|
|
|
|
#### Persistent Storage
|
|
|
|
If you need to use a database or upload files, you cannot save them to the
|
|
container volume. Use Azure Files and mount it into the container at /app/uploaded_files.
|
|
|
|
#### Resource Types
|
|
|
|
* Create a new vnet with 10.0.0.0/16
|
|
* Create a new subnet for redis, database, and containers
|
|
* Deploy redis as a Container Instances
|
|
* Deploy database server as "Azure Database for PostgreSQL"
|
|
* Create a new database for the app
|
|
* Set db-url as a secret containing the db user/password connection string
|
|
* Deploy Storage account for uploaded files
|
|
* Enable access from the vnet and container subnet
|
|
* Create a new file share
|
|
* In the environment, create a new files share (get the storage key)
|
|
* Deploy the backend as a Container App
|
|
* Create a custom Container App Environment linked up to the same vnet as the redis container.
|
|
* Set REDIS_URL and DB_URL environment variables
|
|
* Add the volume from the environment
|
|
* Add the volume mount to the container
|
|
* Deploy the frontend as a Static Web App |