# syntax=docker/dockerfile:1 # --------------------------------------------------------------------------- # Composer deps (runs in parallel with npm ci) # --------------------------------------------------------------------------- FROM composer:2 AS vendor WORKDIR /app COPY composer.json composer.lock ./ RUN composer install \ --no-dev \ --no-scripts \ --no-autoloader \ --prefer-dist \ --no-interaction # --------------------------------------------------------------------------- # npm ci only (parallel with vendor when BuildKit is available) # --------------------------------------------------------------------------- FROM node:22-bookworm AS npm WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci # --------------------------------------------------------------------------- # Vite production build (needs Flux/Livewire + Laravel pagination views) # --------------------------------------------------------------------------- FROM node:22-bookworm AS assets WORKDIR /app COPY --from=npm /app/node_modules ./node_modules COPY package.json package-lock.json ./ COPY --from=vendor /app/vendor/livewire ./vendor/livewire COPY --from=vendor /app/vendor/laravel/framework/src/Illuminate/Pagination \ ./vendor/laravel/framework/src/Illuminate/Pagination COPY vite.config.js ./ COPY resources ./resources COPY public ./public ARG VITE_APP_NAME=AndyTranscribe ARG VITE_REVERB_APP_KEY=andytranscribe-key ARG VITE_REVERB_HOST=localhost ARG VITE_REVERB_PORT=8081 ARG VITE_REVERB_SCHEME=http ENV VITE_APP_NAME=$VITE_APP_NAME \ VITE_REVERB_APP_KEY=$VITE_REVERB_APP_KEY \ VITE_REVERB_HOST=$VITE_REVERB_HOST \ VITE_REVERB_PORT=$VITE_REVERB_PORT \ VITE_REVERB_SCHEME=$VITE_REVERB_SCHEME RUN npm run build # --------------------------------------------------------------------------- # Runtime image # --------------------------------------------------------------------------- FROM dunglas/frankenphp:php8.5-bookworm # Rarely changes — keep early for cache hits RUN install-php-extensions \ pcntl \ pdo_sqlite \ sqlite3 \ zip \ bcmath \ intl \ opcache COPY --from=composer:2 /usr/bin/composer /usr/bin/composer COPY docker/php.ini /usr/local/etc/php/conf.d/99-uploads.ini COPY docker/entrypoint.sh /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/entrypoint.sh WORKDIR /app # Dependency layer (invalidates when lockfiles / vendor change) COPY --from=vendor /app/vendor ./vendor COPY composer.json composer.lock ./ # Application source (.dockerignore excludes vendor, node_modules, public/build, storage uploads) COPY . . # Built frontend assets COPY --from=assets /app/public/build ./public/build # 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 \ storage/framework/sessions \ storage/framework/views \ storage/logs \ database \ bootstrap/cache \ && composer dump-autoload --optimize --no-dev \ && chown -R www-data:www-data storage bootstrap/cache database EXPOSE 80 ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] CMD ["frankenphp", "php-server", "--listen", ":80", "--root", "/app/public"]