Allow setting path prefix (#1344)

* allow setting the path prefix of the server w/ burnettk

* added error in case someone was successfully using SPIFFWORKFLOW_BACKEND_APPLICATION_ROOT w/ burnettk

* Update docs/DevOps_installation_integration/path_based_routing.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: jasquat <jasquat@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
jasquat 2024-04-05 19:14:09 +00:00 committed by GitHub
parent 18edf627db
commit 01c749aa0b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 27 additions and 14 deletions

View File

@ -17,7 +17,6 @@ services:
container_name: spiffworkflow-backend
image: ghcr.io/sartography/spiffworkflow-backend:latest
environment:
SPIFFWORKFLOW_BACKEND_APPLICATION_ROOT: "/"
SPIFFWORKFLOW_BACKEND_ENV: "local_docker"
FLASK_DEBUG: "0"
FLASK_SESSION_SECRET_KEY: "${FLASK_SESSION_SECRET_KEY:-super_secret_key}"

View File

@ -4,20 +4,20 @@ If you are using frontend, frontend and backend need to share cookies.
Backend, in particular, sets a cookie, and frontend needs to read it.
As such, you cannot run frontend and backend on different subdomains, like this:
* frontend.example.com
* backend.example.com
- frontend.example.com
- backend.example.com
Instead, we often run them like this:
* example.com for frontend
* api.example.com for backend
- example.com for frontend
- api.example.com for backend
This works, since backend can set a cookie for the entire domain, and frontend can read it.
Another alternative that works well is to run them on the same host, but with different paths, like this:
* spiff.example.com for frontend
* spiff.example.com/api for backend
- spiff.example.com for frontend
- spiff.example.com/api for backend
To accomplish this path-based routing scenario, set environment variables like this in frontend:
@ -38,3 +38,12 @@ SPIFFWORKFLOW_BACKEND_CONNECTOR_PROXY_URL=http://spiffworkflow-connector:8004
Backend does not support paths like `/api/v1.0/status`, but instead wants `/v1.0/status`.
As such, a proxy in frontend of backend will need to remove the `/api` part of the path before handing the request to backend.
If you are hitting backend at a URL like spiff.example.com/api and not rewriting the path to remove the /api prefix, you can inform backend about this situation by setting this environment variable:
```sh
SPIFFWORKFLOW_BACKEND_WSGI_PATH_PREFIX=/api
```
This will be used as the wsgi SCRIPT_NAME, which essentially removes the prefix before handing the url to the app for routing, but also allows urls generated by the app to return things like /api/v1.0/status.
wsgi is a standard for serving python apps, and there are implementations like gunicorn, green unicorn, uWSGI, mod_wsgi, CherryPy, etc.

View File

@ -49,7 +49,16 @@ additional_args=""
app_root="${SPIFFWORKFLOW_BACKEND_APPLICATION_ROOT:-}"
if [[ -n "$app_root" ]] && [[ "${app_root}" != "/" ]]; then
additional_args="${additional_args} -e SCRIPT_NAME=${app_root}"
echo >&2 "ERROR: SPIFFWORKFLOW_BACKEND_APPLICATION_ROOT has been set. This variable has been renamed to SPIFFWORKFLOW_BACKEND_WSGI_PATH_PREFIX. Please use that instead."
exit 1
fi
path_prefix="${SPIFFWORKFLOW_BACKEND_WSGI_PATH_PREFIX:-}"
if [[ -n "$path_prefix" ]] && [[ "${path_prefix}" != "/" ]]; then
if ! grep -E '^/' <<<"${path_prefix}"; then
echo >&2 "ERROR: SPIFFWORKFLOW_BACKEND_WSGI_PATH_PREFIX must start with a '/'. '$SPIFFWORKFLOW_BACKEND_WSGI_PATH_PREFIX' was used instead."
exit 1
fi
additional_args="${additional_args} -e SCRIPT_NAME=${path_prefix}"
fi
# HACK: if loading fixtures for acceptance tests when we do not need multiple workers

View File

@ -64,9 +64,6 @@ if [[ -z "${SPIFFWORKFLOW_BACKEND_ENV:-}" ]]; then
fi
export FLASK_SESSION_SECRET_KEY="e7711a3ba96c46c68e084a86952de16f"
export SPIFFWORKFLOW_BACKEND_APPLICATION_ROOT="/"
export FLASK_DEBUG=1
if [[ -z "${SPIFFWORKFLOW_BACKEND_RUN_BACKGROUND_SCHEDULER_IN_CREATE_APP:-}" ]]; then
SPIFFWORKFLOW_BACKEND_RUN_BACKGROUND_SCHEDULER_IN_CREATE_APP=true

View File

@ -18,10 +18,10 @@ server_type="${1:-api}"
if [[ "$server_type" == "celery_worker" ]]; then
"${script_dir}/start_celery_worker"
else
if [[ -n "${SPIFFWORKFLOW_BACKEND_LOAD_FIXTURE_DATA:-}" ]]; then
if [[ -n "${SPIFFWORKFLOW_BACKEND_LOAD_FIXTURE_DATA:-}" || -n "${SPIFFWORKFLOW_BACKEND_WSGI_PATH_PREFIX:-}" ]]; then
echo "using ./bin/boot_server_in_docker because we actually load fixture data in wsgi.py, which will not be run with the typical local dev flask server"
./bin/boot_server_in_docker
else
export FLASK_DEBUG=1
if [[ "${SPIFFWORKFLOW_BACKEND_RUN_DATA_SETUP:-}" != "false" ]]; then
SPIFFWORKFLOW_BACKEND_RUN_BACKGROUND_SCHEDULER_IN_CREATE_APP=false SPIFFWORKFLOW_BACKEND_FAIL_ON_INVALID_PROCESS_MODELS=false poetry run python bin/save_all_bpmn.py

View File

@ -52,7 +52,6 @@ services:
environment:
- FLASK_DEBUG=0
- FLASK_SESSION_SECRET_KEY=${FLASK_SESSION_SECRET_KEY:-e7711a3ba96c46c68e084a86952de16f}
- SPIFFWORKFLOW_BACKEND_APPLICATION_ROOT=/
- SPIFFWORKFLOW_BACKEND_BPMN_SPEC_ABSOLUTE_DIR=/app/process_models
- SPIFFWORKFLOW_BACKEND_DATABASE_URI=mysql+mysqldb://root:${SPIFFWORKFLOW_BACKEND_MYSQL_ROOT_DATABASE:-my-secret-pw}@127.0.0.1:7003/${SPIFFWORKFLOW_BACKEND_DATABASE_NAME:-spiffworkflow_backend_development}
- SPIFFWORKFLOW_BACKEND_ENV=${SPIFFWORKFLOW_BACKEND_ENV:-local_development}