Создание Docker-образа с Dockerfile — Ubuntu 20.04, Nginx и PHP-FPM
Введение
Docker — средство виртуализации на уровне операционной системы, удобное разработчикам и системным администраторам. Docker упрощает создание и развёртывание приложений в изолированной среде. Dockerfile — это скрипт, содержащий набор инструкций и команд, выполняющихся последовательно для сборки Docker-образа.
В этом руководстве показано создание собственного Docker-образа с помощью Dockerfile. Пошаговые команды и конфигурации приводятся для Ubuntu 20.04 и включают настройку Nginx, PHP-FPM и supervisord.
Требования
- В примерах использована Ubuntu 20.04.
- Рекомендуемые ресурсы для тестовой машины: 1 ГБ ОЗУ, 25 ГБ свободного места на диске, 2 CPU.
- Установленный Docker (инструкция ниже показывает установку через apt для Ubuntu).
Краткое описание ключевых инструкций Dockerfile
Определение основных инструкций Dockerfile, которые используются в примере:
- FROM — задаёт базовый образ (обязательно в начале Dockerfile).
- LABEL — метаданные образа (maintainer, version, description и т. п.).
- RUN — выполняет команду во время сборки (например, установка пакетов).
- ADD / COPY — копирует файлы/папки из контекста сборки в образ.
- ENV — задаёт переменные окружения на этапе сборки и выполнения.
- ARG — аргумент сборки, доступный только во время docker build.
- CMD — команда по умолчанию при запуске контейнера (может быть переопределена при запуске).
- ENTRYPOINT — задаёт исполняемую точку контейнера (обычно для фиксированных входных точек).
- WORKDIR — рабочая директория для последующих инструкций.
- USER — задаёт пользователя, от имени которого будут выполняться команды.
- EXPOSE — указывает порты, которые приложение слушает (информационная; проброс портов делается через docker run -p).
- VOLUME — объявляет точки монтирования для данных, которые должны храниться вне образа.
Важно: Dockerfile должен содержать только одну инструкцию FROM на старте каждого build-stage; CMD в Dockerfile может быть только один (последний применяется).
Шаг 1 — Установка Docker на Ubuntu 20.04
Обновите индекс пакетов и установите docker.io из репозиториев Ubuntu FocalFossa:
sudo apt update
sudo apt install docker.ioЗапустите службу Docker и включите автозапуск при загрузке:
systemctl start docker
systemctl enable dockerПроверка статуса службы:
systemctl status dockerДалее запустите тестовый контейнер hello-world:
docker run hello-worldОжидаемый вывод подтверждает, что клиент связался с демоном Docker, образ скачан, контейнер выполнен и результат показан в терминале.

Также можно проверить, что служба поднята через системный вывод или скриншоты состояния.

Шаг 2 — Создание Dockerfile и сопутсвующих конфигураций
В нашем примере создаём образ на базе ubuntu:20.04, устанавливаем nginx, php-fpm 7.4 и supervisord, настраиваем виртуальный хост для PHP и добавляем скрипт запуска.
Создайте рабочую директорию и пустой Dockerfile:
mkdir -p nginx-image; cd nginx-image/
touch DockerfileОтредактируйте Dockerfile (в примере используется vim):
vim DockerfileВ верхней части добавьте базовый образ и метаданные. Ниже — последовательность инструкций для установки пакетов, конфигурации PHP и Nginx, копирования конфигураций supervisord и скрипта запуска, а также установка прав и объявление томов и портов.
(Вставляйте и сохраняйте Dockerfile именно в том виде, как он будет собираться; пример полного Dockerfile приведён далее.)
Ниже приведён примерный Dockerfile из руководства (сохраните файл как Dockerfile):
# Download base image ubuntu 20.04
FROM ubuntu:20.04
# LABEL about the custom image
LABEL maintainer="[email protected]"
LABEL version="0.1"
LABEL description="This is custom Docker Image for \
the PHP-FPM and Nginx Services."
# Disable Prompt During Packages Installation
ARG DEBIAN_FRONTEND=noninteractive
# Update Ubuntu Software repository
RUN apt update
# Install nginx, php-fpm and supervisord from ubuntu repository
RUN apt install -y nginx php-fpm supervisor && \
rm -rf /var/lib/apt/lists/* && \
apt clean
# Define the ENV variable
ENV nginx_vhost /etc/nginx/sites-available/default
ENV php_conf /etc/php/7.4/fpm/php.ini
ENV nginx_conf /etc/nginx/nginx.conf
ENV supervisor_conf /etc/supervisor/supervisord.conf
# Enable PHP-fpm on nginx virtualhost configuration
COPY default ${nginx_vhost}
RUN sed -i -e 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g' ${php_conf} && \
echo "\ndaemon off;" >> ${nginx_conf}
# Copy supervisor configuration
COPY supervisord.conf ${supervisor_conf}
RUN mkdir -p /run/php && \
chown -R www-data:www-data /var/www/html && \
chown -R www-data:www-data /run/php
# Volume configuration
VOLUME ["/etc/nginx/sites-enabled", "/etc/nginx/certs", "/etc/nginx/conf.d", "/var/log/nginx", "/var/www/html"]
# Copy start.sh script and define default command for the container
COPY start.sh /start.sh
CMD ["./start.sh"]
# Expose Port for the Application
EXPOSE 80 443Конфигурация Nginx (файл default)
Создайте файл default рядом с Dockerfile и вставьте виртуальный хост, который проксирует PHP через сокет php-fpm:
vim defaultВставьте:
server {
listen 80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
}
}Конфигурация supervisord (supervisord.conf)
Создайте файл supervisord.conf и поместите туда программы для запуска nginx и php-fpm:
vim supervisord.confВставьте:
[unix_http_server]
file=/dev/shm/supervisor.sock ; (the path to the socket file)
[supervisord]
logfile=/var/log/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10 ; (num of main logfile rotation backups;default 10)
loglevel=info ; (log level;default info; others: debug,warn,trace)
pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false ; (start in foreground if true;default false)
minfds=1024 ; (min. avail startup file descriptors;default 1024)
minprocs=200 ; (min. avail process descriptors;default 200)
user=root ;
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///dev/shm/supervisor.sock ; use a unix:// URL for a unix socket
[include]
files = /etc/supervisor/conf.d/*.conf
[program:php-fpm7.4]
command=/usr/sbin/php-fpm7.4 -F
numprocs=1
autostart=true
autorestart=true
[program:nginx]
command=/usr/sbin/nginx
numprocs=1
autostart=true
autorestart=trueСкрипт запуска start.sh
Создайте start.sh и сделайте его исполняемым:
vim start.shВставьте содержимое:
#!/bin/sh
/usr/bin/supervisord -n -c /etc/supervisor/supervisord.confСделайте скрипт исполняемым:
chmod +x start.shПосле этого в директории должны быть: Dockerfile, default, supervisord.conf, start.sh и любые другие файлы/папки, которые вы хотите копировать в образ.

Шаг 3 — Сборка образа и запуск контейнера
Из директории проекта выполните команду сборки образа:
docker build -t nginx-image .Команда скачивает базовый образ ubuntu:20.04 (если его нет локально) и создаёт образ с тегом nginx-image. После успешной сборки проверьте локальные образы:
docker image ls
Запустите контейнер, примонтировав директорию /webroot на хосте к /var/www/html в контейнере и пробросив порт 8080 на 80 контейнера:
mkdir -p /webroot
docker run -d -v /webroot:/var/www/html -p 8080:80 --name test-container nginx-imageПримечания к ключам:
- –name test-container nginx-image — имя контейнера и образ.
- -p 8080:80 — проброс порта 8080 хоста на 80 контейнера.
- -v /webroot:/var/www/html — монтирование директории веб-контента с хоста.
Проверьте запущенные контейнеры:
docker psОжидается, что контейнер test-container будет в списке и слушать проброшенный порт.
Шаг 4 — Тестирование
Создайте простую страницу index.html в /webroot на хост-машине:
echo 'Nginx and PHP-FPM 7.4 inside Docker Container with Ubuntu 20.04 Base Image
' > /webroot/index.htmlПроверьте доступ через curl (замените server-ip на реальный IP сервера или localhost для локальной машины):
curl server-ip:8080
curl -I server-ip:8080Должна отображаться созданная HTML-страница.

Проверьте обработку PHP, создав info.php:
echo '' > /webroot/info.phpОткройте в браузере:
http://server-ip:8080/info.php
Если всё настроено верно, вы увидите страницу phpinfo.

Миф и реальность: где этот подход хорош, а где — нет
- Хорошо подходит для: лёгкой локальной разработки, тестирования конфигураций, быстрых POC и простых сервисов, где не требуется сложного оркестратора.
- Не подходит при: крупных окружениях с множественными сервисами и зависимостями, когда нужен масштабируемый кластер (в таком случае лучше использовать Kubernetes или Docker Swarm с разделением сервисов). Если требуется высокий уровень отказоустойчивости, логирования и мониторинга, используйте специализированные решения.
Альтернативные подходы
- Использовать отдельные образы для Nginx и PHP-FPM и запускать их как связанные сервисы (лучше для масштабирования и изоляции).
- Использовать Docker Compose для описания связки сервисов (nginx + php-fpm + БД) в одном YAML и упрощённого управления.
- Для продакшена применить готовые официальные образы (nginx, php:fpm) и лишь тонко настраивать конфигурации сверху.
Практические эвристики и рекомендации
- Минимизируйте слои Dockerfile: группируйте команды RUN через && для сокращения числа слоёв и итогового размера образа.
- Всегда очищайте apt-кеш (rm -rf /var/lib/apt/lists/* && apt clean) после установки пакетов.
- По возможности используйте официальные slim-образы или специализированные образы PHP/NGINX, чтобы не собирать всё из Ubuntu.
- Храните конфигурации (nginx, supervisord, скрипты) вне образа и монтируйте как тома для быстрой правки без пересборки.
Чек-листы по ролям
Разработчик:
- Проверил, что index.php и зависимости приложения работают внутри контейнера.
- Убедился, что точка монтирования /var/www/html синхронизируется с хостом.
Системный администратор / DevOps:
- Проверил, что образ собирается без интерактивных запросов.
- Наладил мониторинг и логирование (лог nginx в /var/log/nginx должен быть доступен).
- Настроил бэкапы томов с данными.
Тестировщик:
- Запустил phpinfo и проверил версию PHP.
- Проверил обработку статических файлов и отдачу index.html.
- Проверил рестарт контейнера и автозапуск supervisord.
Критерии приёмки
- Контейнер запускается и отображает index.html по адресу http://server-ip:8080.
- PHP-скрипты обрабатываются через сокет php-fpm (phpinfo показывает php-fpm 7.4).
- Nginx и php-fpm управляются supervisord и автоматически перезапускаются при падении.
- Логи Nginx доступны и записываются в указанные тома.
Краткая методология (mini-methodology)
- Разбейте систему на сервисы: nginx, php-fpm, менеджер процессов.
- Выберите стратегию: один контейнер с supervisord или несколько контейнеров — по требованиям масштабирования.
- Настройте конфигурации как отдельные файлы и монтируйте их через тома.
- Автоматизируйте сборку и тестирование образа.
Модель принятия решения (Mermaid)
flowchart TD
A[Нужен быстрый POC] --> B{Требуется масштабирование?}
B -- Да --> C[Отдельные образы + оркестратор]
B -- Нет --> D[Один образ с supervisord]
C --> E[Использовать Docker Compose / Kubernetes]
D --> F[Собрать образ на базе Ubuntu/Alpine]Короткий глоссарий (1 строка для каждого)
- Dockerfile — текстовый файл с инструкциями для сборки Docker-образа.
- Image — неизменяемый шаблон для создания контейнеров.
- Container — исполненный экземпляр образа, изолированный процесс.
- Volume — внешняя точка хранения данных, независимая от жизненного цикла контейнера.
- supervisord — менеджер процессов, позволяющий запускать несколько сервисов в одном контейнере.
Когда этот подход не годится (примеры)
- Если нужно динамически масштабировать PHP-процессы независимо от Nginx — лучше разделить на сервисы.
- Для высоконагруженных систем требуется балансировка, оркестрация и отказоустойчивость — одномашинный образ с supervisord не даст этого.
- Если в проекте строгие требования по безопасности и минимизации образа — используйте специализированные минимальные образы (alpine) и строгие политики прав.
Риски и смягчение
- Риск: большой размер образа -> Смягчение: использовать slimmer базовые образы, объединять команды RUN и очищать кэш.
- Риск: утечка секретов при копировании конфигураций -> Смягчение: не хранить секреты в Dockerfile/образе, использовать переменные окружения и секреты на уровне оркестратора.
Краткая проверка (Test cases / acceptance criteria)
- TC1: Сборка образа завершается без ошибок.
- TC2: Контейнер стартует и возвращает HTTP 200 для /.
- TC3: /info.php возвращает страницу phpinfo с версией PHP 7.4.
- TC4: При перезапуске контейнера приложения автоматически стартуют через supervisord.
Сводка
- Вы создали Dockerfile, определили конфигурации Nginx и supervisord, собрали образ и запустили контейнер.
- Подход прост для разработки и тестирования, но для продакшна рекомендуются отдельные образы сервисов и оркестрация.
Важно: перед переводом в продакшен оцените требования по доступности, мониторингу, безопасности и масштабированию.
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента