47eb4f62c1
Implements the injector diagnostic protocol module per spec:
- Migration: injector_protocols + injector_protocol_rows with company_id
(multi-tenant), vehicle_id (not car_id — this CRM uses Vehicle),
master_id FK to users, snapshot fields (car_model/plate/vin/mileage/year/
injector_brand) captured at protocol time.
- Models with BelongsToTenant; auto-generate protocol_number as
PS-{tenantId}-{year}-{seq6}; auto-seed 8 empty rows on create.
- Permissions: injector_protocols.view + injector_protocols.conclude.
Default roles: owner/admin (both), manager (both), receptionist (view
only), mechanic (both). Test permission count updated 52→54.
- InjectorProtocolResource under Service nav group with 4 sections:
data auto+client (with client_id/vehicle_id lookups auto-filling
snapshot fields), reason checkboxes, 8-row repeater for measurements
(Repeater with position hidden; fixed 8, non-addable/deletable),
conclusion + comment + master signature.
- Table with columns, badge filters, PDF action.
- Blade PDF template: pixel-close to reference (graphite/gold/blue
brand tokens, striped rows, rotated 'ФОРСУНКИ' header).
- Route /app/injector-protocols/{id}/pdf with permission gate,
streams PDF via new InjectorProtocolPdfService (Browsershot).
- Dockerfile: install nodejs 22 + chromium + noto fonts + puppeteer-core
in /opt/browsershot; env vars for Browsershot binary paths.
- +71 RU/EN translations covering resource + PDF template.
All 306 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
113 lines
3.4 KiB
Docker
113 lines
3.4 KiB
Docker
# syntax=docker/dockerfile:1.7
|
|
# AutoCRM — Laravel 12 + Filament + Octane FrankenPHP
|
|
# Multi-stage: composer install + npm build + runtime
|
|
|
|
# ─── Stage 1: Composer dependencies ───────────────────────────
|
|
FROM composer:2 AS composer
|
|
WORKDIR /app
|
|
COPY composer.json composer.lock ./
|
|
RUN composer install \
|
|
--no-dev \
|
|
--no-interaction \
|
|
--no-progress \
|
|
--no-scripts \
|
|
--prefer-dist \
|
|
--optimize-autoloader \
|
|
--ignore-platform-reqs
|
|
|
|
# ─── Stage 2: Node assets (Vite) ──────────────────────────────
|
|
FROM node:22-alpine AS node
|
|
WORKDIR /app
|
|
COPY package.json package-lock.json* ./
|
|
RUN if [ -f package-lock.json ]; then npm ci; else npm install; fi
|
|
COPY resources ./resources
|
|
COPY vite.config.js ./
|
|
COPY public ./public
|
|
RUN npm run build
|
|
|
|
# ─── Stage 3: Runtime (FrankenPHP + PHP 8.4) ──────────────────
|
|
FROM dunglas/frankenphp:1-php8.4 AS runtime
|
|
WORKDIR /app
|
|
|
|
# Install PHP extensions Laravel needs
|
|
RUN install-php-extensions \
|
|
pdo_mysql \
|
|
pcntl \
|
|
bcmath \
|
|
intl \
|
|
gd \
|
|
zip \
|
|
redis \
|
|
opcache \
|
|
pcntl \
|
|
sockets \
|
|
exif \
|
|
curl \
|
|
mbstring \
|
|
gmp
|
|
|
|
# System tools + Chromium + Node.js (for spatie/browsershot PDF rendering)
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
git \
|
|
unzip \
|
|
curl \
|
|
ca-certificates \
|
|
gnupg \
|
|
chromium \
|
|
fonts-liberation \
|
|
fonts-noto \
|
|
fonts-noto-cjk \
|
|
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
|
|
&& apt-get install -y --no-install-recommends nodejs \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Puppeteer + Browsershot deps live in a shared node_modules under /app
|
|
# so Browsershot can spawn `node`+puppeteer bundled with Chromium bindings.
|
|
RUN mkdir -p /opt/browsershot && cd /opt/browsershot \
|
|
&& npm install --omit=dev puppeteer-core@23 \
|
|
&& chown -R www-data:www-data /opt/browsershot
|
|
|
|
ENV BROWSERSHOT_NODE_BINARY=/usr/bin/node \
|
|
BROWSERSHOT_NPM_BINARY=/usr/bin/npm \
|
|
BROWSERSHOT_NODE_MODULE_PATH=/opt/browsershot/node_modules \
|
|
BROWSERSHOT_CHROME_PATH=/usr/bin/chromium
|
|
|
|
# Copy application code
|
|
COPY --link . /app
|
|
# Composer vendor from stage 1
|
|
COPY --from=composer --link /app/vendor /app/vendor
|
|
# Built assets from stage 2
|
|
COPY --from=node --link /app/public/build /app/public/build
|
|
|
|
# Permissions
|
|
RUN chown -R www-data:www-data storage bootstrap/cache \
|
|
&& chmod -R 0775 storage bootstrap/cache
|
|
|
|
# OPcache production config
|
|
RUN { \
|
|
echo "opcache.enable=1"; \
|
|
echo "opcache.enable_cli=1"; \
|
|
echo "opcache.jit_buffer_size=128M"; \
|
|
echo "opcache.jit=tracing"; \
|
|
echo "opcache.memory_consumption=256"; \
|
|
echo "opcache.max_accelerated_files=20000"; \
|
|
echo "opcache.validate_timestamps=0"; \
|
|
} > /usr/local/etc/php/conf.d/opcache.ini
|
|
|
|
ENV OCTANE_SERVER=frankenphp \
|
|
APP_BASE_PATH=/app \
|
|
SERVER_NAME=":8000"
|
|
|
|
EXPOSE 8000
|
|
|
|
# Healthcheck
|
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
|
|
CMD curl -fsSL http://localhost:8000/up || exit 1
|
|
|
|
# Entrypoint script handles migrations + cache
|
|
COPY docker/entrypoint.sh /usr/local/bin/entrypoint
|
|
RUN chmod +x /usr/local/bin/entrypoint
|
|
|
|
ENTRYPOINT ["/usr/local/bin/entrypoint"]
|
|
CMD ["php", "artisan", "octane:start", "--server=frankenphp", "--host=0.0.0.0", "--port=8000", "--admin-port=2019", "--workers=auto", "--max-requests=500"]
|