persist mockup variants on fly volume across deploys
All checks were successful
deploy / deploy (push) Successful in 3m46s

Source mockup WebPs are copied from the release to /data/mockups/
on startup, and variants are generated there. This eliminates the
182-job storm on every deploy that was saturating the CPU and
causing SQLite locking. After the first successful run, subsequent
deploys find all variants intact.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
jamey
2026-03-02 11:20:33 +00:00
parent 8159a312ae
commit 5e70c07b60
4 changed files with 36 additions and 5 deletions

View File

@@ -19,7 +19,13 @@ defmodule Berrypod.Images.VariantCache do
alias Berrypod.Sync.ImageDownloadWorker
import Ecto.Query
defp mockup_dir, do: Application.app_dir(:berrypod, "priv/static/mockups")
# Source mockups bundled in the release
defp release_mockup_dir, do: Application.app_dir(:berrypod, "priv/static/mockups")
# Where mockup variants live — persistent volume in prod, release dir in dev
defp mockup_dir do
Application.get_env(:berrypod, :mockup_dir) || release_mockup_dir()
end
def start_link(opts) do
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
@@ -84,9 +90,25 @@ defmodule Berrypod.Images.VariantCache do
end
defp ensure_mockup_variants do
if File.dir?(mockup_dir()) do
output = mockup_dir()
release = release_mockup_dir()
# When using a persistent volume, copy source WebPs from the release
# so variants can be generated there (and survive deploys).
if output != release and File.dir?(release) do
File.mkdir_p!(output)
Path.wildcard(Path.join(release, "*.webp"))
|> Enum.reject(&is_variant?/1)
|> Enum.each(fn src ->
dest = Path.join(output, Path.basename(src))
unless File.exists?(dest), do: File.cp!(src, dest)
end)
end
if File.dir?(output) do
sources =
Path.wildcard(Path.join(mockup_dir(), "*.webp"))
Path.wildcard(Path.join(output, "*.webp"))
|> Enum.reject(&is_variant?/1)
missing = Enum.reject(sources, &mockup_variants_exist?/1)