From 01c749aa0be7be28e59bae24324cad11739d96c3 Mon Sep 17 00:00:00 2001 From: jasquat <2487833+jasquat@users.noreply.github.com> Date: Fri, 5 Apr 2024 19:14:09 +0000 Subject: [PATCH] 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 Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- docker-compose.yml | 1 - .../path_based_routing.md | 21 +++++++++++++------ .../bin/boot_server_in_docker | 11 +++++++++- .../bin/local_development_environment_setup | 3 --- spiffworkflow-backend/bin/run_server_locally | 4 ++-- spiffworkflow-backend/docker-compose.yml | 1 - 6 files changed, 27 insertions(+), 14 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 4238f6be..d0e96e33 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -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}" diff --git a/docs/DevOps_installation_integration/path_based_routing.md b/docs/DevOps_installation_integration/path_based_routing.md index 837bad7c..0c785498 100644 --- a/docs/DevOps_installation_integration/path_based_routing.md +++ b/docs/DevOps_installation_integration/path_based_routing.md @@ -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. diff --git a/spiffworkflow-backend/bin/boot_server_in_docker b/spiffworkflow-backend/bin/boot_server_in_docker index a0061206..1c306a08 100755 --- a/spiffworkflow-backend/bin/boot_server_in_docker +++ b/spiffworkflow-backend/bin/boot_server_in_docker @@ -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 diff --git a/spiffworkflow-backend/bin/local_development_environment_setup b/spiffworkflow-backend/bin/local_development_environment_setup index 3a2294c2..8c03ed38 100755 --- a/spiffworkflow-backend/bin/local_development_environment_setup +++ b/spiffworkflow-backend/bin/local_development_environment_setup @@ -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 diff --git a/spiffworkflow-backend/bin/run_server_locally b/spiffworkflow-backend/bin/run_server_locally index 8a7d66c6..5b6301e7 100755 --- a/spiffworkflow-backend/bin/run_server_locally +++ b/spiffworkflow-backend/bin/run_server_locally @@ -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 diff --git a/spiffworkflow-backend/docker-compose.yml b/spiffworkflow-backend/docker-compose.yml index 375751b9..f4534cc6 100644 --- a/spiffworkflow-backend/docker-compose.yml +++ b/spiffworkflow-backend/docker-compose.yml @@ -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}