Ответ
Да, регулярно пишу и оптимизирую Dockerfile для сборки образов PHP-приложений. Основная цель — создать воспроизводимое, легковесное и безопасное окружение.
Пример Dockerfile для Laravel-приложения с многоступенчатой сборкой:
# Этап сборки (Builder)
FROM composer:2 AS builder
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-scripts --optimize-autoloader
COPY . .
RUN composer dump-autoload --optimize
# Финальный этап (Production)
FROM php:8.2-fpm-alpine
# Установка системных зависимостей и PHP-расширений
RUN apk add --no-cache
libzip-dev
postgresql-dev
&& docker-php-ext-install zip pdo_pgsql opcache
# Копирование скомпилированных зависимостей из этапа builder
COPY --from=builder /app /var/www/html
WORKDIR /var/www/html
# Настройка прав доступа и пользователя
RUN chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache
USER www-data
# Запуск PHP-FPM
CMD ["php-fpm"]
Ключевые практики, которые я применяю:
- Многоступенчатая сборка: Отдельный этап для установки зависимостей через Composer, чтобы в финальный образ попали только необходимые файлы, что уменьшает его размер.
- Использование легковесных базовых образов: Например,
-alpineверсий. - Объединение команд RUN: Для уменьшения количества слоев в образе.
- Правильная настройка прав пользователя: Запуск процессов от непривилегированного пользователя (не root) для безопасности.
- Кэширование слоев: Правильное копирование
composer.jsonиcomposer.lockдо копирования всего кода, чтобы использовать кэш Docker при установке зависимостей.
Ответ 18+ 🔞
А, Dockerfile для PHP? Ну это ж святое дело, ебать мои старые костыли! Каждый раз как ритуал — собрать образ, чтобы он и летал, и весил как перышко, и чтобы никакой левый хлам внутри не болтался. Цель-то простая: чтоб окружение было как швейцарские часы — воспроизводимое, лёгкое и чтобы никакой шпионской дряни для безопасности.
Вот, глянь, как я обычно Laravel-то упаковываю, с многоступенчатой сборкой:
# Этап сборки (Builder)
FROM composer:2 AS builder
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-scripts --optimize-autoloader
COPY . .
RUN composer dump-autoload --optimize
# Финальный этап (Production)
FROM php:8.2-fpm-alpine
# Установка системных зависимостей и PHP-расширений
RUN apk add --no-cache
libzip-dev
postgresql-dev
&& docker-php-ext-install zip pdo_pgsql opcache
# Копирование скомпилированных зависимостей из этапа builder
COPY --from=builder /app /var/www/html
WORKDIR /var/www/html
# Настройка прав доступа и пользователя
RUN chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache
USER www-data
# Запуск PHP-FPM
CMD ["php-fpm"]
А теперь, ёпта, главные фишки, на которых всё держится:
- Многоступенчатая сборка: Это вообще гениальная вещь. Отдельная кухня, где Composer всю требуху намешивает, а в финальный контейнер попадает только готовый бизнес-ланч — чистый код, без dev-зависимостей и прочего строительного мусора. Размер образа уменьшается в разы, просто праздник какой-то.
- Лёгкие базовые образы:
alpine— наш лучший друг. Эти образы такие тощие, что им паёк в детском саду выдавать надо. Но зато быстрые и безопасные. - Объединение команд RUN: Тут без вариантов — чем меньше слоёв в образе, тем лучше. Склеивай всё, что можно, в одну команду, будто делаешь мега-сэндвич, а не подаёшь блюда по отдельности.
- Правильные права пользователя: Запускать всё от root — это прям приглашение для всяких ушлых типов. Поэтому гоним его нахуй и работаем от
www-data. Безопасность, мать её! - Кэширование слоёв — наше всё: Сначала копируем только
composer.jsonиcomposer.lock, ставим зависимости. Потом уже весь код. Так если зависимости не менялись, Docker возьмёт всё из кэша, и не придётся каждый раз ждать, пока Composer мир обойдёт. Экономия времени — овердохуища!
Видео-ответы
▶
▶
▶
▶
▶
▶
▶