Jonas Meyer-Ohle
02/21/2025, 4:36 PMStefan Krawczyk
02/21/2025, 4:49 PMElijah Ben Izzy
02/21/2025, 4:50 PMJonas Meyer-Ohle
02/21/2025, 5:41 PMElijah Ben Izzy
02/21/2025, 5:53 PMElijah Ben Izzy
02/21/2025, 5:54 PMJonas Meyer-Ohle
02/21/2025, 11:17 PMlocation /grafana/ {
auth_request /validate-jwt; # JWT token validation
auth_request_set $auth_status $upstream_status;
proxy_pass <http://hamilton:8242>;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Session-Info $cookie_session;
proxy_set_header X-Username $cookie_username;
proxy_cache my_cache;
proxy_cache_valid any 10m;
error_page 401 /custom401.html;
}
With hamilton being the name of the container. Will have to give your nginx a try but if I understand it correctly, this doesn't actually setup a subpath?Jonas Meyer-Ohle
02/21/2025, 11:19 PMStefan Krawczyk
02/22/2025, 6:37 AMwww.somedomain.com/some_path/
and so you want all URLs in the Hamilton UI to be pre-pended with /some_path/ ?
(note I spot location /grafana/ in your snippet above in case that’s an error) — and have a good weekend!Jonas Meyer-Ohle
02/24/2025, 1:58 PMserver {
listen 443 ssl;
server_name <http://domain.com|domain.com>;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
error_page 502 /custom502.html;
error_page 504 /custom504.html;
error_page 401 /custom401.html;
location = /custom502.html {
root /opt/bitnami/nginx/html;
internal;
}
location = /custom504.html {
root /opt/bitnami/nginx/html;
internal;
}
location = /custom401.html {
root /opt/bitnami/nginx/html;
internal;
}
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
proxy_set_header X-Session-Info $cookie_session;
proxy_set_header X-Username $cookie_username;
proxy_pass <http://host.docker.internal:8080>;
proxy_read_timeout 864000;
proxy_cache my_cache;
proxy_cache_revalidate on;
proxy_cache_min_uses 3;
proxy_cache_use_stale error timeout updating http_500 http_502
http_503 http_504;
proxy_cache_background_update on;
proxy_cache_lock on;
}
location /grafana/ {
auth_request /validate-jwt; # JWT token validation
auth_request_set $auth_status $upstream_status;
proxy_pass <http://grafana:3000>;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Session-Info $cookie_session;
proxy_set_header X-Username $cookie_username;
proxy_cache my_cache;
proxy_cache_valid any 10m;
error_page 401 /custom401.html;
}
location /hamilton/ {
auth_request /validate-jwt; # JWT token validation
auth_request_set $auth_status $upstream_status;
proxy_pass <http://hamilton-ui-frontend:8242>;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Session-Info $cookie_session;
proxy_set_header X-Username $cookie_username;
proxy_cache my_cache;
proxy_cache_valid any 10m;
error_page 401 /custom401.html;
}
# JWT validation block
location = /validate-jwt {
internal;
proxy_pass <https://authentication:9876/auth>;
proxy_set_header Host $host;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_cache_valid 200 10m;
proxy_set_header X-Session-Info $cookie_session;
proxy_set_header X-Username $cookie_username;
}
The docker file looks as such:
hamilton-ui-frontend:
<<: *default-logging
container_name: hamilton-ui-frontend
image: tnpatlas/hamilton-ui-frontend:latest
ports:
- "8242:8242"
networks:
- app-network
environment:
- NGINX_PORT=8242 # NB Custom port won't be visible in console & will mean the backend's shortcut will fail
- NODE_ENV=development
- REACT_APP_AUTH_MODE=local
- REACT_APP_USE_POSTHOG=false
- REACT_APP_API_URL=<http://hamilton-ui-backend:8241>
depends_on:
hamilton-ui-backend:
condition: service_started
grafana:
container_name: grafana
image: grafana/grafana:latest
ports:
- "3000:3000"
volumes:
- grafana-storage:/var/lib/grafana
- ./lgtm/grafana-datasources.yml:/etc/grafana/provisioning/datasources/grafana-datasources.yml
environment:
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
- GF_AUTH_ANONYMOUS_ENABLED=true
- GF_AUTH_BASIC_ENABLED=false
- GF_SECURITY_ALLOW_EMBEDDING=true
- GF_SERVER_ROOT_URL=%(protocol)s://%(domain)s/grafana
- GF_SERVER_SERVE_FROM_SUB_PATH=true
domain.com/grafana works but domain.com/hamilton has the following error:
GET <https://domain.com/static/css/main.5f18e71d.css> net::ERR_ABORTED 404 (NOT FOUND)
GET <https://domain.com/static/js/main.a45999b9.js> net::ERR_ABORTED 404 (NOT FOUND)Jonas Meyer-Ohle
02/24/2025, 1:59 PMStefan Krawczyk
02/24/2025, 7:35 PM/hamilton/ then I think we need to rebuild the container & expose an option for this.
Will try get you some pointers on how to do this today / tomorrow. @Elijah Ben Izzy might be able to point to where in the frontend code we need to set this - which if you test out we could then fold back into Hamilton with your help.Elijah Ben Izzy
02/24/2025, 7:36 PMJonas Meyer-Ohle
02/25/2025, 10:28 AMJonas Meyer-Ohle
02/26/2025, 2:39 PMimport { BrowserRouter, Route } from 'react-router-dom';
// Then in render
<BrowserRouter basename='/path/to/subfolder/'>
<Route path='/' component={ Home } exact />
<Route path='/about' component={ About } exact />
{/*...*/}
</BrowserRouter>
And then exposing a basename variable that can be set in docker etc.Elijah Ben Izzy
02/26/2025, 4:46 PM/path/to/subfolder to /hamilton/ — then can make it a config variableElijah Ben Izzy
02/26/2025, 4:46 PMJonas Meyer-Ohle
02/26/2025, 5:00 PMElijah Ben Izzy
02/26/2025, 5:00 PMJonas Meyer-Ohle
02/27/2025, 12:04 PMElijah Ben Izzy
02/27/2025, 3:56 PMElijah Ben Izzy
02/27/2025, 3:56 PM