我不确定我是否在这里误解了一些内容,但似乎只能通过从图像创建一个新容器来设置端口映射。有没有办法将端口映射分配给现有的Docker容器?
答案 0 :(得分:378)
我也对这个问题感兴趣。
如上所述@Thasmo,只能使用docker run
命令指定端口转发
其他命令docker start
没有-p
选项,docker port
仅显示当前转发。
要添加端口转发,我始终按照以下步骤操作
答案 1 :(得分:203)
您可以通过直接编辑hostconfig.json
文件来更改端口映射
/var/lib/docker/containers/[hash_of_the_container]/hostconfig.json
您可以通过docker inspect <container_name>
命令以及&#34; Id&#34;的值来确定[hash_of_the_container]。字段是哈希。
1) stop the container
2) stop docker service (per Tacsiazuma's comment)
3) change the file
4) restart your docker engine (to flush/clear config caches)
5) start the container
因此,您不需要使用此方法创建图像。您也可以在此处更改重启标志。
P.S。您可以访问https://docs.docker.com/engine/admin/以了解如何根据主机正确重启docker引擎。我使用sudo systemctl restart docker
重新启动在Ubuntu 16.04上运行的docker引擎
答案 2 :(得分:26)
如果“现有”是指“正在运行”,那么(目前)无法添加端口映射。
但是,您可以动态添加新网络接口,例如Pipework,如果您需要在正在运行的容器中公开服务而不停止/重新启动它。
答案 3 :(得分:16)
不确定是否可以将端口映射应用于正在运行的容器。您可以在运行与创建新容器不同的容器时应用端口转发。
$ docker run -p <public_port>:<private_port> -d <image>
将开始运行容器。 This tutorial解释了端口重定向。
答案 4 :(得分:13)
在Fujimoto Youichi的例子test01
是一个容器,而test02
是一个图像。
在执行docker run
之前,您可以删除原始容器,然后再次为容器指定相同的名称:
$ docker stop container01
$ docker commit container01 image01
$ docker rm container01
$ docker run -d -P --name container01 image01
(使用-P
将端口暴露给随机端口而不是手动分配。
答案 5 :(得分:8)
编辑 hostconfig.json 似乎现在无法正常工作。它只会以暴露但未发布到主机的端口结束。承诺和重新创建容器对我来说不是最好的方法。没有人提到docker network
?
最佳解决方案是在同一网络中使用反向代理
如果您之前的容器不在任何已命名的容器中,请创建一个新网络。
docker network create my_network
将现有容器加入创建的网络
docker network connect my_network my_existing_container
启动反向代理服务(例如nginx),发布您需要的端口,加入同一网络
docker run -d --name nginx --network my_network -p 9000:9000 nginx
可选择删除nginx中的 default.conf
docker exec nginx rm /etc/nginx/conf.d/default.conf
创建新的nginx配置
server
{
listen 9000;
location / {
proxy_pass http://my_existing_container:9000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
将配置复制到nginx容器。
docker cp ./my_conf.conf nginx:/etc/nginx/conf.d/my_conf.conf
重新启动nginx
docker restart nginx
优点:要发布新端口,您可以根据需要安全地停止/更新/重新创建nginx容器,而无需触及业务容器。如果nginx需要零停机时间,则可以添加更多反向代理服务加入同一网络。此外,容器可以加入多个网络。
编辑:
要反向代理非http服务,配置文件有点不同。这是一个简单的例子:
upstream my_service {
server my_existing_container:9000;
}
server {
listen 9000;
proxy_pass my_service;
}
答案 6 :(得分:6)
如果你运行docker run <NAME>
,它会产生一个新图像,这很可能不是你想要的。
如果要更改当前图像,请执行以下操作:
docker ps -a
获取目标容器的ID并转到:
cd /var/lib/docker/containers/<conainerID><and then some:)>
停止容器:
docker stop <NAME>
更改文件
vi config.v2.json
"Config": {
....
"ExposedPorts": {
"80/tcp": {},
"8888/tcp": {}
},
....
},
"NetworkSettings": {
....
"Ports": {
"80/tcp": [
{
"HostIp": "",
"HostPort": "80"
}
],
并更改档案
vi hostconfig.json
"PortBindings": {
"80/tcp": [
{
"HostIp": "",
"HostPort": "80"
}
],
"8888/tcp": [
{
"HostIp": "",
"HostPort": "8888"
}
]
}
重新启动您的泊坞窗,它应该可以正常工作。
答案 7 :(得分:6)
# list all containers
$ docker ps -a
$ docker stop docker101tutorial
# Use grep or rg to get Id of container
$ docker inspect docker101tutorial | grep -i id
"Id": "sha256:fff0a4b22d6f3d2eb8d2748b8a8bbc9967ea87199988acee8e86ac70bce9c3eb",
# run plain ubuntu docker image with shell and change it's namespace to docker host
# https://stackoverflow.com/questions/60408574/how-to-access-var-lib-docker-in-windows-10-docker-desktop/60411313#60411313
# https://forums.docker.com/t/the-location-of-images-in-docker-for-windows/19647/4
$ docker run -it --privileged --pid=host ubuntu nsenter -t 1 -m -u -i sh
# We want to find out the directory of docker101tutorial container. We are looking for:
# `"Image":"sha256:fff0a4b22d6f3d2eb8d2748b8a8bbc9967ea87199988acee8e86ac70bce9c3eb"`
# in /var/lib/docker/containers/*/config.v2.json
$ grep -rl --include=config.v2.json fff0a4b22d /var/lib/docker/containers/
/var/lib/docker/containers/c1eda20b30f058bce9f8ece3b47a21641df5b399770e12ab57416a954d3c8bbf/config.v2.json
# edit it
$ vi /var/lib/docker/containers/c1eda20b30f058bce9f8ece3b47a21641df5b399770e12ab57416a954d3c8bbf/hostconfig.json
i
进入插入模式。"HostPort":"80"
更改为"HostPort":"8092"
Escape
并输入:wq
。按Enter
。docker101tutorial
。否则,对HostPort
的更改将被还原。8092
。8092
。基于@holdfenytolvaj答案。
答案 8 :(得分:4)
我们使用诸如ssh之类的方便工具来轻松完成此操作。
我正在使用ubuntu主机和基于ubuntu的docker映像。
当需要映射新端口时,
在docker内部运行以下命令
ssh -R8888:localhost:8888 <username>@172.17.0.1
172.17.0.1是docker接口的ip
(您可以通过运行
ifconfig docker0 | grep "inet addr" | cut -f2 -d":" | cut -f1 -d" "
在主机上)。
在这里,我将本地8888端口映射回了主机8888。您可以根据需要更改端口。
如果您还需要一个端口,则可以杀死ssh并使用新端口向其添加-R一行。
我已经用netcat测试过了。
答案 9 :(得分:2)
如果你对Docker深度配置不满意,那么你的另一种方式就是你的朋友。
iptables -t nat -A DOCKER -p tcp --dport ${YOURPORT} -j DNAT --to-destination ${CONTAINERIP}:${YOURPORT}
iptables -t nat -A POSTROUTING -j MASQUERADE -p tcp --source ${CONTAINERIP} --destination ${CONTAINERIP} --dport ${YOURPORT}
iptables -A DOCKER -j ACCEPT -p tcp --destination ${CONTAINERIP} --dport ${YOURPORT}
这只是一个不适合我的方案的推荐方法,因为我无法阻止容器,我希望也会帮助你。
答案 10 :(得分:2)
/var/lib/docker/containers/${container_id}
目录并编辑hostconfig.json
PortBindings.HostPort
您要进行的更改。答案 11 :(得分:0)
作为response的@Fujimoto-Youichi的补充
在创建容器时,您也可以使用$ docker run -P CONTAINER
随机映射端口,但要注意安全性!
-P
对--publish-all
的等效项:“它将所有公开的端口发布到随机端口”,
然后运行docker inspect CONTAINER
来查找端口映射,如下图所示:
在docker run中了解有关docker run -P
的更多信息
答案 12 :(得分:0)
简短的回答:您无法将端口映射分配给现有的Docker容器
答案 13 :(得分:0)
我正在开发一个 dockerizer go 包,用于在 docker 容器中部署批处理应用程序。我的包包含一个 MessageBroker 组件,该组件具有 3 个要发布的端口:jobAgentPort、backendPort、frontendPort。
我将长话短说,建议最好设计一个嵌入到服务器/代理/代理中的 endpointProvider 组件。
也就是说,容器部署至少是一个 2 步过程。
例如 server/proxy/broker 构造函数有一个签名:
NewMessageBroker(epc *EndpointConfig) *MessageBroker
。然后,使用 docker-client api 创建容器映像,最后启动容器 (docker run) 并使用暴露端口值的 endpointConfig 发布端口。
答案 14 :(得分:-2)
"docker run -p 8761:8761 --name
答案 15 :(得分:-3)
如何将端口映射分配给现有的 Docker 容器?
非常简单。有两件事,一是您机器上的本地服务器端口,如 800,8080 等,第二个是您要映射的容器端口。 Docker Port mapping
docker run -p 8080:8080 <Image ID>
要获取图像 ID,您可以使用
docker ps
答案 16 :(得分:-8)
如果您只想更改正在运行的容器的端口,请执行以下操作:
sudo docker stop NAME
sudo docker run -d -p 81:80 NAME
其中:
“ - d”到背景/ deamon the docker
“ - p”启用端口映射
您用浏览器访问的“81”外部(公开)端口
“80”内部docker容器监听端口