The app reads its Base44 app id and backend URL from VITE_BASE44_APP_ID and VITE_BASE44_BACKEND_URL, but neither was set anywhere, so Vite compiled both defaults to undefined and app-params resolved them to null at runtime. On base44's own host these arrive as query params; on a custom domain they never do. A null serverUrl skipped the SDK's default (it only applies to undefined), making every API baseURL relative — requests hit our own nginx, which answered with index.html, and the app rendered against HTML and died. Deploys reported success while serving an empty page. appBaseUrl was never passed either, so login/logout redirects were relative too and bounced between /login and the SPA fallback. redirectToLogin also omits app_id, which base44.app/login 404s on when the request comes from our domain rather than a *.base44.app one, so login now goes through loginWithProvider. Set both vars as build args in the Dockerfile — they must be present at build time, since runtime env vars in Dokploy arrive after Vite has already inlined them. Guard the build against an empty app id and a missing dist/index.html. Surface failures instead of hiding them: an ErrorBoundary around the tree, and a diagnostic panel for auth errors that previously fell through to a crash. In nginx, serve a real 404 for missing /assets/ files. Falling through to the SPA rule returned index.html as text/html, which the browser refuses to run as a module — another silent blank page. Also add /health and stop the SPA fallback from being cached under the requested path. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
59 lines
2.4 KiB
Docker
59 lines
2.4 KiB
Docker
# ---- Build stage ----
|
|
FROM node:22-alpine AS build
|
|
|
|
WORKDIR /app
|
|
|
|
# Safety valve for the 2 GB host: without a cap a runaway build can exhaust the
|
|
# server's RAM and take down neighbouring containers. Measured peak for this app
|
|
# is ~550 MB, so 1 GB leaves headroom while still failing the build rather than
|
|
# the server. Raise this only if the host gets more RAM.
|
|
ENV NODE_OPTIONS=--max-old-space-size=1024
|
|
|
|
# Vite inlines VITE_* vars into the bundle at build time, so these have to be
|
|
# present here — setting them as runtime env vars in Dokploy does nothing, the
|
|
# JS is already compiled by then. .env.* is gitignored, so a build from the repo
|
|
# has no other source for them: without these the app boots with a null app id,
|
|
# every API call resolves against our own origin, nginx answers with index.html
|
|
# and the browser shows a blank page. Defaults match this app so a plain
|
|
# `docker build` works; override via Dokploy's build args to point elsewhere.
|
|
ARG VITE_BASE44_APP_ID=68fc6cf01386035c266e7a5d
|
|
ARG VITE_BASE44_BACKEND_URL=https://base44.app
|
|
ENV VITE_BASE44_APP_ID=$VITE_BASE44_APP_ID
|
|
ENV VITE_BASE44_BACKEND_URL=$VITE_BASE44_BACKEND_URL
|
|
|
|
# Install deps from the lockfile first so this layer is reused when only src changes
|
|
COPY package.json package-lock.json ./
|
|
RUN npm ci --no-audit --no-fund
|
|
|
|
COPY . .
|
|
|
|
# Fail loudly here rather than shipping an image that serves an empty page.
|
|
RUN test -n "$VITE_BASE44_APP_ID" || (echo "VITE_BASE44_APP_ID is empty — the build would produce a blank app" && exit 1)
|
|
RUN npm run build
|
|
|
|
# The build is only useful if it actually emitted an entry point.
|
|
RUN test -f dist/index.html || (echo "vite build produced no dist/index.html" && exit 1)
|
|
|
|
# ---- Runtime stage ----
|
|
FROM nginx:alpine
|
|
|
|
# Remove Nginx's default "Welcome" page files completely
|
|
RUN rm -rf /usr/share/nginx/html/*
|
|
|
|
# Only the compiled assets reach the final image — no node_modules, no source
|
|
COPY --from=build /app/dist /usr/share/nginx/html
|
|
|
|
COPY nginx.conf /etc/nginx/nginx.conf
|
|
|
|
# Catch a broken config at build time instead of at container start, where
|
|
# Dokploy would report the deploy as successful and then serve nothing.
|
|
RUN nginx -t
|
|
|
|
EXPOSE 80 3000
|
|
|
|
# Gives Dokploy a real signal that the container is serving, not just running.
|
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
|
CMD wget -q --spider http://127.0.0.1/health || exit 1
|
|
|
|
CMD ["nginx", "-g", "daemon off;"]
|