Files
AgendaPro/Dockerfile
AgendaPro DevandClaude Opus 5 4f566ddde7 fix: quitar el VOLUME anónimo que borraba la base en cada despliegue
`VOLUME /app/data` hacía que Docker fabricara un volumen anónimo en cada arranque,
y Coolify los purga al recrear el contenedor. Cada despliegue estrenaba una base
vacía que `ensureSeed()` volvía a sembrar: se perdían las citas, los clientes y
todo lo configurado desde Ajustes, en silencio y sin error.

Verificado en el host: el volumen montado era 991d42df… y el día anterior era
3cff8c0d…, y no queda ningún volumen huérfano con agendapro.db — los anteriores
fueron destruidos. La base se creaba un minuto después del contenedor.

La persistencia la aporta ahora un volumen con nombre declarado como Persistent
Storage en Coolify y montado en /app/data, precargado con un snapshot consistente
de la base actual (155 citas, 15 clientes, 8 usuarios, integrity_check ok).

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-29 00:33:11 -06:00

62 lines
2.4 KiB
Docker

# ---- Build frontend ----
FROM node:22-slim AS web-build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
# El login mágico y el "Ver como…" del panel viven detrás de la constante de build
# `DEMO` (`import.meta.env.DEV || import.meta.env.VITE_DEMO_UI === "1"`, ver
# src/pages/LoginPage.tsx, src/components/AppShell.tsx y src/components/DemoSwitcher.tsx).
# En un build de producción `DEV` es false, así que sin esta variable Vite elimina esas
# ramas por dead-code elimination: el despliegue quedaba con la landing prometiendo
# "no pide registro" y un /login sin ninguna cuenta de prueba que ofrecer.
#
# Este despliegue ES la demostración del producto, de ahí el default en 1. Cuando deje
# de serlo, basta pasar `--build-arg VITE_DEMO_UI=0` (o declararlo como build variable en
# Coolify) y las cuentas demo desaparecen del bundle sin tocar código.
ARG VITE_DEMO_UI=1
ENV VITE_DEMO_UI=$VITE_DEMO_UI
RUN npm run build
# ---- Runtime ----
FROM node:22-slim
WORKDIR /app
ENV NODE_ENV=production
ENV HOST=0.0.0.0
ENV PORT=3000
# La zona del contenedor se fija explícitamente a UTC, que es como se almacenan los
# instantes en la base. La lógica de agenda ya no depende de ella (usa
# `businesses.timezone` vía server/lib/time.ts), y dejarla en UTC hace que cualquier
# recaída a la tz del proceso se note de inmediato en vez de esconderse en dev.
ENV TZ=UTC
COPY package*.json ./
RUN npm ci --omit=dev && npm cache clean --force
# Built frontend (vite outputs to dist/)
COPY --from=web-build /app/dist ./dist
# Server source (tsx runs TS directly in production)
COPY server ./server
COPY shared ./shared
COPY tsconfig.json ./
# Persistent SQLite data.
#
# NO declares `VOLUME /app/data` aquí. Esa instrucción hace que Docker fabrique un
# volumen ANÓNIMO en cada arranque, y Coolify los purga al recrear el contenedor:
# cada despliegue estrenaba base vacía y `ensureSeed()` la resembraba, así que se
# perdían las citas, los clientes y todo lo configurado en Ajustes. Se verificó
# comparando el nombre del volumen entre despliegues — cambiaba cada vez.
#
# La persistencia la aporta el almacenamiento con nombre declarado en Coolify
# (`s30f7egdlkx4wyjp59o1iunc-agendamax-data` montado en /app/data), que sobrevive a
# la recreación del contenedor. Si algún día se despliega en otro sitio, hay que
# declarar allí un volumen equivalente: sin él la base es efímera.
RUN mkdir -p /app/data
EXPOSE 3000
CMD ["npx", "tsx", "server/index.ts"]