Speed up Docker builds with a single image and parallel deps.
Build app once for queue/reverb, run Composer and npm in parallel with cache mounts, and skip redundant vite npm ci on restart.
This commit is contained in:
@@ -28,5 +28,6 @@ npm-debug.log
|
|||||||
yarn-error.log
|
yarn-error.log
|
||||||
tests
|
tests
|
||||||
docs
|
docs
|
||||||
|
todo.txt
|
||||||
*.md
|
*.md
|
||||||
!README.md
|
!README.md
|
||||||
|
|||||||
+36
-10
@@ -1,26 +1,46 @@
|
|||||||
# syntax=docker/dockerfile:1
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Composer deps (runs in parallel with npm ci)
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
FROM composer:2 AS vendor
|
FROM composer:2 AS vendor
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY composer.json composer.lock ./
|
COPY composer.json composer.lock ./
|
||||||
RUN composer install \
|
|
||||||
|
RUN --mount=type=cache,target=/tmp/cache \
|
||||||
|
composer install \
|
||||||
--no-dev \
|
--no-dev \
|
||||||
--no-scripts \
|
--no-scripts \
|
||||||
--no-autoloader \
|
--no-autoloader \
|
||||||
--prefer-dist \
|
--prefer-dist \
|
||||||
--no-interaction
|
--no-interaction
|
||||||
|
|
||||||
FROM node:22-bookworm AS assets
|
# ---------------------------------------------------------------------------
|
||||||
|
# npm ci only (parallel with vendor — does not wait on Composer)
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
FROM node:22-bookworm AS npm
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY package.json package-lock.json ./
|
COPY package.json package-lock.json ./
|
||||||
RUN npm ci
|
|
||||||
|
|
||||||
COPY --from=vendor /app/vendor ./vendor
|
RUN --mount=type=cache,target=/root/.npm \
|
||||||
COPY composer.json composer.lock ./
|
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 vite.config.js ./
|
||||||
COPY resources ./resources
|
COPY resources ./resources
|
||||||
COPY public ./public
|
COPY public ./public
|
||||||
@@ -39,8 +59,12 @@ ENV VITE_APP_NAME=$VITE_APP_NAME \
|
|||||||
|
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Runtime image
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
FROM dunglas/frankenphp:php8.5-bookworm
|
FROM dunglas/frankenphp:php8.5-bookworm
|
||||||
|
|
||||||
|
# Rarely changes — keep early for cache hits
|
||||||
RUN install-php-extensions \
|
RUN install-php-extensions \
|
||||||
pcntl \
|
pcntl \
|
||||||
pdo_sqlite \
|
pdo_sqlite \
|
||||||
@@ -50,16 +74,21 @@ RUN install-php-extensions \
|
|||||||
intl \
|
intl \
|
||||||
opcache
|
opcache
|
||||||
|
|
||||||
COPY docker/php.ini /usr/local/etc/php/conf.d/99-uploads.ini
|
|
||||||
|
|
||||||
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
|
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
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Dependency layer (invalidates when lockfiles / vendor change)
|
||||||
COPY --from=vendor /app/vendor ./vendor
|
COPY --from=vendor /app/vendor ./vendor
|
||||||
COPY composer.json composer.lock ./
|
COPY composer.json composer.lock ./
|
||||||
|
|
||||||
|
# Application source (.dockerignore excludes vendor, node_modules, public/build)
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
|
# Built frontend assets
|
||||||
COPY --from=assets /app/public/build ./public/build
|
COPY --from=assets /app/public/build ./public/build
|
||||||
|
|
||||||
RUN composer dump-autoload --optimize --no-dev \
|
RUN composer dump-autoload --optimize --no-dev \
|
||||||
@@ -74,9 +103,6 @@ RUN composer dump-autoload --optimize --no-dev \
|
|||||||
bootstrap/cache \
|
bootstrap/cache \
|
||||||
&& chown -R www-data:www-data storage bootstrap/cache database
|
&& chown -R www-data:www-data storage bootstrap/cache database
|
||||||
|
|
||||||
COPY docker/entrypoint.sh /usr/local/bin/entrypoint.sh
|
|
||||||
RUN chmod +x /usr/local/bin/entrypoint.sh
|
|
||||||
|
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ sed -i "s|^APP_KEY=.*|APP_KEY=${KEY}|" .env
|
|||||||
docker compose up --build -d
|
docker compose up --build -d
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Compose builds the **app** image once; `queue` and `reverb` reuse `andytranscribe-app:latest` (no triple rebuild). With the [dev overlay](#local-development-hot-reload), skip `--build` for routine PHP/Blade/JS work — the repo is bind-mounted.
|
||||||
|
|
||||||
On first start the app container will:
|
On first start the app container will:
|
||||||
|
|
||||||
- create `database/database.sqlite` if needed
|
- create `database/database.sqlite` if needed
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ services:
|
|||||||
image: node:22-bookworm
|
image: node:22-bookworm
|
||||||
container_name: andytranscribe-vite
|
container_name: andytranscribe-vite
|
||||||
working_dir: /app
|
working_dir: /app
|
||||||
command: sh -c "npm ci && npm run dev -- --host 0.0.0.0 --port 5173"
|
command: >
|
||||||
|
sh -c "if [ ! -x node_modules/.bin/vite ]; then npm ci; fi;
|
||||||
|
npm run dev -- --host 0.0.0.0 --port 5173"
|
||||||
ports:
|
ports:
|
||||||
- "${VITE_HOST_PORT:-5173}:5173"
|
- "${VITE_HOST_PORT:-5173}:5173"
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
+4
-18
@@ -70,17 +70,11 @@ services:
|
|||||||
condition: service_started
|
condition: service_started
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
|
# Shares andytranscribe-app:latest — do not declare build: here (avoids rebuilding 3×).
|
||||||
|
# `docker compose up --build` builds `app` first, then starts these with the tagged image.
|
||||||
queue:
|
queue:
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
args:
|
|
||||||
VITE_APP_NAME: ${VITE_APP_NAME:-AndyTranscribe}
|
|
||||||
VITE_REVERB_APP_KEY: ${REVERB_APP_KEY:-andytranscribe-key}
|
|
||||||
VITE_REVERB_HOST: ${VITE_REVERB_HOST:-localhost}
|
|
||||||
VITE_REVERB_PORT: ${REVERB_HOST_PORT:-8081}
|
|
||||||
VITE_REVERB_SCHEME: ${VITE_REVERB_SCHEME:-http}
|
|
||||||
image: andytranscribe-app:latest
|
image: andytranscribe-app:latest
|
||||||
|
pull_policy: never
|
||||||
container_name: andytranscribe-queue
|
container_name: andytranscribe-queue
|
||||||
command:
|
command:
|
||||||
- php
|
- php
|
||||||
@@ -107,16 +101,8 @@ services:
|
|||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
reverb:
|
reverb:
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
args:
|
|
||||||
VITE_APP_NAME: ${VITE_APP_NAME:-AndyTranscribe}
|
|
||||||
VITE_REVERB_APP_KEY: ${REVERB_APP_KEY:-andytranscribe-key}
|
|
||||||
VITE_REVERB_HOST: ${VITE_REVERB_HOST:-localhost}
|
|
||||||
VITE_REVERB_PORT: ${REVERB_HOST_PORT:-8081}
|
|
||||||
VITE_REVERB_SCHEME: ${VITE_REVERB_SCHEME:-http}
|
|
||||||
image: andytranscribe-app:latest
|
image: andytranscribe-app:latest
|
||||||
|
pull_policy: never
|
||||||
container_name: andytranscribe-reverb
|
container_name: andytranscribe-reverb
|
||||||
command:
|
command:
|
||||||
- php
|
- php
|
||||||
|
|||||||
Reference in New Issue
Block a user