HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <p><strong>Для взаимодействия с Docker-контейнером с хоста нужно настроить маппинг портов. Разберемся, почему это важно, и рассмотрим несколько способов добавления нового маппинга после запуска Docker-контейнера.</strong></p>
1 <p><strong>Для взаимодействия с Docker-контейнером с хоста нужно настроить маппинг портов. Разберемся, почему это важно, и рассмотрим несколько способов добавления нового маппинга после запуска Docker-контейнера.</strong></p>
2 <p><em>Это адаптированный перевод статьи<a>Assigning a Port Mapping to a Running Docker Container</a>из блога образовательного проекта Baeldung.</em></p>
2 <p><em>Это адаптированный перевод статьи<a>Assigning a Port Mapping to a Running Docker Container</a>из блога образовательного проекта Baeldung.</em></p>
3 <blockquote><p>Эта статья предназначена для разработчиков, которые знают Docker хотя бы на базовом уровне. Если вы еще не знакомы с этой технологией и вам интересно с ней разобраться, пройдите<a>курс по Docker</a>на Хекслете.</p>
3 <blockquote><p>Эта статья предназначена для разработчиков, которые знают Docker хотя бы на базовом уровне. Если вы еще не знакомы с этой технологией и вам интересно с ней разобраться, пройдите<a>курс по Docker</a>на Хекслете.</p>
4 </blockquote><h2>Содержание</h2>
4 </blockquote><h2>Содержание</h2>
5 <ul><li><a>Зачем нужен маппинг</a></li>
5 <ul><li><a>Зачем нужен маппинг</a></li>
6 <li><a>Как назначить маппинг работающему Docker-контейнеру</a></li>
6 <li><a>Как назначить маппинг работающему Docker-контейнеру</a></li>
7 <li><a>Повторный запуск из docker commit</a></li>
7 <li><a>Повторный запуск из docker commit</a></li>
8 <li><a>Перенастройка Docker-контейнера без его удаления</a></li>
8 <li><a>Перенастройка Docker-контейнера без его удаления</a></li>
9 </ul><h2>Зачем нужен маппинг</h2>
9 </ul><h2>Зачем нужен маппинг</h2>
10 <p>По умолчанию Docker запускает сервис изолированно - то есть все порты между хостом и Docker-контейнером закрыты. Для того, чтобы получить доступ к сервису с хоста или из внешней сети, нужно использовать сопоставление портов или маппинг.</p>
10 <p>По умолчанию Docker запускает сервис изолированно - то есть все порты между хостом и Docker-контейнером закрыты. Для того, чтобы получить доступ к сервису с хоста или из внешней сети, нужно использовать сопоставление портов или маппинг.</p>
11 <p>Маппинг нужен для того, чтобы все запросы, проходящие через порт хоста, перенаправлялись в Docker-контейнер. Другими словами, сопоставление портов делает процессы внутри контейнера доступными извне.</p>
11 <p>Маппинг нужен для того, чтобы все запросы, проходящие через порт хоста, перенаправлялись в Docker-контейнер. Другими словами, сопоставление портов делает процессы внутри контейнера доступными извне.</p>
12 <p>При запуске нового Docker-контейнера с помощью команды docker run можно сопоставить порты опцией --publish или -p:</p>
12 <p>При запуске нового Docker-контейнера с помощью команды docker run можно сопоставить порты опцией --publish или -p:</p>
13 <p>Эта команда запускает Docker-контейнер httpd (HTTP-сервер Apache) и маппинг 81 порта хоста с 80 портом внутри Docker-контейнера. Стоит отметить, что по умолчанию сервер httpd прослушивает порт 80.</p>
13 <p>Эта команда запускает Docker-контейнер httpd (HTTP-сервер Apache) и маппинг 81 порта хоста с 80 портом внутри Docker-контейнера. Стоит отметить, что по умолчанию сервер httpd прослушивает порт 80.</p>
14 <p>Теперь доступ к приложению можно получить, используя порт 81 на хосте:</p>
14 <p>Теперь доступ к приложению можно получить, используя порт 81 на хосте:</p>
15 <p>Важно отметить, что выполнять маппинг для всех Docker-контейнеров необязательно. Например, в случаях, когда нужно сохранить службы Docker-контейнера закрытыми или видимыми только родственным контейнерам в той же сети Docker.</p>
15 <p>Важно отметить, что выполнять маппинг для всех Docker-контейнеров необязательно. Например, в случаях, когда нужно сохранить службы Docker-контейнера закрытыми или видимыми только родственным контейнерам в той же сети Docker.</p>
16 <h2>Как назначить маппинг работающему Docker-контейнеру</h2>
16 <h2>Как назначить маппинг работающему Docker-контейнеру</h2>
17 <p>Рассмотрим ситуацию, в которой маппинг не был задан при запуске Docker-контейнера или был задан с ошибкой. Получить доступ к сервису через TCP/IP-соединение на хосте не получится, но есть три способа решить эту проблему:</p>
17 <p>Рассмотрим ситуацию, в которой маппинг не был задан при запуске Docker-контейнера или был задан с ошибкой. Получить доступ к сервису через TCP/IP-соединение на хосте не получится, но есть три способа решить эту проблему:</p>
18 <ul><li><strong>Остановить работающий Docker</strong>-<strong>контейнер</strong>, а затем создать и запустить новый c оригинальным docker images</li>
18 <ul><li><strong>Остановить работающий Docker</strong>-<strong>контейнер</strong>, а затем создать и запустить новый c оригинальным docker images</li>
19 <li><strong>Сделать docker commit работающего Docker-контейнера,</strong>создать новый и запустите его через docker images, сохранив состояние</li>
19 <li><strong>Сделать docker commit работающего Docker-контейнера,</strong>создать новый и запустите его через docker images, сохранив состояние</li>
20 <li><strong>Добавить новый маппинг</strong>, используя файлы конфигурации Docker</li>
20 <li><strong>Добавить новый маппинг</strong>, используя файлы конфигурации Docker</li>
21 </ul><p>Разберем каждый способ подробнее.</p>
21 </ul><p>Разберем каждый способ подробнее.</p>
22 <blockquote><h3>Освойте DevOps на<a>интенсиве Хекслета</a></h3>
22 <blockquote><h3>Освойте DevOps на<a>интенсиве Хекслета</a></h3>
23 <p>Научитесь автоматизировать окружение, деплоить приложения одной кнопкой одновременно на любое количество машин и разворачивать облачный кластер на Digital Ocean или Yandex Cloud.</p>
23 <p>Научитесь автоматизировать окружение, деплоить приложения одной кнопкой одновременно на любое количество машин и разворачивать облачный кластер на Digital Ocean или Yandex Cloud.</p>
24 </blockquote><h3>Перезапуск Docker-контейнера</h3>
24 </blockquote><h3>Перезапуск Docker-контейнера</h3>
25 <p>Это самое технически простое решение: работающий Docker-контейнер удаляется, а вместо него создается новый, запущенный из образа. При создании Docker-контейнера сопоставляются порты.</p>
25 <p>Это самое технически простое решение: работающий Docker-контейнер удаляется, а вместо него создается новый, запущенный из образа. При создании Docker-контейнера сопоставляются порты.</p>
26 <p>Хотя это самый простой способ, он подходит не во всех ситуациях. Например, решение не подойдет в ситуации, когда внутри Docker-контейнера уже выполнены некоторые операции: установились зависимости, запустились процессы или обновились файлы. Если восстановить такой Docker-контейнер из образа, все эти изменения будут потеряны.</p>
26 <p>Хотя это самый простой способ, он подходит не во всех ситуациях. Например, решение не подойдет в ситуации, когда внутри Docker-контейнера уже выполнены некоторые операции: установились зависимости, запустились процессы или обновились файлы. Если восстановить такой Docker-контейнер из образа, все эти изменения будут потеряны.</p>
27 <p>Стоит отметить, что важные данные лучше хранить в<a>Docker volumes</a>, чтобы упростить замену Docker-контейнеров.</p>
27 <p>Стоит отметить, что важные данные лучше хранить в<a>Docker volumes</a>, чтобы упростить замену Docker-контейнеров.</p>
28 <h2>Повторный запуск из docker commit</h2>
28 <h2>Повторный запуск из docker commit</h2>
29 <p>Этот подход предполагает создание нового образа на базе существующего Docker-контейнера. Затем образ можно использовать для запуска нового Docker-контейнера с открытыми нужными портами.</p>
29 <p>Этот подход предполагает создание нового образа на базе существующего Docker-контейнера. Затем образ можно использовать для запуска нового Docker-контейнера с открытыми нужными портами.</p>
30 <p>Поскольку мы фиксируем состояние существующего Docker-контейнера оно становится доступно в новом образе.</p>
30 <p>Поскольку мы фиксируем состояние существующего Docker-контейнера оно становится доступно в новом образе.</p>
31 <p>Попробуем реализовать этот способ. Сначала остановим Docker-контейнер и создадим его образ с помощью команды docker commit:</p>
31 <p>Попробуем реализовать этот способ. Сначала остановим Docker-контейнер и создадим его образ с помощью команды docker commit:</p>
32 <p>Затем удалим Docker-контейнер и заново запустим его из образа. На этом этапе важно убедиться, что маппинг настроен верно:</p>
32 <p>Затем удалим Docker-контейнер и заново запустим его из образа. На этом этапе важно убедиться, что маппинг настроен верно:</p>
33 <h2>Перенастройка Docker-контейнера без его удаления</h2>
33 <h2>Перенастройка Docker-контейнера без его удаления</h2>
34 <p>В подходах, которые обсуждались выше, речь шла об удалении существующего Docker-контейнера и создании нового. Хотя новый Docker-контейнер работает также, его метаданные полностью отличаются.</p>
34 <p>В подходах, которые обсуждались выше, речь шла об удалении существующего Docker-контейнера и создании нового. Хотя новый Docker-контейнер работает также, его метаданные полностью отличаются.</p>
35 <p>Рассмотрим способ, как настроить маппинг в уже существующем Docker-контейнере. Сначала запустим новый без сопоставления портов:</p>
35 <p>Рассмотрим способ, как настроить маппинг в уже существующем Docker-контейнере. Сначала запустим новый без сопоставления портов:</p>
36 <p>Команда docker run возвращает полный идентификатор Docker длиной 64 символа. Другой способ получить его - команда<a>docker inspect</a>:</p>
36 <p>Команда docker run возвращает полный идентификатор Docker длиной 64 символа. Другой способ получить его - команда<a>docker inspect</a>:</p>
37 <p>Идентификатор пригодится для поиска файла конфигурации Docker.</p>
37 <p>Идентификатор пригодится для поиска файла конфигурации Docker.</p>
38 <h3>Остановка Docker-контейнера и службы Docker</h3>
38 <h3>Остановка Docker-контейнера и службы Docker</h3>
39 <p>Первый шаг по перенастройке работающего Docker-контейнера - его остановка. Выполнить ее можно командой docker stop:</p>
39 <p>Первый шаг по перенастройке работающего Docker-контейнера - его остановка. Выполнить ее можно командой docker stop:</p>
40 <p>Для обновления конфигурационных файлов Docker-контейнера нужно остановить и службу Docker. Стоит отметить, что это действие приведет к отключению всех Docker-контейнеров до тех пор, пока процесс настройки не закончится.</p>
40 <p>Для обновления конфигурационных файлов Docker-контейнера нужно остановить и службу Docker. Стоит отметить, что это действие приведет к отключению всех Docker-контейнеров до тех пор, пока процесс настройки не закончится.</p>
41 <h3>Как найти конфигурационные файлы</h3>
41 <h3>Как найти конфигурационные файлы</h3>
42 <p>Все конфигурационные файлы, которые относятся к Docker-контейнерам, образам, томам и сетям Docker, можно найти в каталоге /var/lib/docker. Стоит отметить, что на Windows и MacOS путь к каталогу отличается.</p>
42 <p>Все конфигурационные файлы, которые относятся к Docker-контейнерам, образам, томам и сетям Docker, можно найти в каталоге /var/lib/docker. Стоит отметить, что на Windows и MacOS путь к каталогу отличается.</p>
43 <p>В данном случае интерес представляют два файла: hostconfig.json и config.v2.json. Найти их можно в следующем каталоге:</p>
43 <p>В данном случае интерес представляют два файла: hostconfig.json и config.v2.json. Найти их можно в следующем каталоге:</p>
44 <p>В данном случае ID - полный идентификатор Docker-контейнера, который мы получили ранее:</p>
44 <p>В данном случае ID - полный идентификатор Docker-контейнера, который мы получили ранее:</p>
45 <p>Конфигурационные файлы можно найти в следующем каталоге:</p>
45 <p>Конфигурационные файлы можно найти в следующем каталоге:</p>
46 <h3>Обновление конфигурационных файлов</h3>
46 <h3>Обновление конфигурационных файлов</h3>
47 <p>В первую очередь стоит обновить файл hostconfig.json. Для этого найдем ключ привязки портов в этом файле. Поскольку при запуске Docker-контейнера маппинг не был настроен, поле ключа PortBindings Docker-контейнера будет пустым:</p>
47 <p>В первую очередь стоит обновить файл hostconfig.json. Для этого найдем ключ привязки портов в этом файле. Поскольку при запуске Docker-контейнера маппинг не был настроен, поле ключа PortBindings Docker-контейнера будет пустым:</p>
48 <p>Следующий шаг - назначение 82 порта хоста 80 порту Docker-контейнера httpd-container. Для этого обновим привязки портов в файле JSON:</p>
48 <p>Следующий шаг - назначение 82 порта хоста 80 порту Docker-контейнера httpd-container. Для этого обновим привязки портов в файле JSON:</p>
49 <p>Как только маппинг выполнен, нужно открыть порт 80 Docker-контейнера в файле config.v2.json. Для этого добавим поле открытых портов (если его еще нет) в ключ конфигурации:</p>
49 <p>Как только маппинг выполнен, нужно открыть порт 80 Docker-контейнера в файле config.v2.json. Для этого добавим поле открытых портов (если его еще нет) в ключ конфигурации:</p>
50 <p>Таким образом мы сообщаем демону Docker, что Docker-контейнер прослушивает 80 порт в этом сетевом интерфейсе.</p>
50 <p>Таким образом мы сообщаем демону Docker, что Docker-контейнер прослушивает 80 порт в этом сетевом интерфейсе.</p>
51 <p>Можно открыть несколько портов, передав значения в виде пар ключ-значение, разделенных запятыми:</p>
51 <p>Можно открыть несколько портов, передав значения в виде пар ключ-значение, разделенных запятыми:</p>
52 <h3>Проверка изменений</h3>
52 <h3>Проверка изменений</h3>
53 <p>Проверка изменений состоит из нескольких шагов. Сначала запустим службу Docker:</p>
53 <p>Проверка изменений состоит из нескольких шагов. Сначала запустим службу Docker:</p>
54 <p>Теперь запустим httpd-контейнер и проверим маппинг портов с помощью команды docker ps:</p>
54 <p>Теперь запустим httpd-контейнер и проверим маппинг портов с помощью команды docker ps:</p>
55 <p>Из результата выполнения команды видно, что порты Docker-контейнера теперь сопоставлены с портами хоста. После этого доступ к службе httpd Docker-контейнера можно получить извне - через 82 порт:</p>
55 <p>Из результата выполнения команды видно, что порты Docker-контейнера теперь сопоставлены с портами хоста. После этого доступ к службе httpd Docker-контейнера можно получить извне - через 82 порт:</p>
56 <p>При таком подходе идентификатор Docker-контейнера и все выполненные в нем настройки сохраняются, поскольку исходный контейнер не заменяется новым.</p>
56 <p>При таком подходе идентификатор Docker-контейнера и все выполненные в нем настройки сохраняются, поскольку исходный контейнер не заменяется новым.</p>
57 <p>Изменить существующие маппинги любого Docker-контейнера можно используя процедуру, описанную выше. Единственное отличие будет заключаться в том, что ключ привязки портов в файле hostconfig.json не будет пустым. В этом случае достаточно просто обновить номер используемого порта.</p>
57 <p>Изменить существующие маппинги любого Docker-контейнера можно используя процедуру, описанную выше. Единственное отличие будет заключаться в том, что ключ привязки портов в файле hostconfig.json не будет пустым. В этом случае достаточно просто обновить номер используемого порта.</p>
58 <p>При обновлении TCP-порта Docker-контейнера в маппинге необходимо указать тот же порт в файле config.v2.json.</p>
58 <p>При обновлении TCP-порта Docker-контейнера в маппинге необходимо указать тот же порт в файле config.v2.json.</p>
59 <p>Теперь все проверки прошли - можно запустить службу Docker и Docker-контейнер, чтобы изменения вступили в силу.</p>
59 <p>Теперь все проверки прошли - можно запустить службу Docker и Docker-контейнер, чтобы изменения вступили в силу.</p>