-
Notifications
You must be signed in to change notification settings - Fork 14.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: Allow superset to be deployed under a prefixed URL #30134
base: master
Are you sure you want to change the base?
Conversation
Thanks for tackling this... it's a popular request, no doubt about it. If you think it's relevant, we might also want to add an entry in the documentation somewhere. |
Yes agreed I definitely need to add some documentation for how to use this. I wanted to wait until I was more confident that the general approach was acceptable before working on describing how to use it. In terms of a review as part of #26319 is there anything I need to do at the moment? |
); | ||
this.baseUrl = url.href.replace(/\/+$/, ''); // always strip trailing slash | ||
this.basePath = basePath.replace(/\/+$/, ''); // always strip trailing slash |
Check failure
Code scanning / CodeQL
Polynomial regular expression used on uncontrolled data High
regular expression
library input
This
regular expression
library input
I think this may be quite an undertaking and might have to be tackled in phases. Would love to see this done :) I remember giving it a shot early on in the project at least once, and never wrapped up the work. My main advice would be to avoid taking in side mission or bigger refactor while tackling this. |
docker/docker-frontend.sh
Outdated
@@ -17,19 +17,23 @@ | |||
# | |||
set -e | |||
|
|||
# zstd exe is required by simple-zstd package | |||
apt-get update | |||
apt-get install -y zstd |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's a recent fix in master for this
Thanks for these changes. |
For what it's worth, we've been running this fork to serve superset on a path prefix in a Kubernetes(K3S) + traefik context without any problems so far. Though testing has been limited. Thanks for the work so far |
93d66c7
to
09a05b3
Compare
09a05b3
to
fe3b01a
Compare
Sorry for the delay in replying to this. I've had zero time to spend on this lately. The latest commits rebase on the current master and I have also added some documentation to the configuring superset pages that describe the new variables with an example |
If you think it's ready for review, I'd say you can go ahead and move it from Draft to "Ready for Review" - though it looks like CI might need a little more love still. As for the SIP, since @sfirke reopened the GitHub issue, I set the SIP itself back to "pre-discussion" state for its official consensus. Did you want to re-kindle that pre-existing SIP, or would it be easier to open a new one? I'm happy to help you carry that SIP through to fruition if you'd like. Feel free to DM me on slack if it's easier. |
When clicking on the user list or role list, and then clicking on datasets, a 404 error appears. |
Thanks a lot for the response. Also dashboard menu items export to PDF/image not working (Dashboard -> Download -> Export to PDF/Download as Image) |
I tried to fix above issue of missing prefixes in top-level menu. Please check this PR 2 |
The solution really works. Solved a long term issue in our deployment behind proxies. Hoping to get merged soon with official code base |
Very good, looking forward to merging the code soon |
For whom it may concern, I'm testing with a port of this work to 3.1.1rc1 available from watercraft:superset branch prefix |
Hi, I can see this PR is still flagged as DRAFT. What's left to do to get it "Ready for Review" ? @martyngigg do you need help in completing this PR ? I'm quite a superset newbie, but I'm willing to provide some help if necessary to get this merged. |
Docker version of superset_config sets ENABLE_PROXY_FIX=True if BASE_PATH not empty.
Also simplifies Nginx server block so it no longer needs modifying when a prefix is set or not - simply set the BASE_PATH/ASSET_BASE_URL environment variables when running docker compose and it will take case of the rest.
If not an empty string, a new middleware class is attached to the wsgi_app callable that intercepts each request and transforms the SCRIPT_NAME & PATH_INFO variables in the request environment so that the rest of the code still sees non-prefixed paths yet the application itself appears to sit on a common subpath. A new environment variable SUPERSET_APP_ROOT has been introduced into the docker config to control the value of the application root.
Adjusted Flask app templates to include the static_assets_prefix and webpack build dir while rendering. This removes the need to rebuild the frontend in order to Superset it at a different application prefix.
9b77478
to
e0eb2ed
Compare
Korbit doesn't automatically review large (500+ lines changed) pull requests such as this one. If you want me to review anyway, use |
window.location.href = ensureBasePath( | ||
`/superset/dashboard/${resp.json.result.id}/`, | ||
); |
Check warning
Code scanning / CodeQL
DOM text reinterpreted as HTML Medium
DOM text
@@ -193,7 +194,7 @@ | |||
), | |||
buttonStyle: 'tertiary', | |||
onClick: () => { | |||
window.location.assign('/chart/add'); | |||
window.location.assign(ensureBasePath('/chart/add')); |
Check warning
Code scanning / CodeQL
DOM text reinterpreted as HTML Medium
DOM text
@@ -196,19 +197,20 @@ | |||
), | |||
buttonStyle: 'tertiary', | |||
onClick: () => { | |||
window.location.assign('/dashboard/new'); | |||
window.location.assign(ensureBasePath('/dashboard/new')); |
Check warning
Code scanning / CodeQL
DOM text reinterpreted as HTML Medium
DOM text
@@ -171,7 +173,7 @@ | |||
<Button | |||
buttonStyle="primary" | |||
onClick={() => { | |||
window.location.href = favRedirects[tableName]; | |||
window.location.href = ensureBasePath(favRedirects[tableName]); |
Check warning
Code scanning / CodeQL
DOM text reinterpreted as HTML Medium
DOM text
@@ -313,11 +314,11 @@ | |||
> | |||
{isFrontendRoute(window.location.pathname) ? ( | |||
<GenericLink className="navbar-brand" to={brand.path}> | |||
<img src={brand.icon} alt={brand.alt} /> | |||
<img src={assetUrl(brand.icon)} alt={brand.alt} /> |
Check warning
Code scanning / CodeQL
DOM text reinterpreted as HTML Medium
DOM text
@@ -460,7 +461,7 @@ | |||
{menu.label} | |||
</Link> | |||
) : ( | |||
<a href={menu.url}> | |||
<a href={ensureBasePath(menu.url || '')}> |
Check warning
Code scanning / CodeQL
DOM text reinterpreted as HTML Medium
DOM text
@@ -495,7 +496,9 @@ | |||
{isFrontendRoute(child.url) ? ( | |||
<Link to={child.url || ''}>{menuItemDisplay}</Link> | |||
) : ( | |||
<a href={child.url}>{menuItemDisplay}</a> | |||
<a href={ensureBasePath(child.url || '')}> |
Check warning
Code scanning / CodeQL
DOM text reinterpreted as HTML Medium
DOM text
@@ -264,7 +266,7 @@ | |||
name: t('View All »'), | |||
buttonStyle: 'link', | |||
onClick: () => { | |||
window.location.href = '/savedqueryview/list'; | |||
window.location.href = ensureBasePath('/savedqueryview/list'); |
Check warning
Code scanning / CodeQL
DOM text reinterpreted as HTML Medium
DOM text
@@ -277,7 +278,7 @@ | |||
}; | |||
|
|||
const onLayerAdd = (id?: number) => { | |||
window.location.href = `/annotationlayer/${id}/annotation`; | |||
window.location.href = ensureBasePath(`/annotationlayer/${id}/annotation`); |
Check warning
Code scanning / CodeQL
DOM text reinterpreted as HTML Medium
DOM text
@@ -682,7 +683,7 @@ | |||
), | |||
buttonStyle: 'primary', | |||
onClick: () => { | |||
window.location.assign('/dashboard/new'); | |||
window.location.assign(ensureBasePath('/dashboard/new')); |
Check warning
Code scanning / CodeQL
DOM text reinterpreted as HTML Medium
SUMMARY
Introduces changes in the front and backend to allow Superset to be deployed under a prefixed-URL path rather than the root of the domain.
The backend
superset.app:create_app
has been augemented with a newapp_root
argument that accepts a root path for the application. This is passed through theFLASK_APP
environment variable or theflask --app
cli argument. When the path is not/
a middleware is created that intercepts paths and updates them to strip theapp_root
and forward them to the rest of the application. This was inspired by Application Dispatching.The backend has also been refactored to avoid using hardcoded paths in redirects and instead uses
Flask.url_for
to construct all references.The frontend has been updated to include the prefix in any resource links along with two new helper utilities,
assetUrl
&pathUtils
, to help construct the paths. TheSupersetClient
has been updated to remove the unusedbaseUrl
field and rename it asbasePath
such that the object can be initialized with the base path and calling any endpoints through this class can use the same relative link as before. QUESTION: Have I broken an API here?Documentation has been added to the "Configuring Superset" pages that demonstrate how to use the new arugment.
BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
TESTING INSTRUCTIONS
ADDITIONAL INFORMATION