Skip to content
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

Add configuration to serve public routes from a different base url path #2704

5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion assets/js/hooks/js_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 ||
Expand Down
5 changes: 5 additions & 0 deletions lib/livebook.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 11 additions & 0 deletions lib/livebook/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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.
"""
Expand Down
33 changes: 31 additions & 2 deletions lib/livebook_web.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
1 change: 1 addition & 0 deletions lib/livebook_web/components/layouts/root.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<link phx-track-static rel="stylesheet" href={~p"/assets/app.css"} />
<script>
window.LIVEBOOK_BASE_URL_PATH = "<%= Livebook.Config.base_url_path() %>";
window.LIVEBOOK_PUBLIC_BASE_URL_PATH = "<%= Livebook.Config.public_base_url_path() %>"
</script>
<LivebookWeb.LayoutComponents.dev_script />
<%!-- This prevents the script to be loaded twice in Chrome --%>
Expand Down
Loading