Skip to content

Commit

Permalink
Add configuration to serve public routes from a different base url pa…
Browse files Browse the repository at this point in the history
…th (#2704)

Co-authored-by: Jonatan Kłosko <[email protected]>
  • Loading branch information
elepedus and jonatanklosko authored Jul 17, 2024
1 parent d4f9289 commit d4201c6
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 3 deletions.
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

0 comments on commit d4201c6

Please sign in to comment.