Создание Docker-образа с помощью Dockerfile
Этот пошаговый гид показывает, как собрать собственный Docker-образ на базе Ubuntu 18.04 с PHP‑FPM и Nginx, настроить supervisord и протестировать контейнер через порт 8080. Включены примеры Dockerfile, конфигураций Nginx и supervisord, сценарий запуска и рекомендации по отладке и безопасности.
Кому полезно
- Разработчикам и системным администраторам, которые хотят упаковать PHP‑приложение в Docker.
- Тем, кто делает простые стековые образы (Nginx + PHP‑FPM) на Ubuntu.
Основные шаги на высоком уровне
- Установить Docker CE на Ubuntu 18.04.
- Создать проект и Dockerfile с нужными инструкциями (FROM, RUN, COPY и т.д.).
- Добавить конфигурации для Nginx и supervisord, скрипт старта.
- Собрать образ docker build и запустить контейнер docker run.
- Протестировать HTTP и phpinfo.
Важно: все команды в руководстве предполагают работу с правами администратора или через sudo.

Необходимые ресурсы и предпосылки
- Сервер или виртуальная машина с Ubuntu 18.04, минимум 1 ГБ ОЗУ, ~25 ГБ свободного места, 2 CPU.
- Доступ root / sudo.
- Подключение к интернету для загрузки образов и пакетов.
Если вы используете другую версию Ubuntu, учтите возможные отличия в путях конфигураций PHP (например, php7.4 вместо php7.2).
Введение в инструкции Dockerfile
Dockerfile — это набор инструкций, которые Docker последовательно выполняет, чтобы построить образ. Ниже — краткая справка по наиболее важным инструкциям, используемым в примере.
- FROM — задаёт базовый образ. Должен быть первым оператором в Dockerfile.
- LABEL — метаданные образа (maintainer, version, description).
- ARG — аргументы, передаваемые на этапе сборки (build-time).
- ENV — переменные окружения, доступные при сборке и в контейнере.
- RUN — команды, выполняемые во время сборки (установка пакетов и т. п.).
- COPY / ADD — копирование файлов из контекста сборки в образ. ADD может также скачивать файлы по URL.
- WORKDIR — рабочая директория для следующих инструкций.
- USER — пользователь для выполнения команд в контейнере.
- VOLUME — определяет точки монтирования для внешних томов/директорий.
- EXPOSE — объявляет порты, используемые приложением (не публикует их автоматически).
- ENTRYPOINT и CMD — задают, что будет запущено при старте контейнера. ENTRYPOINT фиксирует программу, CMD даёт аргументы по умолчанию.
Понимание этих инструкций поможет адаптировать Dockerfile под ваши нужды.
Шаг 1 — Установка Docker CE (Community Edition)
Если на вашей Ubuntu Docker ещё не установлен, выполните обновление индексa пакетов и установку зависимостей:
sudo apt update
sudo apt install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-commonДобавьте GPG-ключ официального репозитория Docker:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -Добавьте репозиторий Docker CE:
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"Установите пакеты Docker CE:
sudo apt install docker-ce docker-ce-cli containerd.ioЗапустите сервис Docker и включите автозапуск:
systemctl start docker
systemctl enable dockerПроверьте установку запуском тестового контейнера:
docker run hello-worldОжидаемый вывод — сообщение “Hello from Docker!” и краткая последовательность шагов, которые Docker выполнил.

Совет: добавьте своего пользователя в группу docker, чтобы запускать контейнеры без sudo: sudo usermod -aG docker $USER (потребуется выход/вход в систему).
Шаг 2 — Создание проекта и Dockerfile
Мы соберём образ на базе Ubuntu 18.04 с Nginx, PHP‑FPM и supervisord. Создайте рабочую директорию и пустой Dockerfile:
mkdir -p nginx-image; cd nginx-image/
touch DockerfileОткройте Dockerfile в редакторе и добавьте базовый образ и метаданные. В примере используются комментарии для удобства; они не влияют на выполнение.
# Скачиваем базовый образ Ubuntu 18.04
FROM ubuntu:18.04
# METADATA
LABEL maintainer="[email protected]"
LABEL version="0.1"
LABEL description="This is custom Docker Image for \
the PHP-FPM and Nginx Services."Далее задаём ARG, обновляем репозитории и устанавливаем пакеты. Мы отключаем интерактивные подсказки при установке:
# Отключаем интерактивные подсказки
ARG DEBIAN_FRONTEND=noninteractive
# Обновляем индекс пакетов
RUN apt update
# Устанавливаем nginx, php-fpm и supervisor, потом очищаем кеш apt
RUN apt install -y nginx php-fpm supervisor && \
rm -rf /var/lib/apt/lists/* && \
apt cleanПримечание: при использовании другой версии PHP замените пути и имена пакетов (например, php7.4-fpm).
Определим переменные окружения, чтобы позже ссылаться на конфигурационные пути компактно:
ENV nginx_vhost /etc/nginx/sites-available/default
ENV php_conf /etc/php/7.2/fpm/php.ini
ENV nginx_conf /etc/nginx/nginx.conf
ENV supervisor_conf /etc/supervisor/supervisord.confКопируем собственный виртуальный хост Nginx и изменяем php.ini и nginx.conf:
# Копируем конфигурацию виртуального хоста
COPY default ${nginx_vhost}
# Меняем cgi.fix_pathinfo на 0 и добавляем daemon off в nginx.conf
RUN sed -i -e 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g' ${php_conf} && \
echo "\ndaemon off;" >> ${nginx_conf}Копируем конфигурацию supervisord и создаём необходимые каталоги и права:
# Копируем конфигурацию supervisord
COPY supervisord.conf ${supervisor_conf}
# Создаём сок php-fpm и настраиваем права на web-root
RUN mkdir -p /run/php && \
chown -R www-data:www-data /var/www/html && \
chown -R www-data:www-data /run/phpОпределим тома и команду запуска:
VOLUME ["/etc/nginx/sites-enabled", "/etc/nginx/certs", "/etc/nginx/conf.d", "/var/log/nginx", "/var/www/html"]
COPY start.sh /start.sh
CMD ["./start.sh"]
EXPOSE 80 443Ниже — полный Dockerfile, который мы использовали в примере. Вставляйте его как есть в файл Dockerfile в корне проекта.
# Download base image ubuntu 18.04
FROM ubuntu:18.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.2/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Дополнительные файлы проекта
Ниже — примеры файлов, которые нужно поместить рядом с Dockerfile в контексте сборки: конфигурация виртуального хоста Nginx (default), конфигурация supervisord (supervisord.conf) и скрипт запуска (start.sh).
Файл default (Nginx virtualhost):
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.2-fpm.sock;
}
}Файл supervisord.conf:
[unix_http_server]
file=/dev/shm/supervisor.sock
[supervisord]
logfile=/var/log/supervisord.log
logfile_maxbytes=50MB
logfile_backups=10
loglevel=info
pidfile=/tmp/supervisord.pid
nodaemon=false
minfds=1024
minprocs=200
user=root
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///dev/shm/supervisor.sock
[include]
files = /etc/supervisor/conf.d/*.conf
[program:php-fpm7.2]
command=/usr/sbin/php-fpm7.2 -F
numprocs=1
autostart=true
autorestart=true
[program:nginx]
command=/usr/sbin/nginx
numprocs=1
autostart=true
autorestart=trueФайл start.sh:
#!/bin/sh
/usr/bin/supervisord -n -c /etc/supervisor/supervisord.confНе забудьте сделать start.sh исполняемым:
chmod +x start.shПосле подготовки всех файлов у вас в проекте будут как минимум следующие сущности:
- Dockerfile
- default
- supervisord.conf
- start.sh
Команда tree . покажет структуру проекта.

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

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

Если phpinfo отображается — PHP‑FPM корректно обрабатывает запросы через Nginx.
Раздел: отладка и распространённые проблемы
- Нету сокета php7.2-fpm.sock или неверный путь — проверьте путь в php-fpm конфигурации и в Nginx.
- Права на /var/www/html — проверьте владельца и права (chown -R www-data:www-data /var/www/html).
- Конфликты портов — если 8080 занят, используйте другой хост‑порт при docker run (-p 8081:80 и т.д.).
- Обновления пакетов в образе — обязательно очищайте кеш apt, чтобы уменьшить размер образа.
- При изменениях в файлах конфигурации в образе — пересобирайте образ или используйте томы для конфигурационных директорий.
Команды для быстрой диагностики внутри контейнера:
docker exec -it test-container bash
# внутри контейнера
ps aux | grep nginx
ps aux | grep php-fpm
tail -n 200 /var/log/nginx/error.log
tail -n 200 /var/log/supervisord.logСоветы по уменьшению размера образа и улучшению практик
- Используйте минимальные базовые образы (alpine) там, где это возможно, но учтите отличия в менеджере пакетов и путях.
- Объединяйте RUN-инструкции в один слой (используя &&) — это сокращает число слоёв образа.
- Очищайте кеш apt и временные файлы в конце RUN: rm -rf /var/lib/apt/lists/* && apt clean.
- Рассмотрите multi-stage builds для сборки артефактов и копирования только нужного в финальный образ.
Контрпример: если вы стремитесь к максимально лёгкому PHP/Nginx-образу, лучше использовать официальные образы nginx:alpine и php:fpm-alpine и настраивать их совместно, а не Ubuntu, — это уменьшит размер и поверхность атаки.
Безопасность и эксплуатация
- Минимизируйте набор пакетов внутри образа.
- Не храните секреты и пароли в Dockerfile или в ENV; используйте секреты Docker или внешние хранилища.
- Ограничьте привилегии пользователя: по возможности не запускать процессы от root.
- Обновляйте базовый образ и переcобирайте образы при выходе важных патчей безопасности.
Краткая рекомендация: для production-окружения перенесите supervisord логи в централизованную систему логирования и используйте healthcheck для определения состояния контейнера.
Альтернативные подходы
- Использовать docker-compose: описать сервисы nginx и php-fpm в отдельных контейнерах и связать их сетью.
- Отказаться от supervisord, если контейнер должен запускать один процесс — использовать однотоновую (single‑process) модель (nginx как proxy, php-fpm как отдельный сервис).
- Многослойная архитектура: один контейнер — Nginx, второй — PHP‑FPM; это упрощает масштабирование и обновления.
Когда текущий подход не подходит: если вы планируете горизонтально масштабировать приложение или использовать orchestration (Kubernetes), чаще применяют отдельные контейнеры для Nginx и PHP-FPM.
Модель принятия решения (простой хелпер)
- Нужна простая локальная разработка и удобный монтируемый webroot? Используйте одну копию Nginx+PHP в контейнере и том.
- Нужна масштабируемость и отказоустойчивость? Разделите на два сервиса: frontend (Nginx) и backend (PHP‑FPM).
- Требуется минимальный размер образа? Используйте alpine‑based образы или официальный php-fpm/nginx.
Критерии приёмки
- Образ успешно собирается командой docker build без ошибок.
- Контейнер стартует и статус docker ps — Up.
- По адресу http://host:8080 доступен index.html.
- Страница http://host:8080/info.php показывает phpinfo().
- Логи supervisord и nginx не содержат критических ошибок.
Контрольный список для продакшена
- Проверить отсутствие секретов в образе.
- Настроить healthcheck в Dockerfile или Docker Compose.
- Перенести логи в централизованную систему.
- Организовать автоматическую сборку образов при обновлениях безопасности.
- Тестировать производительность (нагрузочный тест) перед деплоем.
Короткая методология миграции на другой PHP
Если вы хотите перейти с PHP 7.2 на 7.4/8.0:
- Обновить пакет в RUN apt install (php7.4-fpm).
- Изменить пути в ENV php_conf и в конфигурациях nginx (php7.4-fpm.sock).
- Протестировать phpinfo и критический функционал приложения.
1‑строчный глоссарий
- Dockerfile — инструкция для сборки Docker‑образа.
- Image — неизменяемый шаблон, из которого создаются контейнеры.
- Container — запущенный экземпляр образа.
- VOLUME — точка монтирования для длительного хранения данных.
Краткое резюме
- Создать Dockerfile, конфигурации и скрипт запуска.
- Собрать образ docker build и запустить контейнер docker run.
- Протестировать доступность приложения и работу PHP.
Если нужно, могу:
- Подготовить docker-compose.yml для разделения Nginx и PHP‑FPM.
- Адаптировать Dockerfile под другую версию PHP или минимизированный образ (alpine).
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента