Писал ли Dockerfile?

Ответ

Да, регулярно пишу и оптимизирую 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 мир обойдёт. Экономия времени — овердохуища!