Запуск 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
есть:
- Основной конфиг
/etc/nginx/nginx.conf
- Подкаталог
/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;
}
Как видим, файл состоит из:
- Контекстов (блоков), ограниченных фигурными скобками — events { ... }, http { ... }
- Директив — например,
sendfile on;
- Комментариев — например,
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-запросы следующим образом:
- Из URL извлекается URLPath
- Если такому URLPath соответствует какой-либо файл в root (в нашем случае это каталог "public/" проекта), то nginx отдаст его содержимое
- Иначе 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 позволит выводить логи непрерывно |