Запуск 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 будет равно числу ядер
events worker_connections 1024; Каждый рабочий процесс обрабатывает до 1024 соединений одновременно
http include /etc/nginx/mime.types; Подключает конфиг "mime.types" с описаниями возможных MIME типов (типов файлов)
http default_type application/octet-stream; Если nginx не может определить MIME тип контента, отдавать "application/octet-steam" (бинарный файл)
http include /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 — стандартный поток ошибок
http access_log /dev/fd/1 main; Выводим лог запросов в stdout — стандартный поток вывода
http include /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;
    }
}

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

Контекст Директива Эффект
server listen 80; nginx слушает порт 80 контейнера (протокол IPv4)
server listen [::]:80; nginx слушает порт 80 контейнера (протокол IPv6)
server server_name localhost atdd.lan atdd.ru; Данный server используется, если заголовок Host в запросе совпадает с одним из перечисленных — localhost, atdd.lan, atdd.ru
server root /app/public; Относительные пути считать от каталоге /app/public в контейнере — а docker-compose монтирует каталог public/ проекта в /app/public контейнера
server location / {} Правило обработки любых HTTP-запросов, не обработанных другими правилами location
location index 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 позволит выводить логи непрерывно