diff --git a/.docker/dev-start.sh b/.docker/dev-start.sh new file mode 100644 index 0000000..3bb6ae8 --- /dev/null +++ b/.docker/dev-start.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +set -eu + +pnpm install --frozen-lockfile + +exec pnpm dev --host "${HOST:-0.0.0.0}" --port "${PORT:-20013}" diff --git a/Dockerfile b/Dockerfile index c48468f..18cdfba 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,6 +12,13 @@ FROM deps AS build COPY . . RUN pnpm build +FROM deps AS dev +ENV NODE_ENV=development +COPY .docker/dev-start.sh /usr/local/bin/docker-dev-start +RUN chmod +x /usr/local/bin/docker-dev-start +EXPOSE 20013 +CMD ["docker-dev-start"] + FROM base AS prod-deps COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ RUN pnpm install --frozen-lockfile --prod diff --git a/README.md b/README.md index 98159c9..7e39373 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ The repo now includes a production-ready container stack: - [Dockerfile](/mnt/d/SourceCode/tootaio/dinner-ticket-system/Dockerfile) - [docker-compose.yml](/mnt/d/SourceCode/tootaio/dinner-ticket-system/docker-compose.yml) +- [docker-compose.dev.yml](/mnt/d/SourceCode/tootaio/dinner-ticket-system/docker-compose.dev.yml) - [.dockerignore](/mnt/d/SourceCode/tootaio/dinner-ticket-system/.dockerignore) Bring up the full environment: @@ -97,6 +98,29 @@ docker compose down -v For passkey testing in Docker, set `NUXT_PUBLIC_APP_URL` to the exact origin you open in the browser. In production, this should be your final HTTPS URL. +### Docker Development With Hot Reload + +Use the dev override when you want live reload instead of rebuilding the image after every code change: + +```bash +docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build +``` + +This keeps PostgreSQL and Redis in Docker, but runs the app container in Nuxt dev mode with: + +- the project directory bind-mounted into `/app` +- a persistent `/app/node_modules` volume so dependencies stay inside Docker +- an automatic `pnpm install --frozen-lockfile` during app container startup +- polling-based file watching for reliable reloads on mounted filesystems + +After the first start, code changes on the host should reload automatically without rebuilding the image. + +When you change dependencies, restart the app container so it reruns `pnpm install` against the current lockfile: + +```bash +docker compose -f docker-compose.yml -f docker-compose.dev.yml restart app +``` + ## Protected Areas - `/login` diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..8a57509 --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,31 @@ +services: + app: + build: + context: . + dockerfile: Dockerfile + target: dev + environment: + NODE_ENV: development + HOST: 0.0.0.0 + NITRO_HOST: 0.0.0.0 + PORT: 20013 + CHOKIDAR_USEPOLLING: "true" + CHOKIDAR_INTERVAL: ${CHOKIDAR_INTERVAL:-1000} + WATCHPACK_POLLING: "true" + NUXT_DATABASE_URL: ${NUXT_DATABASE_URL:-postgresql://postgres:postgres@postgres:5432/dinner_ticket_system} + NUXT_REDIS_URL: ${NUXT_REDIS_URL:-redis://redis:6379} + NUXT_SESSION_COOKIE_NAME: ${NUXT_SESSION_COOKIE_NAME:-dinner_ticket_session} + NUXT_PUBLIC_APP_URL: ${NUXT_PUBLIC_APP_URL:-http://localhost:20013} + NUXT_PUBLIC_RP_NAME: ${NUXT_PUBLIC_RP_NAME:-Dinner Ticket System} + volumes: + - .:/app + - app_node_modules:/app/node_modules + - app_nuxt:/app/.nuxt + healthcheck: + start_period: 60s + tty: true + stdin_open: true + +volumes: + app_node_modules: + app_nuxt: