引言
有时想在运行的容器中再添加一个端口,特别是使用 nginx docker
时,刚开始没有预留足够的端口映射,后来又要添加几个项目,还不想启动多个nginx的容器,那么就一心想添加几个端口映射。
比如我想添加 宿主机的 [18080] 到 docker 的 [8080] 端口。
方法一:删除原来容器,重新run一个容器。
记得重新run容器的时候将需要映射的端口加上;这种方法只适合没有状态的容器或者没有持久化的容器,毕竟重建后的容器是一个全新的,之前配置的东西全还原了。也可以将之前容器中的数据通过docker cp命令拷贝出来,再拷贝进新的容器中。
优缺点:优点是简单快捷,在测试环境使用较多。缺点是如果是数据库镜像,那重新建一个又要重新配置一次,就比较麻烦了。
方法二:修改容器的配置文件,需要重启docker进程
要修改 /var/lib/docker/containers/[containerId]
目录下,hostconfig.json
和 config.v2.json
两个配置文件。
1.停止docker 服务
一定要先停 docker 服务,要不修改无效,还会被刷回去。
systemctl stop docker
执行 systemctl stop docker
后提示“Warning: Stopping docker.service, but it can still be activated by: docker.socket”
这是docker在关闭状态下被访问自动唤醒机制,很人性化,即这时再执行任意docker命令会直接启动
注:如果真的不希望docker被访问自动唤醒,执行 systemctl stop docker
后再执行systemctl stop docker.socket
即可
停止 docker 服务,所有的 docker 容器也自动停了。
2. 修改配置文件
容器的配置文件:/var/lib/docker/containers/[hash_of_the_container]/hostconfig.json
容器的配置文件:/var/lib/docker/containers/[hash_of_the_container]/config.v2.json
其中的hash of the container是docker镜像的hash值,可以通过docker ps或者docker inspect containername查看。(CONTAINER ID就可以看出来)
根据你的实际容器id去查找
2.1 修改 hostconfig.json文件
hostconfig.json
文件用于描述容器与宿主机之间的交互信息,包括端口映射、挂载卷等。其中的 PortBindings
字段指定容器内部端口与宿主机端口的映射关系,用于实现容器内部服务的外部访问。
只需给 PortBindings 选项添加一项 “8080/tcp”:[{“HostIp”:””,”HostPort”:”18080″}]
{ # ... 省略其他不相关 "PortBindings":{ "22/tcp":[{"HostIp":"","HostPort":"5022"}], # 添加新的映射代码 "8080/tcp":[{"HostIp":"","HostPort":"18080"}] }, # ... 省略其他不相关 }
2.2 修改config.v2.json 文件
config.v2.json
文件用于描述容器的配置信息,包括容器的命令、环境变量、暴露的端口等。其中的 Ports
字段指定容器内部正在监听的端口,但并不表示这些端口会映射到宿主机上。
# ... 省略其他不相关 # 对外暴露端口 "ExposedPorts":{ "22/tcp":{}, # 添加新的映射代码 "8080/tcp":{} } # ... 省略其他不相关 # 如果Ports字段本来就是空,那就不用修改 "Ports": { "22/tcp": [{"HostIp": "0.0.0.0","HostPort": "5022"}], # 添加新的映射代码 "8080/tcp": [{"HostIp": "0.0.0.0","HostPort": "18080"}], } # ... 省略其他不相关
docker 配置文件 config.v2.json 中 Ports 和 hostconfig.json 中 PortBindings 区别: config.v2.json 主要用于描述容器的配置信息,Ports 字段用于指定容器内部正在监听的端口,即容器内的端口。因为 ExposedPorts 字段已经对外暴露了端口,所以如果宿主机所有ip都可以映射到暴露的端口,那么此处 Ports 字段就可以为空。如果需要设置对应的IP那么就应该设置。 hostconfig.json 主要用于描述容器与宿主机之间的交互信息, PortBindings 字段用于指定容器内部端口与宿主机端口的映射关系,用于实现容器内部服务的外部访问。 由于 Ports 和 PortBindings 都涉及容器的端口映射,有时候可能会造成一些冗余和混淆。一般来说,在 Docker 中,推荐使用 PortBindings 来指定容器的端口映射,而将 config.v2.json 中的 Ports 字段留空或不指定。这样可以更清晰地表达容器与宿主机之间的端口映射关系,减少重复配置。
优缺点:这个方法的优点是没有副作用,操作简单。缺点是需要重启整个docker服务,如果在同一个宿主机上运行着多个容器服务的话,就会影响其他容器服务。
3.重启 docker服务
systemctl restart docker
方法三:使用docker commit将当前容器创建为一个镜像,在启动这个镜像时映射新的端口号出来。
docker commit:把一个容器的文件改动和配置信息commit到一个新的镜像。这个在测试的时候会非常有用,把容器所有的文件改动和配置信息导入成一个新的docker镜像,然后用这个新的镜像重起一个容器,这对之前的容器不会有任何影响。
1、停止docker容器
docker stop container01
2、commit该docker容器
docker commit container01 new_image:tag
3、用前一步新生成的镜像重新起一个容器
docker run --name container02 -p 80:80 new_image:tag
优缺点:这种方式的优点是不会影响统一宿主机上的其他容器,缺点是管理起来显得比较乱,没有第二种方法那么直观。