diff --git a/config/prod.exs b/config/prod.exs index 050640b..9c2f673 100644 --- a/config/prod.exs +++ b/config/prod.exs @@ -19,5 +19,8 @@ config :logger, level: :info # Structured JSON logs for production (machine-parseable by fly logs, journalctl, Loki, etc.) config :logger, :default_handler, formatter: {LoggerJSON.Formatters.Basic, []} +# Persistent image cache on the Fly volume (survives deploys) +config :berrypod, :image_cache_dir, "/data/image_cache" + # Runtime production configuration, including reading # of environment variables, is done on config/runtime.exs. diff --git a/lib/berrypod_web/endpoint.ex b/lib/berrypod_web/endpoint.ex index bbf97c0..4f5199d 100644 --- a/lib/berrypod_web/endpoint.ex +++ b/lib/berrypod_web/endpoint.ex @@ -16,6 +16,15 @@ defmodule BerrypodWeb.Endpoint do websocket: [connect_info: [session: @session_options]], longpoll: [connect_info: [session: @session_options]] + # In prod, image variants live on the persistent volume (/data/image_cache) + # rather than inside the ephemeral release directory. + if image_cache_dir = Application.compile_env(:berrypod, :image_cache_dir) do + plug Plug.Static, + at: "/image_cache", + from: image_cache_dir, + cache_control_for_etags: "public, max-age=31536000, immutable" + end + # Serve at "/" the static files from "priv/static" directory. # gzip only in prod — avoids stale .gz files from mix assets.deploy # shadowing freshly-built dev assets. diff --git a/lib/berrypod_web/plugs/broken_url_tracker.ex b/lib/berrypod_web/plugs/broken_url_tracker.ex index 978015c..ae65b97 100644 --- a/lib/berrypod_web/plugs/broken_url_tracker.ex +++ b/lib/berrypod_web/plugs/broken_url_tracker.ex @@ -34,6 +34,7 @@ defmodule BerrypodWeb.Plugs.BrokenUrlTracker do defp static_path?(path) do String.starts_with?(path, "/assets/") or String.starts_with?(path, "/images/") or + String.starts_with?(path, "/image_cache/") or String.starts_with?(path, "/favicon") end end