fix: resolve storage healthcheck path via LOCAL_STORAGE_PATH env var (#3004)

* fix: resolve local data directory to /app/data in production Docker

In the official Docker image, cwd is /app/apps/web (set via WORKDIR), but
the data volume is mounted at /app/data. Without pnpm-workspace.yaml present
in the runtime image, findWorkspaceRoot() returns null, so getLocalDataDirectory()
fell back to <cwd>/data = /app/apps/web/data, which the node user has no
permission to create. This caused the storage healthcheck to fail with
EACCES.

Add a production fallback: when cwd ends in apps/web, resolve the data
directory to two levels up (matching /app/data in the official image).

Re-resolves #2990.

https://claude.ai/code/session_015pSTtukxf7mFTty2Y6PHZf

* fix: replace apps/web heuristic with LOCAL_STORAGE_PATH env var

The previous fix special-cased a cwd ending in apps/web to land on /app/data,
but the heuristic could false-positive on any path with that suffix and was
fragile to Dockerfile changes. pnpm-workspace.yaml is never copied into the
runtime image, so the workspace-root walk was also dead code in production.

Replace the heuristic with an explicit LOCAL_STORAGE_PATH env var:
- Set LOCAL_STORAGE_PATH=/app/data in the Dockerfile (single source of truth).
- Add LOCAL_STORAGE_PATH to the env schema; storage and statistics services
  pass it through to getLocalDataDirectory.
- getLocalDataDirectory now uses the override when set, else workspace root
  (dev), else cwd/data.
- New Nitro plugin validates the resolved local data directory at startup
  and refuses to boot with a clear error if it isn't writable, surfacing
  permission issues immediately instead of at first upload/healthcheck.
- Document the new variable in .env.example and the Docker self-hosting docs.

https://claude.ai/code/session_015pSTtukxf7mFTty2Y6PHZf

* fix: address review feedback on storage path handling

- apps/web/plugins/2.storage.ts: use the default-import style for
  node:fs/promises (matches the rest of the repo, sidesteps any
  named-export concerns for fs.constants).
- packages/env/src/server.ts: reject relative LOCAL_STORAGE_PATH values
  via a zod refinement. Relative paths would be resolved against cwd,
  which differs between dev and Docker — exactly the same surprise the
  original bug had. Failing fast at config validation time gives a
  clear error before the server boots.

https://claude.ai/code/session_015pSTtukxf7mFTty2Y6PHZf

* fix: update data volume configuration in Docker Compose and enhance Nitro plugin

* fix: remove "Can I customize the templates?" FAQ entry from multiple language files

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Amruth Pillai
2026-05-08 16:05:47 +02:00
committed by GitHub
co-authored by Claude
parent 05f094bd13
commit bdfb854602
65 changed files with 40 additions and 502 deletions
-9
View File
@@ -462,10 +462,6 @@ msgstr "Lista com marcadores"
msgid "By the community, for the community."
msgstr "Pela comunidade, para a comunidade."
#: src/routes/_home/-sections/faq.tsx
msgid "Can I customize the templates?"
msgstr "Posso personalizar os modelos?"
#: src/routes/_home/-sections/faq.tsx
msgid "Can I export my resume to PDF?"
msgstr "Posso exportar o meu currículo para PDF?"
@@ -3385,10 +3381,6 @@ msgstr "X (Twitter)"
msgid "Yes, Reactive Resume is available in multiple languages. You can choose your preferred language in the settings page, or using the language switcher in the top right corner. If you don't see your language, or you would like to improve the existing translations, you can <0>contribute to the translations on Crowdin<1> (opens in new tab)</1></0>."
msgstr "Sim, o Reactive Resume está disponível em vários idiomas. Pode escolher o seu idioma preferido na página de configurações ou utilizando o seletor de idioma no canto superior direito. Se não vir o seu idioma ou quiser melhorar as traduções existentes, pode <0>contribuir para as traduções no Crowdin<1> (abre num novo separador)</1></0>."
#: src/routes/_home/-sections/faq.tsx
msgid "Yes! Every template is fully customizable. You can change colors, fonts, spacing, and even write custom CSS for complete control over your resume's appearance."
msgstr "Sim! Todos os modelos são totalmente personalizáveis. Pode alterar cores, fontes, espaçamento e até escrever CSS personalizado para ter controlo total sobre a aparência do seu currículo."
#: src/routes/_home/-sections/faq.tsx
msgid "Yes! Reactive Resume is completely free to use, with no hidden costs, premium tiers, or subscription fees. It's open-source and will always remain free."
msgstr "Sim! O Reactive Resume é completamente gratuito, sem custos ocultos, níveis premium ou taxas de subscrição. É de código aberto e permanecerá sempre gratuito."
@@ -3495,4 +3487,3 @@ msgstr "Afastar"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"