Skip to content

Commit 09b92e7

Browse files
martyngiggkgabryje
andauthored
feat: Allow superset to be deployed under a prefixed URL (#30134)
Co-authored-by: Kamil Gabryjelski <[email protected]>
1 parent 31ac389 commit 09b92e7

File tree

100 files changed

+732
-318
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+732
-318
lines changed

.github/workflows/bashlib.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,14 +145,20 @@ cypress-install() {
145145

146146
cypress-run-all() {
147147
local USE_DASHBOARD=$1
148+
local APP_ROOT=$2
148149
cd "$GITHUB_WORKSPACE/superset-frontend/cypress-base"
149150

150151
# Start Flask and run it in background
151152
# --no-debugger means disable the interactive debugger on the 500 page
152153
# so errors can print to stderr.
153154
local flasklog="${HOME}/flask.log"
154155
local port=8081
155-
export CYPRESS_BASE_URL="http://localhost:${port}"
156+
CYPRESS_BASE_URL="http://localhost:${port}"
157+
if [ -n "$APP_ROOT" ]; then
158+
export SUPERSET_APP_ROOT=$APP_ROOT
159+
CYPRESS_BASE_URL=${CYPRESS_BASE_URL}${APP_ROOT}
160+
fi
161+
export CYPRESS_BASE_URL
156162

157163
nohup flask run --no-debugger -p $port >"$flasklog" 2>&1 </dev/null &
158164
local flaskProcessId=$!

.github/workflows/superset-e2e.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ jobs:
4242
matrix:
4343
parallel_id: [0, 1, 2, 3, 4, 5]
4444
browser: ["chrome"]
45+
app_root: ["", "/app/prefix"]
4546
env:
4647
SUPERSET_ENV: development
4748
SUPERSET_CONFIG: tests.integration_tests.superset_test_config
@@ -135,7 +136,7 @@ jobs:
135136
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
136137
NODE_OPTIONS: "--max-old-space-size=4096"
137138
with:
138-
run: cypress-run-all ${{ env.USE_DASHBOARD }}
139+
run: cypress-run-all ${{ env.USE_DASHBOARD }} ${{ matrix.app_root }}
139140
- name: Upload Artifacts
140141
uses: actions/upload-artifact@v4
141142
if: failure()

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ RUN rm superset/translations/*/*/*.po
208208
COPY --from=superset-node /app/superset/translations superset/translations
209209
COPY --from=python-translation-compiler /app/translations_mo superset/translations
210210

211-
HEALTHCHECK CMD curl -f "http://localhost:${SUPERSET_PORT}/health"
211+
HEALTHCHECK CMD /app/docker/docker-healthcheck.sh
212212
CMD ["/app/docker/entrypoints/run-server.sh"]
213213
EXPOSE ${SUPERSET_PORT}
214214

docker-compose.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ x-superset-volumes: &superset-volumes
2929
- ./superset-frontend:/app/superset-frontend
3030
- superset_home:/app/superset_home
3131
- ./tests:/app/tests
32-
3332
x-common-build: &common-build
3433
context: .
3534
target: ${SUPERSET_BUILD_TARGET:-dev} # can use `dev` (default) or `lean`
@@ -43,6 +42,11 @@ x-common-build: &common-build
4342

4443
services:
4544
nginx:
45+
env_file:
46+
- path: docker/.env # default
47+
required: true
48+
- path: docker/.env-local # optional override
49+
required: false
4650
image: nginx:latest
4751
container_name: superset_nginx
4852
restart: unless-stopped
@@ -52,6 +56,8 @@ services:
5256
- "host.docker.internal:host-gateway"
5357
volumes:
5458
- ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
59+
- ./docker/nginx/templates:/etc/nginx/templates:ro
60+
5561
redis:
5662
image: redis:7
5763
container_name: superset_cache

docker/.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ REDIS_HOST=redis
5454
REDIS_PORT=6379
5555

5656
FLASK_DEBUG=true
57+
SUPERSET_APP_ROOT="/"
5758
SUPERSET_ENV=development
5859
SUPERSET_LOAD_EXAMPLES=yes
5960
CYPRESS_CONFIG=false

docker/docker-healthcheck.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Licensed to the Apache Software Foundation (ASF) under one or more
4+
# contributor license agreements. See the NOTICE file distributed with
5+
# this work for additional information regarding copyright ownership.
6+
# The ASF licenses this file to You under the Apache License, Version 2.0
7+
# (the "License"); you may not use this file except in compliance with
8+
# the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#
18+
19+
curl -f "http://localhost:${SUPERSET_PORT}/${SUPERSET_APP_ROOT/\//}/health" || exit 1

docker/nginx/nginx.conf

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -90,44 +90,5 @@ http {
9090

9191
client_max_body_size 10m;
9292

93-
upstream superset_app {
94-
server host.docker.internal:8088;
95-
keepalive 100;
96-
}
97-
98-
upstream superset_websocket {
99-
server host.docker.internal:8080;
100-
keepalive 100;
101-
}
102-
103-
server {
104-
listen 80 default_server;
105-
server_name _;
106-
107-
location /ws {
108-
proxy_pass http://superset_websocket;
109-
proxy_http_version 1.1;
110-
proxy_set_header Upgrade $http_upgrade;
111-
proxy_set_header Connection "Upgrade";
112-
proxy_set_header Host $host;
113-
}
114-
115-
location /static {
116-
proxy_pass http://host.docker.internal:9000; # Proxy to superset-node
117-
proxy_http_version 1.1;
118-
proxy_set_header Host $host;
119-
}
120-
121-
location / {
122-
proxy_pass http://superset_app;
123-
proxy_set_header Host $host;
124-
proxy_set_header X-Real-IP $remote_addr;
125-
proxy_set_header X-Forwarded-For $remote_addr;
126-
proxy_set_header X-Forwarded-Host $host;
127-
proxy_set_header X-Forwarded-Proto $scheme;
128-
proxy_http_version 1.1;
129-
port_in_redirect off;
130-
proxy_connect_timeout 300;
131-
}
132-
}
93+
include /etc/nginx/conf.d/superset.conf;
13394
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
upstream superset_app {
19+
server host.docker.internal:8088;
20+
keepalive 100;
21+
}
22+
23+
upstream superset_websocket {
24+
server host.docker.internal:8080;
25+
keepalive 100;
26+
}
27+
28+
server {
29+
listen 80 default_server;
30+
server_name _;
31+
32+
location /ws {
33+
proxy_pass http://superset_websocket;
34+
proxy_http_version 1.1;
35+
proxy_set_header Upgrade $http_upgrade;
36+
proxy_set_header Connection "Upgrade";
37+
proxy_set_header Host $host;
38+
}
39+
40+
location ${SUPERSET_APP_ROOT}/static {
41+
proxy_pass http://host.docker.internal:9000; # Proxy to superset-node
42+
proxy_http_version 1.1;
43+
proxy_set_header Host $host;
44+
}
45+
46+
location ${SUPERSET_APP_ROOT} {
47+
proxy_pass http://superset_app;
48+
proxy_set_header Host $http_host;
49+
proxy_set_header X-Real-IP $remote_addr;
50+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
51+
proxy_set_header X-Forwarded-Proto $scheme;
52+
proxy_http_version 1.1;
53+
port_in_redirect off;
54+
proxy_connect_timeout 300;
55+
}
56+
57+
}

docker/pythonpath_dev/superset_config.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
"CACHE_REDIS_DB": REDIS_RESULTS_DB,
7272
}
7373
DATA_CACHE_CONFIG = CACHE_CONFIG
74+
THUMBNAIL_CACHE_CONFIG = CACHE_CONFIG
7475

7576

7677
class CeleryConfig:
@@ -100,9 +101,11 @@ class CeleryConfig:
100101

101102
FEATURE_FLAGS = {"ALERT_REPORTS": True}
102103
ALERT_REPORTS_NOTIFICATION_DRY_RUN = True
103-
WEBDRIVER_BASEURL = "http://superset:8088/" # When using docker compose baseurl should be http://superset_app:8088/ # noqa: E501
104+
WEBDRIVER_BASEURL = f"http://superset_app{os.environ.get('SUPERSET_APP_ROOT', '/')}/" # When using docker compose baseurl should be http://superset_nginx{ENV{BASEPATH}}/ # noqa: E501
104105
# The base URL for the email report hyperlinks.
105-
WEBDRIVER_BASEURL_USER_FRIENDLY = WEBDRIVER_BASEURL
106+
WEBDRIVER_BASEURL_USER_FRIENDLY = (
107+
f"http://localhost:8888/{os.environ.get('SUPERSET_APP_ROOT', '/')}/"
108+
)
106109
SQLLAB_CTAS_NO_LIMIT = True
107110

108111
log_level_text = os.getenv("SUPERSET_LOG_LEVEL", "INFO")

docs/docs/configuration/configuring-superset.mdx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,45 @@ In case the reverse proxy is used for providing SSL encryption, an explicit defi
215215
RequestHeader set X-Forwarded-Proto "https"
216216
```
217217

218+
## Configuring the application root
219+
220+
*Please be advised that this feature is in BETA.*
221+
222+
Superset supports running the application under a non-root path. The root path
223+
prefix can be specified in one of two ways:
224+
225+
- Setting the `SUPERSET_APP_ROOT` environment variable to the desired prefix.
226+
- Customizing the [Flask entrypoint](https://github.com/apache/superset/blob/master/superset/app.py#L29)
227+
by passing the `superset_app_root` variable.
228+
229+
Note, the prefix should start with a `/`.
230+
231+
### Customizing the Flask entrypoint
232+
233+
To configure a prefix, e.g `/analytics`, pass the `superset_app_root` argument to
234+
`create_app` when calling flask run either through the `FLASK_APP`
235+
environment variable:
236+
237+
```sh
238+
FLASK_APP="superset:create_app(superset_app_root='/analytics')"
239+
```
240+
241+
or as part of the `--app` argument to `flask run`:
242+
243+
```sh
244+
flask --app "superset.app:create_app(superset_app_root='/analytics')"
245+
```
246+
247+
### Docker builds
248+
249+
The [docker compose](/docs/installation/docker-compose#configuring-further) developer
250+
configuration includes an additional environmental variable,
251+
[`SUPERSET_APP_ROOT`](https://github.com/apache/superset/blob/master/docker/.env),
252+
to simplify the process of setting up a non-default root path across the services.
253+
254+
In `docker/.env-local` set `SUPERSET_APP_ROOT` to the desired prefix and then bring the
255+
services up with `docker compose up --detach`.
256+
218257
## Custom OAuth2 Configuration
219258

220259
Superset is built on Flask-AppBuilder (FAB), which supports many providers out of the box

0 commit comments

Comments
 (0)