Урок 4. Запуск сервиса: порты, переменные, имя и перезапуск
В прошлом уроке Nginx работал в контейнере, но открыть его в браузере было нельзя. В этом уроке — всё, что превращает контейнер в настоящий сервис: порт снаружи, настройки, понятное имя и автоматический запуск после перезагрузки сервера.
Сервис одной командой
Удалите контейнер из прошлого урока, если он остался, и запустите Nginx заново:
docker rm -f web
docker run -d --name web -p 8080:80 --restart unless-stopped nginx:alpineОткройте в браузере http://localhost:8080 (на сервере — http://адрес-сервера:8080): появится страница «Welcome to nginx!». Проверить можно и из терминала:
$ curl -I http://localhost:8080
HTTP/1.1 200 OKНиже ответа будут ещё заголовки, среди них Server: nginx/… с номером версии. Разберём ключи по одному.
-d и --name
-d— работать в фоне. Без него терминал занят выводом Nginx, аCtrl+Cостановит контейнер.--name web— имя контейнера. По имени удобно обращаться:docker logs web,docker stop web. Имя должно быть уникальным: второй контейнер с именемwebне создастся, пока не удалён первый — Docker ответит ошибкойConflict. The container name "/web" is already in use.
-p: порт снаружи
У каждого контейнера своя сеть, и порты внутри него снаружи не видны. Ключ -p (publish — опубликовать) связывает порт хоста с портом контейнера:
-p 8080:80
│ └── порт внутри контейнера (его слушает Nginx)
└─────── порт на хосте (к нему подключаются снаружи)Порядок важен: сначала порт хоста, потом порт контейнера. Какой порт слушает программа в контейнере, написано в описании образа на Docker Hub: у Nginx — 80, у PostgreSQL — 5432, у MariaDB и MySQL — 3306.
Варианты записи:
| Запись | Что значит |
|---|---|
-p 8080:80 | порт 8080 на всех адресах хоста → порт 80 контейнера |
-p 80:80 -p 443:443 | несколько портов — несколько ключей -p |
-p 127.0.0.1:8080:80 | порт доступен только с самого хоста |
-p 192.168.1.10:8080:80 | порт только на одном адресе хоста |
-p 5353:53/udp | порт UDP (без /udp — TCP) |
Какие порты опубликованы у работающего контейнера, показывает docker port web.
Опубликованный порт доступен не только с хоста, но и всем, кто может достучаться до сервера по сети. На Linux Docker открывает такие порты своими правилами брандмауэра — в обход ufw: запрет в ufw их не закроет. Порты баз данных и панелей управления публикуйте только на 127.0.0.1 или не публикуйте вовсе. Подробно — в справке Docker открывает порты в обход ufw.
-e: настройки через переменные
Большинство образов настраиваются переменными окружения: пароль базы, имя пользователя, режим работы. Их передают ключом -e (environment). Пример — PostgreSQL 18, которому при первом запуске нужен пароль суперпользователя:
docker run -d --name db -e POSTGRES_PASSWORD=Smena-Parol-2026 --restart unless-stopped postgres:18Пароль в примере придумайте свой.
Какие переменные понимает образ, перечислено в его описании на Docker Hub. У PostgreSQL обязательна только POSTGRES_PASSWORD, а POSTGRES_USER и POSTGRES_DB создают своего пользователя и базу.
Проверьте, что база запустилась, и подключитесь к ней изнутри контейнера:
docker logs db
docker exec -it db psql -U postgresВ логах должна появиться строка database system is ready to accept connections. Вторая команда запускает консоль psql внутри работающего контейнера; выход — \q. Команда docker exec подробно разобрана в справке Как зайти в контейнер.
Когда переменных много, их держат в файле — по одной ИМЯ=значение в строке, например в db.env, — и передают целиком:
POSTGRES_PASSWORD=Smena-Parol-2026
POSTGRES_USER=app
POSTGRES_DB=appdocker run -d --name db --env-file ./db.env postgres:18Переменные контейнера видны любому, кто может выполнить docker inspect. Файл с паролями не кладите в git и не отправляйте в чаты; права на него — только для владельца: chmod 600 db.env.
Файлы базы у этого контейнера пока лежат в анонимном томе (томе без имени, который Docker создал сам): новый контейнер его не подхватит, и после пересоздания база окажется пустой. Как хранить данные правильно — в следующем уроке.
--restart: запуск после перезагрузки
Без --restart контейнер, упавший с ошибкой или остановленный перезагрузкой сервера, так и останется лежать. Политика перезапуска говорит Docker, что делать:
| Значение | Поведение |
|---|---|
no | не перезапускать (по умолчанию) |
on-failure | перезапускать, только если программа завершилась с ошибкой (код не 0) |
always | перезапускать всегда; остановленный вручную — поднимется после перезапуска Docker |
unless-stopped | как always, но остановленный вручную контейнер остаётся остановленным |
Для сервисов обычно берут unless-stopped: сервер перезагрузился — контейнер поднялся сам, а если вы остановили его командой docker stop, он не оживёт неожиданно. Политику работающего контейнера можно поменять без пересоздания: docker update --restart unless-stopped web.
Порядок в команде
Всё, что стоит до имени образа, — ключи Docker. Всё, что после, — команда и её аргументы для программы внутри контейнера:
docker run -d --name web -p 8080:80 nginx:alpine
docker run --rm alpine ls -l /etcВ первой строке все ключи относятся к Docker. Во второй ls -l /etc выполнится внутри контейнера. Ошибка новичка — docker run nginx:alpine -p 8080:80: здесь -p 8080:80 уйдёт программе в контейнере, а не Docker, и порт не откроется.
Как поменять параметры
Порты, переменные и тома задаются при создании контейнера, и у готового контейнера их не поменять. Порядок такой: удалить контейнер и создать заново с новыми ключами.
docker rm -f web
docker run -d --name web -p 8081:80 --restart unless-stopped nginx:alpineПоэтому команды запуска стоит сохранять — в заметках, в скрипте или, лучше всего, в файле Docker Compose (урок Docker Compose). Данные при этом не теряются, если они в томе.
Коротко
-d— в фоне,--name— своё имя,--restart unless-stopped— подниматься после перезагрузки.-p хост:контейнерпубликует порт;-p 127.0.0.1:…— только для самого хоста.- Опубликованные порты Docker открывает в обход ufw — базы и панели наружу не публикуйте.
-e ИМЯ=значениеи--env-fileпередают настройки; какие нужны — в описании образа.- Ключи Docker — до имени образа, команда для контейнера — после.
- Чтобы поменять порты или переменные, контейнер пересоздают.