Гид по технологиям

Dockerfile: создать образ с Nginx и PHP‑FPM на Ubuntu 16.04

• 7 min read • Docker • Обновлено 22 Nov 2025
Dockerfile: образ Nginx + PHP‑FPM на Ubuntu 16.04
Dockerfile: образ Nginx + PHP‑FPM на Ubuntu 16.04

Иллюстрация: контейнеры Docker на сервере

Введение

Docker — это виртуализация на уровне ОС, ориентированная на разработчиков и системных администраторов. Docker упрощает создание и развёртывание приложений в изолированной среде. Dockerfile — это скрипт с набором инструкций, которые выполняются последовательно при сборке Docker‑образа.

В этом пошаговом руководстве вы научитесь создавать собственный образ на базе Ubuntu 16.04 с Nginx, PHP‑FPM 7 и Supervisord. Я объясню каждую секцию Dockerfile и сопутствующие файлы, а также дам советы по безопасности, отладке и альтернативные подходы.

Краткие определения:

  • Dockerfile: файл с инструкциями для сборки образа.
  • Образ (image): статичная, переносимая версия файловой системы, из которой запускают контейнер.
  • Контейнер: запущенный экземпляр образа.

Требования

  • Сервер с Linux (в примерах использованы команды для Ubuntu). Можно работать локально или на удалённом хосте.
  • Привилегии root или sudo.
  • Установленный Docker или доступ для установки (в шаге 1 показана установка через apt).

Важно: в примере используется Ubuntu 16.04 как базовый образ. Учтите, что это довольно старая версия ОС — при разработке на продакшн рекомендовано рассмотреть более новые LTS‑версии Ubuntu (например, 18.04/20.04/22.04) или официальные минимальные образы.

Команды Dockerfile — быстрый обзор

Ниже — основные инструкции Dockerfile с кратким объяснением:

  • FROM — базовый образ; должен быть первой инструкцией (за исключением комментариев).
  • MAINTAINER — необязательная метаинформация с автором/поддерживающим.
  • RUN — выполнить команду при сборке образа.
  • COPY / ADD — добавить файлы из контекста сборки в образ; ADD умеет распаковывать архивы и скачивать по URL.
  • ENV — задать переменные окружения.
  • CMD — команда по умолчанию, выполняемая при запуске контейнера (можно переопределить docker run).
  • ENTRYPOINT — фиксирует исполняемый процесс контейнера; CMD дополняет ENTRYPOINT.
  • WORKDIR — рабочая директория для последующих команд.
  • USER — поменять пользователя внутри контейнера.
  • VOLUME — объявить точки монтирования для внешних томов.
  • EXPOSE — декларация открытых портов (не пробрасывает порты автоматически).

Шаг 1 — Установка Docker на сервере

Подключитесь к серверу и обновите список пакетов:

ssh [email protected]
apt-get update

Установите docker.io через apt:

apt-get install docker.io

Запустите сервис Docker и включите автозапуск при старте системы:

systemctl start docker
systemctl enable docker

После этого Docker доступен и готов к использованию.

Шаг 2 — Создаём директорию и Dockerfile

Создадим папку для образа и пустой Dockerfile:

mkdir ~/myimages
cd myimages/
touch Dockerfile

В этом примере мы установим Nginx, PHP‑FPM 7 и Supervisord в образ на базе Ubuntu 16.04. Supervisord позволяет запускать и контролировать несколько сервисов в одном контейнере.

Откройте Dockerfile в редакторе (в примере использован nano):

nano Dockerfile

Добавьте в начало базовый образ:

#Download base image ubuntu 16.04
FROM ubuntu:16.04

Обновим index пакетов внутри образа:

# Update Ubuntu Software repository
RUN apt-get update

Установим nginx, php7.0-fpm и supervisor, а затем очистим кеш apt, чтобы уменьшить размер слоя образа:

# Install nginx, php-fpm and supervisord from ubuntu repository
RUN apt-get install -y nginx php7.0-fpm supervisor && \
    rm -rf /var/lib/apt/lists/*

Далее задаём переменные окружения, чтобы удобнее ссылаться на пути в конфигурациях, и включим правильную настройку php.ini и nginx:

#Define the ENV variable
ENV nginx_vhost /etc/nginx/sites-available/default
ENV php_conf /etc/php/7.0/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}

Затем скопируем конфигурацию Supervisord:

#Copy supervisor configuration
COPY supervisord.conf ${supervisor_conf}

Создадим runtime каталог для PHP‑FPM и назначим владельцем www‑data, чтобы веб‑сервер имел права на каталог /var/www/html:

RUN mkdir -p /run/php && \
    chown -R www-data:www-data /var/www/html && \
    chown -R www-data:www-data /run/php

Объявим VOLUME, чтобы можно было монтировать специфичные папки с хоста:

# Volume configuration
VOLUME ["/etc/nginx/sites-enabled", "/etc/nginx/certs", "/etc/nginx/conf.d", "/var/log/nginx", "/var/www/html"]

Скопируем скрипт старта и зададим команду по умолчанию, а также откроем порты HTTP/HTTPS:

# Configure Services and Port
COPY start.sh /start.sh
CMD ["./start.sh"]

EXPOSE 80 443

Сохраняем Dockerfile. Ниже — полный файл целиком (сохраните в проекте как Dockerfile):

#Download base image ubuntu 16.04
FROM ubuntu:16.04

# Update Software repository
RUN apt-get update

# Install nginx, php-fpm and supervisord from ubuntu repository
RUN apt-get install -y nginx php7.0-fpm supervisor && \
    rm -rf /var/lib/apt/lists/*

#Define the ENV variable
ENV nginx_vhost /etc/nginx/sites-available/default
ENV php_conf /etc/php/7.0/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"]

# Configure Services and Port
COPY start.sh /start.sh
CMD ["./start.sh"]

EXPOSE 80 443

Конфигурационные файлы: default, supervisord.conf и start.sh

В той же директории создайте три файла: default (виртуальный хост nginx), supervisord.conf и start.sh.

Создаём файл default:

vim default

Вставьте конфигурацию виртуального хоста:

server {
    listen 80 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.0-fpm.sock;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny all;
    #}
}

Создаём supervisord.conf:

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

; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[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.0]
command=/usr/sbin/php-fpm7.0 -F
numprocs=1
autostart=true
autorestart=true

[program:nginx]
command=/usr/sbin/nginx
numprocs=1
autostart=true
autorestart=true

Создаём start.sh (скрипт запуска):

vim start.sh

Вставьте:

#!/bin/sh

/usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf

Сделайте скрипт исполняемым:

chmod +x start.sh

Важно: проверяйте пути бинарников в образе (nginx, php-fpm, supervisord). В разных дистрибутивах они могут отличаться.

Список локальных Docker-образов после сборки

Шаг 3 — Сборка образа и запуск контейнера

В директории с Dockerfile и файлами конфигурации выполните:

docker build -t nginx_image .

Проверьте, что образ создан:

docker images

Перед запуском контейнера создайте директорию для webroot на хосте:

mkdir -p /webroot

Запустите контейнер, смонтировав /webroot в /var/www/html и открыв порт 80:

docker run -d -v /webroot:/var/www/html -p 80:80 --name hakase nginx_image

Проверим, что контейнер работает:

docker ps

Примечание по параметрам команд:

  • –name hakase nginx_image — контейнер с именем hakase, созданный на основе образа nginx_image.
  • -p 80:80 — проброс порта 80 на хосте в порт 80 контейнера.
  • -v /webroot:/var/www/html — монтирование папки с хоста в контейнер (содержимое /webroot будет доступно как /var/www/html).

Если контейнер запущен без ошибок, переходим к тестированию.

Шаг 4 — Тестирование Nginx и PHP‑FPM

Создадим простой HTML-файл в /webroot на хосте:

echo '

Nginx and PHP-FPM 7 inside Docker Container

' > /webroot/index.html

Проверим доступ командой curl (замените IP на IP вашего хоста):

curl 192.168.1.250
curl -I 192.168.1.250

Ожидаемый результат — HTML‑страница или заголовки ответа от Nginx.

Проверка доступа к Nginx внутри контейнера: вывод curl

Для проверки PHP создадим phpinfo:

echo '' > /webroot/info.php

Откройте в браузере:

http://вашегохоста>/info.php

Вы увидите страницу phpinfo(), подтверждающую работу PHP‑FPM через Nginx.

Вывод phpinfo() через Nginx и PHP‑FPM в контейнере

Если всё работает — образ nginx_image успешно собран и контейнер функционирует.

Полезные практики и проверочные списки

Краткая методология (микро‑SOP) для повторяемой сборки:

  1. Подготовить директорию проекта с Dockerfile и конфигурациями.
  2. Проверить пути и версии бинарников (nginx, php-fpm, supervisord).
  3. Собирать образ локально в чистом окружении (docker build).
  4. Тестировать контейнер с пробросом портов и монтированием локального каталога.
  5. Скриптировать тесты (curl, проверка процессов через docker exec).
  6. Произвести скан образа (clair, trivy) и зафиксировать результаты.

Стендовые критерии приёмки:

  • Образ собирается без ошибок при docker build.
  • Контейнер стартует и в supervisord запущены процессы nginx и php-fpm.
  • Страница /index.html отдается корректно.
  • /info.php отображает phpinfo() при включенной обработке .php.

Роль‑ориентированные чек-листы:

  • Для разработчика:
    • Монтирование /var/www/html должно отображать изменения в коде сразу.
    • Наличие удобного логирования (stdout/stderr) или маппинг /var/log/nginx.
  • Для системного администратора:
    • Настроить мониторинг контейнера (ресурсы, перезапуски).
    • Настроить хранение логов вне контейнера.
  • Для инженера по безопасности:
    • Минимизировать права процесса; избегать запуска сервисов от root.
    • Просканировать образ на уязвимости.

Безопасность и hardening (рекомендации)

  • Не запускайте сервисы под root внутри контейнера, если это возможно. Используйте USER www-data для запуска nginx/php‑fpm или создайте специализированного пользователя.
  • Зафиксируйте версии пакетов в Dockerfile (apt-get install пакет=версия) для повторяемости сборки.
  • Избегайте выполнения apt-get upgrade в Dockerfile — это усложняет контроль слоёв и воспроизводимость.
  • Ограничьте доступность метаданных и сокетов: не монтируйте лишние хостовые сокеты в контейнер.
  • Запустите сканирование образа инструментами типа trivy или clair перед продакшн‑развёртыванием.
  • Минимизируйте размер образа: рассматривайте использование более лёгких базовых образов (alpine, debian:slim) и multi‑stage сборки.

Когда этот подход не подходит (контрпримеры)

  • Если вы хотите разворачивать масштабируемый набор микросервисов с отдельными процессами для каждого сервиса, запуск нескольких демонов в одном контейнере (через Supervisord) нарушает принцип «один процесс — один контейнер». В таких случаях рекомендуется запускать nginx и php‑fpm в отдельных контейнерах и связать их через сеть Docker или docker‑compose.
  • Если вам критична безопасность и минимальный вектор атаки, лучше использовать минимальные официальные образы, а не полный Ubuntu с apt.

Альтернативные подходы

  • Docker Compose: описать сервисы nginx и php‑fpm как отдельные сервисы в docker‑compose.yml и запускать их вместе с docker-compose up —d. Это улучшит масштабируемость и управление.
  • Официальные образы: использовать официальные образы nginx и php:fpm и настроить их взаимодействие — это уменьшит объем собственных конфигураций и облегчит обновления.
  • Multi‑stage builds: полезно при сборке приложений, где сборочные зависимости можно убрать в финальный слой.

Совместимость и миграция

  • Ubuntu 16.04 — относительно старая база; при подготовке к долгосрочной эксплуатации рассмотрите переход на более новые LTS‑релизы или официальные образы PHP/Nginx.
  • Версии PHP и путей к сокетам (php7.0, /run/php/php7.0-fpm.sock) зависят от дистрибутива и версии PHP. При миграции на PHP 7.2+ обновите пути и имена пакетов.

Отладка — набор команд

  • Просмотреть логи контейнера:
docker logs hakase
  • Выполнить команду внутри контейнера для диагностики:
docker exec -it hakase /bin/bash
ps aux | grep nginx
cat /var/log/nginx/error.log
  • Проверить, что сокет PHP‑FPM существует:
ls -l /run/php

Шаблоны и сниппеты (cheat sheet)

  • Быстрая сборка и запуск в одной строке (локально):
docker build -t nginx_image . && docker run -d -v $(pwd)/webroot:/var/www/html -p 80:80 --name hakase nginx_image
  • Остановить и удалить контейнер + образ:
docker stop hakase && docker rm hakase && docker rmi nginx_image

Краткое резюме

  • Вы написали Dockerfile, установили Nginx, PHP‑FPM и Supervisord, подготовили конфигурации и проверили работу контейнера.
  • Для продакшн‑среды рассмотрите разделение процессов по контейнерам, улучшение безопасности, фиксацию версий и сканирование образов.

Ссылки для справки:

Важно: постоянно проверяйте совместимость версий и обновляйте базовые образы, когда это требуется.

Итоговые ключевые шаги

  • Подготовка файлов (Dockerfile, default, supervisord.conf, start.sh).
  • Сборка образа: docker build -t nginx_image .
  • Запуск контейнера: docker run -d -v /webroot:/var/www/html -p 80:80 –name hakase nginx_image
  • Тестирование: curl и просмотр phpinfo().
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Несколько аккаунтов Skype: Multi Skype Launcher
Программное обеспечение

Несколько аккаунтов Skype: Multi Skype Launcher

Журнал для работы: повысить продуктивность
Productivity

Журнал для работы: повысить продуктивность

Персональные звуки уведомлений на Android
Android.

Персональные звуки уведомлений на Android

Скачивание шоу Hulu для офлайн‑просмотра
Стриминг

Скачивание шоу Hulu для офлайн‑просмотра

Microsoft Start: персонализированная новостная лента
Новости

Microsoft Start: персонализированная новостная лента

Как изменить имя в Epic Games быстро
Гайды

Как изменить имя в Epic Games быстро