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>