diff --git a/README.md b/README.md
index e6ebdd74e71..82fb881371e 100644
--- a/README.md
+++ b/README.md
@@ -196,6 +196,11 @@ The following environment variables can be used to configure Livebook on boot:
* `LIVEBOOK_BASE_URL_PATH` - sets the base url path the web application is
served on. Useful when deploying behind a reverse proxy.
+ * `LIVEBOOK_PUBLIC_BASE_URL_PATH` - sets the base url path the `/public/*` routes
+ are served on. Note that this takes precedence over `LIVEBOOK_BASE_URL_PATH`,
+ if both are set. Setting this may be useful to create exceptions when deploying
+ behind a reverse proxy that requires au1thentication.
+
* `LIVEBOOK_CACERTFILE` - path to a local file containing CA certificates.
Those certificates are used during for server authentication when Livebook
accesses files from external sources.
diff --git a/assets/js/hooks/js_view.js b/assets/js/hooks/js_view.js
index 8ffec257e71..767314d6a9f 100644
--- a/assets/js/hooks/js_view.js
+++ b/assets/js/hooks/js_view.js
@@ -507,7 +507,7 @@ const JSView = {
* once and the response is cached.
*/
function cachedPublicEndpointCheck() {
- const healthUrl = window.LIVEBOOK_BASE_URL_PATH + "/public/health";
+ const healthUrl = window.LIVEBOOK_PUBLIC_BASE_URL_PATH + "/public/health";
cachedPublicEndpointCheck.promise =
cachedPublicEndpointCheck.promise ||
diff --git a/lib/livebook.ex b/lib/livebook.ex
index 9b8639df050..5455ce503d0 100644
--- a/lib/livebook.ex
+++ b/lib/livebook.ex
@@ -114,6 +114,11 @@ defmodule Livebook do
config :livebook, LivebookWeb.Endpoint, url: [path: base_url_path]
end
+ if public_base_url_path =
+ Livebook.Config.base_url_path!("LIVEBOOK_PUBLIC_BASE_URL_PATH") do
+ config :livebook, :public_base_url_path, public_base_url_path
+ end
+
if password = Livebook.Config.password!("LIVEBOOK_PASSWORD") do
config :livebook, :authentication, {:password, password}
else
diff --git a/lib/livebook/config.ex b/lib/livebook/config.ex
index 036db32bb1a..616790fdf2d 100644
--- a/lib/livebook/config.ex
+++ b/lib/livebook/config.ex
@@ -226,6 +226,17 @@ defmodule Livebook.Config do
String.trim_trailing(path, "/")
end
+ @doc """
+ Returns the base url path for Livebook public endpoints (health & assets)
+ """
+ @spec public_base_url_path() :: String.t()
+ def public_base_url_path() do
+ case Application.get_env(:livebook, :public_base_url_path) do
+ nil -> base_url_path()
+ path -> String.trim_trailing(path, "/")
+ end
+ end
+
@doc """
Returns the configured port for the iframe endpoint.
"""
diff --git a/lib/livebook_web.ex b/lib/livebook_web.ex
index 81df01cb9b4..7acaebde360 100644
--- a/lib/livebook_web.ex
+++ b/lib/livebook_web.ex
@@ -78,8 +78,10 @@ defmodule LivebookWeb do
statics: LivebookWeb.static_paths()
# We don't know the hostname Livebook runs on, so we don't use
- # absolute URL helpers
- import Phoenix.VerifiedRoutes, only: :sigils
+ # absolute URL helpers. We don't import sigil_p either, because
+ # we override it.
+ import Phoenix.VerifiedRoutes, only: []
+ import LivebookWeb, only: [sigil_p: 2]
end
end
@@ -89,4 +91,31 @@ defmodule LivebookWeb do
defmacro __using__(which) when is_atom(which) do
apply(__MODULE__, which, [])
end
+
+ # Overrides
+ require Phoenix.VerifiedRoutes
+
+ defmacro sigil_p({:<<>>, _meta, ["/public/" <> _ | _]} = route, extra) do
+ # We allow configuring a base path for all routes and we configure
+ # Phoenix to use it. However, we have an additional configuration
+ # for base path applying only to /public. We use a custom sigil_p
+ # to insert this base path if needed.
+ quote do
+ path = Phoenix.VerifiedRoutes.sigil_p(unquote(route), unquote(extra))
+ LivebookWeb.__rewrite_public_base_path__(path)
+ end
+ end
+
+ defmacro sigil_p(route, extra) do
+ quote do
+ Phoenix.VerifiedRoutes.sigil_p(unquote(route), unquote(extra))
+ end
+ end
+
+ def __rewrite_public_base_path__(path) do
+ base_url_path = Livebook.Config.base_url_path()
+ public_base_url_path = Livebook.Config.public_base_url_path()
+ ^base_url_path <> rest = path
+ public_base_url_path <> rest
+ end
end
diff --git a/lib/livebook_web/components/layouts/root.html.heex b/lib/livebook_web/components/layouts/root.html.heex
index e5adf0c390b..9d155ec79f8 100644
--- a/lib/livebook_web/components/layouts/root.html.heex
+++ b/lib/livebook_web/components/layouts/root.html.heex
@@ -13,6 +13,7 @@
<%!-- This prevents the script to be loaded twice in Chrome --%>