diff --git a/.dockerignore b/.dockerignore index 4e4ea8f..f31fbcd 100644 --- a/.dockerignore +++ b/.dockerignore @@ -10,12 +10,13 @@ node_modules vendor public/build public/hot -storage/app/private/** -storage/app/public/** -storage/logs/** -storage/framework/cache/** -storage/framework/sessions/** -storage/framework/views/** +# Exclude whole trees (not only /**) so Docker never tries to stat root-owned tmp dirs +storage/app/private +storage/app/public +storage/logs +storage/framework/cache +storage/framework/sessions +storage/framework/views database/*.sqlite* .env .env.* diff --git a/Dockerfile b/Dockerfile index 5fcf5a8..75136ab 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,8 +9,7 @@ WORKDIR /app COPY composer.json composer.lock ./ -RUN --mount=type=cache,target=/tmp/cache \ - composer install \ +RUN composer install \ --no-dev \ --no-scripts \ --no-autoloader \ @@ -18,7 +17,7 @@ RUN --mount=type=cache,target=/tmp/cache \ --no-interaction # --------------------------------------------------------------------------- -# npm ci only (parallel with vendor — does not wait on Composer) +# npm ci only (parallel with vendor when BuildKit is available) # --------------------------------------------------------------------------- FROM node:22-bookworm AS npm @@ -26,8 +25,7 @@ WORKDIR /app COPY package.json package-lock.json ./ -RUN --mount=type=cache,target=/root/.npm \ - npm ci +RUN npm ci # --------------------------------------------------------------------------- # Vite production build (needs Flux/Livewire + Laravel pagination views) @@ -85,14 +83,14 @@ WORKDIR /app COPY --from=vendor /app/vendor ./vendor COPY composer.json composer.lock ./ -# Application source (.dockerignore excludes vendor, node_modules, public/build) +# Application source (.dockerignore excludes vendor, node_modules, public/build, storage uploads) COPY . . # Built frontend assets COPY --from=assets /app/public/build ./public/build -RUN composer dump-autoload --optimize --no-dev \ - && mkdir -p \ +# Framework/view cache paths must exist before package:discover runs during dump-autoload +RUN mkdir -p \ storage/app/private \ storage/app/public \ storage/framework/cache \ @@ -101,6 +99,7 @@ RUN composer dump-autoload --optimize --no-dev \ storage/logs \ database \ bootstrap/cache \ + && composer dump-autoload --optimize --no-dev \ && chown -R www-data:www-data storage bootstrap/cache database EXPOSE 80 diff --git a/README.md b/README.md index bc0017f..64a6010 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,14 @@ docker compose up -d Data under `./database`, `./storage/app`, and `./storage/logs` is kept on the host. +If `docker compose build` fails with `can't stat .../storage/app/private/livewire-tmp`, a container created that directory as root. Fix ownership (or remove it), then rebuild: + +```bash +sudo chown -R "$USER:$USER" storage +# or: sudo rm -rf storage/app/private/livewire-tmp +docker compose up --build -d +``` + ### Live reload while developing Default Compose uses the built image, so PHP/Blade/CSS/JS changes need a rebuild. For day-to-day work, use the dev overlay (bind-mounts the repo and runs Vite HMR):