Запуск nginx в docker-compose

Запуск nginx в docker-compose #

Используем docker для локального запуска nginx.

Docker образ nginx и его содержимое #

Docker Hub предоставляет готовые docker образы nginx.

Допустим, мы будем использовать версию nginx 1.27.4, выпущенную в феврале 2025.

Для начала обследуем, как устроен docker образ. Для этого запустим контейнер с nginx с командой bash:

docker run -it --rm nginx:1.27.4 bash

Теперь перейдём в каталог конфигурации nginx и проверим его содержимое:

cd /etc/nginx
ls -lah

Увидим, что в каталоге /etc/nginx есть:

  1. Основной конфиг /etc/nginx/nginx.conf
  2. Подкаталог /etc/nginx/conf.d/, где находятся дополнительные файлы конфигурации

Если вывести основной конфиг командой cat nginx.conf, то мы увидим:

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

Как видим, файл состоит из:

  1. Контекстов (блоков), ограниченных фигурными скобками — events { … }, http { … }
  2. Директив — например, sendfile on;
  3. Комментариев — например, gzip on

Объяснение директив в этом файле:

КонтекстДирективаЭффект
user nginx;Запускать nginx под Unix пользователем nginx
worker_processes auto;Число рабочих процессов nginx будет равно числу ядер
eventsworker_connections 1024;Каждый рабочий процесс обрабатывает до 1024 соединений одновременно
httpinclude /etc/nginx/mime.types;Подключает конфиг “mime.types” с описаниями возможных MIME типов (типов файлов)
httpdefault_type application/octet-stream;Если nginx не может определить MIME тип контента, отдавать “application/octet-steam” (бинарный файл)
httpinclude /etc/nginx/conf.d/*.conf;Подключить все файлы *.conf из каталога /etc/nginx/conf.d

Запуск в docker-compose со своими конфигами #

Мы будем запускать docker контейнер с nginx с монтированием (mount) своих конфигов.

Предполагаемая структура файлов проекта (вы можете её поменять):

ПутьОписание
docker-compose.ymlКонфигурация docker-compose
public/Каталог файлов, раздаваемых веб-сервером — его мы укажем в директиве root в нашем конфиге nginx
src/nginx/Каталог с нашей конфигурацией nginx
src/nginx/nginx.confОсновной файл нашей конфигурации nginx
src/nginx/conf.d/Каталог дополнительных файлов конфигурации nginx
src/nginx/ssl/Каталог SSL сертификатов и приватных ключей

Файл docker-compose.yml #

Создадим файл docker-compose.yml и опишем в нём один docker контейнер с nginx:

version: '3'

services:
  atdd-ru-ingress:
    container_name: atdd-ru-ingress
    image: nginx:1.27.4
    volumes:
      - ./public:/app/public:ro
      - ./src/nginx/conf.d:/etc/nginx/conf.d:ro
      - ./src/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./src/nginx/ssl:/etc/nginx/ssl:ro
    ports:
      - "127.0.0.1:80:80"
      - "127.0.0.1:443:443"

Объяснение конфигурации:

ПараметрЭффект
container_name: atdd-ru-ingressконтейнер будет иметь имя atdd-ru-ingress (можно поменять)
image: nginx:1.27.4контейнер будет запущен из образа nginx:1.27.4
volumes:монтирование файлов/каталогов в формате “путь-на-хосте:путь-в-контейнере:ro”, где “:ro” означает, что файл/каталог будет read-only для контейнера
ports:привязка портов в формате “127.0.0.1:порт-на-хосте:порт-в-контейнере”, где префикс “127.0.0.1:” блокирует доступ к этому порту из других машин сети

Каталог public #

В каталоге public можно разместить какой-нибудь файл index.html, например:

<!DOCTYPE html>
<html lang="ru">

<head>
    <meta charset="utf8" />
    <title>Проверочный сайт</title>
    <meta name="viewport" content="width=device-width" />
<body>
    <h1>Теперь nginx работает!</h1>
</body>

</html>

Каталог src/nginx/ #

В каталоге с нашей конфигурацией nginx создадим файл nginx.conf с таким содержимым:

user  nginx;
worker_processes 2;

error_log stderr warn;
pid /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    access_log /dev/fd/1 main;

    sendfile on;

    keepalive_timeout 65;

    include /etc/nginx/conf.d/*.conf;
}

Объяснение директив в этом файле:

КонтекстДирективаЭффект
worker_processes 2;Оставляем 2 рабочих процесса nginx (каждый обрабатывает до 1024 соединений одновременно)
error_log stderr warn;Выводим лог ошибок в stderr — стандартный поток ошибок
httpaccess_log /dev/fd/1 main;Выводим лог запросов в stdout — стандартный поток вывода
httpinclude /etc/nginx/conf.d/*.conf;Подключить все файлы *.conf из каталога /etc/nginx/conf.d

Теперь создадим в каталоге src/nginx/conf.d/ файл с конфигурацией хоста — можно назвать его, например, atdd_ru.conf:

server {
    listen 80;
    listen [::]:80;

    server_name localhost atdd.lan atdd.ru;

    root /app/public;

    location / {
        index index.html;
    }
}

Объяснение директив в этом файле:

КонтекстДирективаЭффект
serverlisten 80;nginx слушает порт 80 контейнера (протокол IPv4)
serverlisten [::]:80;nginx слушает порт 80 контейнера (протокол IPv6)
serverserver_name localhost atdd.lan atdd.ru;Данный server используется, если заголовок Host в запросе совпадает с одним из перечисленных — localhost, atdd.lan, atdd.ru
serverroot /app/public;Относительные пути считать от каталоге /app/public в контейнере — а docker-compose монтирует каталог public/ проекта в /app/public контейнера
serverlocation / {}Правило обработки любых HTTP-запросов, не обработанных другими правилами location
locationindex index.htmlЕсли URLPath равен “/”, то отдавать index.html

В данном случае блок location обрабатывает любые HTTP-запросы следующим образом:

  1. Из URL извлекается URLPath
  2. Если такому URLPath соответствует какой-либо файл в root (в нашем случае это каталог “public/” проекта), то nginx отдаст его содержимое
  3. Иначе nginx отдаст страницу 404-й ошибки

Блоки location в nginx имеют свой особенный синтаксис — подробное описание вариантов location с примерами можно найти в Интернете.

Запуск #

В актуальных версиях Docker уже есть встроенный docker-compose, поэтому мы запустим контейнеры так:

docker compose up

В браузере можно открыть адрес http://localhost/ — в результате вы увидите содержимое index.html.

Другие команды docker-compose:

КомандаЧто делает
docker compose up -dЗапуск в фоновом режиме — команда не будет занимать терминал
docker-compose downОстановка и удаление контейнеров
docker-compose psПроверка состояния контейнеров
docker-compose logВывод логов контейнеров — а флаг -f позволит выводить логи непрерывно

Сайт atdd.ru — блог разработчика.