Metabase Custom URL

Hi,

I have a quick question. when setting up the custom URL, is it possible to add Metabase on a subdomain like this form https://analytics.example.com.zm/metabase/ or it required to be https://metabase.example.com.zm. Kindly note that the latter was my setup and everything worked well, I have since changed to the former and the dashboards are not loading.

Hi @asimumba
Yes, it’s possible to run Metabase in a sub-directory via a reverse-proxy.
Make sure you set the Admin > Settings > General > Site URL.
Though, there are some known issues:
https://github.com/metabase/metabase/issues/13602 - upvote by clicking :+1: on the first post

1 Like

@flamber thanks. Initially, this worked. But I am having now challenges to set-up the nginx server. When I try to access Metabase via localhost:3000 I am being redirected to the URL I have set-up https://analytics.example.com.zm/. My first suspicion is the URL I had set-up in the admin panel. Now that I can access Metabase, makes it impossible to check the base URL. Would you know an alternative to access Metabase? or I have to deal with nginx server first?

@asimumba Open you application database - look in the table setting for the key site-url and change that to the actual URL you’re using when visiting Metabase (so not localhost:3000).
I cannot help more, when you don’t post the configurations or the actual URL, so I can only give you hints - you have to figure out the rest.

1 Like

@flamber I have taken a look at the Metabase application database, I have noticed the site-url value is some sort of a cryptic value. In this case, do I replace it with a human-readable URL I am using to access Metabase?

For your information, I cannot provide the configurations as I am unable to access Metabase even by using localhost:3000. When I do so, I am redirected to the URL I had entered under settings as the site URL. I remember to have also set it to https redirects.

@asimumba
If you have enabled encryption, then that’s why the setting is “a cryptic value”.
You can replace the value with a clear string - make sure you backup before changing application database manually, since you can end up with a corrupted state.
I don’t know how or where you’re running Metabase, or if you’re using reverse-proxy, so it’s not possible to give any hints on what to do.
Read this: https://github.com/metabase/metabase/issues/13084

@flamber Yes, I am using Nginx and running it as a service on an Ubuntu Linux server. I will try you recommendations as revert with the status.

@flamber I am making some progress, now I can visit the URL after manually updating the site-url to my URL (https://data.example.com.zm/metabase/) and the redirect-all-requests-to-https=false in the application database. I have this error log when I visit the above URL. Any hits on what may be wrong from my end?

{"via":[{"type":"com.fasterxml.jackson.core.JsonParseException","message":"Unexpected character ('d' (code 100)): Expected space separating root-level values\n at [Source: (StringReader); line: 1, column: 3]","at":["com.fasterxml.jackson.core.JsonParser","_constructError","JsonParser.java",1804]}],"trace":[["com.fasterxml.jackson.core.JsonParser","_constructError","JsonParser.java",1804],["com.fasterxml.jackson.core.base.ParserMinimalBase","_reportError","ParserMinimalBase.java",669],["com.fasterxml.jackson.core.base.ParserMinimalBase","_reportUnexpectedChar","ParserMinimalBase.java",567],["com.fasterxml.jackson.core.base.ParserMinimalBase","_reportMissingRootWS","ParserMinimalBase.java",614],["com.fasterxml.jackson.core.json.ReaderBasedJsonParser","_verifyRootSpace","ReaderBasedJsonParser.java",1654],["com.fasterxml.jackson.core.json.ReaderBasedJsonParser","_parsePosNumber","ReaderBasedJsonParser.java",1297],["com.fasterxml.jackson.core.json.ReaderBasedJsonParser","nextToken","ReaderBasedJsonParser.java",744],["cheshire.parse$parse","invokeStatic","parse.clj",88],["cheshire.parse$parse","invoke","parse.clj",86],["cheshire.core$parse_string","invokeStatic","core.clj",206],["cheshire.core$parse_string","invoke","core.clj",192],["cheshire.core$parse_string","invokeStatic","core.clj",203],["cheshire.core$parse_string","invoke","core.clj",192],["metabase.models.setting$get_json","invokeStatic","setting.clj",227],["metabase.models.setting$get_json","invoke","setting.clj",224],["clojure.core$partial$fn__5839","invoke","core.clj",2623],["metabase.models.setting$get","invokeStatic","setting.clj",256],["metabase.models.setting$get","invoke","setting.clj",248],["metabase.models.setting$properties$fn__22307","invoke","setting.clj",674],["clojure.core$map$fn__5866","invoke","core.clj",2755],["clojure.lang.LazySeq","sval","LazySeq.java",42],["clojure.lang.LazySeq","seq","LazySeq.java",51],["clojure.lang.Cons","next","Cons.java",39],["clojure.lang.RT","next","RT.java",713],["clojure.core$next__5386","invokeStatic","core.clj",64],["clojure.core.protocols$fn__8159","invokeStatic","protocols.clj",169],["clojure.core.protocols$fn__8159","invoke","protocols.clj",124],["clojure.core.protocols$fn__8114$G__8109__8123","invoke","protocols.clj",19],["clojure.core.protocols$seq_reduce","invokeStatic","protocols.clj",31],["clojure.core.protocols$fn__8146","invokeStatic","protocols.clj",75],["clojure.core.protocols$fn__8146","invoke","protocols.clj",75],["clojure.core.protocols$fn__8088$G__8083__8101","invoke","protocols.clj",13],["clojure.core$reduce","invokeStatic","core.clj",6828],["clojure.core$into","invokeStatic","core.clj",6895],["clojure.core$into","invoke","core.clj",6887],["metabase.models.setting$properties","invokeStatic","setting.clj",675],["metabase.models.setting$properties","invoke","setting.clj",668],["metabase.routes.index$load_entrypoint_template","invokeStatic","index.clj",77],["metabase.routes.index$load_entrypoint_template","invoke","index.clj",74],["metabase.routes.index$entrypoint","invokeStatic","index.clj",98],["metabase.routes.index$entrypoint","invoke","index.clj",93],["clojure.core$partial$fn__5841","invoke","core.clj",2633],["compojure.response$fn__377","invokeStatic","response.clj",70],["compojure.response$fn__377","invoke","response.clj",67],["compojure.response$fn__335$G__330__346","invoke","response.clj",17],["compojure.response$send","invokeStatic","response.clj",27],["compojure.response$send","invoke","response.clj",22],["compojure.core$wrap_response$fn__1993","invoke","core.clj",160],["compojure.core$wrap_route_middleware$fn__1977","invoke","core.clj",132],["compojure.core$wrap_route_info$fn__1982","invoke","core.clj",139],["compojure.core$wrap_route_matches$fn__1986","invoke","core.clj",151],["compojure.core$routes$fn__2005$f__2006","invoke","core.clj",198],["compojure.core$routes$fn__2005","invoke","core.clj",200],["metabase.middleware.exceptions$catch_uncaught_exceptions$fn__68555","invoke","exceptions.clj",96],["metabase.middleware.exceptions$catch_api_exceptions$fn__68552","invoke","exceptions.clj",84],["metabase.middleware.log$log_api_call$fn__70433","invoke","log.clj",189],["metabase.middleware.security$add_security_headers$fn__68518","invoke","security.clj",121],["metabase.middleware.json$wrap_json_body$fn__70136","invoke","json.clj",66],["metabase.middleware.json$wrap_streamed_json_response$fn__70154","invoke","json.clj",100],["ring.middleware.keyword_params$wrap_keyword_params$fn__70734","invoke","keyword_params.clj",55],["ring.middleware.params$wrap_params$fn__70750","invoke","params.clj",69],["metabase.middleware.misc$maybe_set_site_url$fn__70464","invoke","misc.clj",59],["metabase.middleware.session$bind_current_user$fn__65014$fn__65015","invoke","session.clj",204],["metabase.middleware.session$do_with_current_user","invokeStatic","session.clj",186],["metabase.middleware.session$do_with_current_user","invoke","session.clj",178],["metabase.middleware.session$bind_current_user$fn__65014","invoke","session.clj",203],["metabase.middleware.session$wrap_current_user_info$fn__65001","invoke","session.clj",169],["metabase.middleware.session$wrap_session_id$fn__64989","invoke","session.clj",127],["metabase.middleware.auth$wrap_api_key$fn__68460","invoke","auth.clj",27],["ring.middleware.cookies$wrap_cookies$fn__70654","invoke","cookies.clj",216],["metabase.middleware.misc$add_content_type$fn__70449","invoke","misc.clj",28],["metabase.middleware.misc$disable_streaming_buffering$fn__70472","invoke","misc.clj",76],["ring.middleware.gzip$wrap_gzip$fn__70696","invoke","gzip.clj",86],["metabase.middleware.ssl$redirect_to_https_middleware$fn__70485","invoke","ssl.clj",49],["metabase.server$async_proxy_handler$fn__70211","invoke","server.clj",72],["metabase.server.proxy$org.eclipse.jetty.server.handler.AbstractHandler$ff19274a","handle",null,-1],["org.eclipse.jetty.server.handler.HandlerWrapper","handle","HandlerWrapper.java",127],["org.eclipse.jetty.server.Server","handle","Server.java",500],["org.eclipse.jetty.server.HttpChannel","lambda$handle$1","HttpChannel.java",383],["org.eclipse.jetty.server.HttpChannel","dispatch","HttpChannel.java",547],["org.eclipse.jetty.server.HttpChannel","handle","HttpChannel.java",375],["org.eclipse.jetty.server.HttpConnection","onFillable","HttpConnection.java",273],["org.eclipse.jetty.io.AbstractConnection$ReadCallback","succeeded","AbstractConnection.java",311],["org.eclipse.jetty.io.FillInterest","fillable","FillInterest.java",103],["org.eclipse.jetty.io.ChannelEndPoint$2","run","ChannelEndPoint.java",117],["org.eclipse.jetty.util.thread.strategy.EatWhatYouKill","runTask","EatWhatYouKill.java",336],["org.eclipse.jetty.util.thread.strategy.EatWhatYouKill","doProduce","EatWhatYouKill.java",313],["org.eclipse.jetty.util.thread.strategy.EatWhatYouKill","tryProduce","EatWhatYouKill.java",171],["org.eclipse.jetty.util.thread.strategy.EatWhatYouKill","run","EatWhatYouKill.java",129],["org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread","run","ReservedThreadExecutor.java",375],["org.eclipse.jetty.util.thread.QueuedThreadPool","runJob","QueuedThreadPool.java",806],["org.eclipse.jetty.util.thread.QueuedThreadPool$Runner","run","QueuedThreadPool.java",938],["java.lang.Thread","run","Thread.java",834]],"cause":"Unexpected character ('d' (code 100)): Expected space separating root-level values\n at [Source: (StringReader); line: 1, column: 3]","message":"Unexpected character ('d' (code 100)): Expected space separating root-level values\n at [Source: (StringReader); line: 1, column: 3]","type":"class com.fasterxml.jackson.core.JsonParseException"}

@asimumba That is because the values aren’t encrypted. If you go to the Admin > Settings > General, then it should update the Site URL, but it’s a little more tricky with the redirect, since you cannot turn the setting on, so you would need to make an API request to try to make it write the value again, which would add encryption.

1 Like

@flamber I cannot thank you enough for your patience and guidance. I feel I have learnt quite a lot. I have updated the MB_ENCRYPTION_SECRET_KEY with the encryption key, and I am now able to load Metabase after countless hours trying to redeem my production environment. In case of anything, I will let you know. For now, I will try to complete what I had envisioned to accomplish with my setup.

@asimumba Excellent you got it working. For anyone else viewing this topic, this is one of the main reasons we have created the Metabase Cloud option, so hosting and operations are handled by us:
https://www.metabase.com/start/hosted/

1 Like

@asimumba i am also facing the similar issue, i have updated the site_url in settings.
Can you share the nginx config that you used to get it work. value in application database is also correct.

Hi @rahul_kumar, help me with the issue. Are you locked out of your Metabase instance or it's the redirect issue you're faced with?

@asimumba , i am locked out actually. I have a similar setup, nginx is pointing to original deployment and i already have set the site-url in env. When i go to base path "https://base-url/metabase", i get a blank white page.


as you can see in browser network. files are being called twice. First call goes to "https://base-url/metabase/app/..." but second call goes to "https://base-url/app/..."

Kindly follow this comment Metabase Custom URL - #4 by flamber. Back up your metabase DB first before you can make changes to it. For my case, I used Dbeaver to edit the table setting for the key site-ur.

I will share my nginx set-up once I get access to my env.

your problem is that you're using Metabase in a sub domain. Check out the posts to run metabase in a sub domain or follow this demo GitHub - paoliniluis/metabase-subpath: Metabase running on a subpath rather than on the root path