概述
创建宿主机与容器的端口映射,可以在docker run
创建并运行容器的时候,通过-p
指定端口映射规则。但是,我本次遇到的情况时在创建容器给新增需求或缺少以及修改部分端口映射的情况。
docker start
运行容器后,并没有提供一个选项或设置可以修改指定的端口映射规则。那么这种情况我们该怎么处理呢?
解决方案
本篇仅记录docker run
相关方法,不涉及到使用docker-compose
。如果你有更好的方法,欢迎留言指正 🙂
重建容器
这种方法比较简单直接,即删除原有的缺少端口映射的容器,重新创建一个指定端口映射规则的容器。由于此方案需要重建容器,所以仅适用于创建镜像后还没开始配置或容器配置简单、配置成本较小的情况。
但我的环境中,已经在Nginx容器里修改、新增了一些配置项。不想再重新来一遍,所以我通过以下方式,先将容器内指定的文件&文件夹复制到本地,待重建容器时再把本地的文件夹、文件挂载到容器中,也为了方便日后直接在本地修改配置文件。
导出容器内的文件及文件夹至本地
# docker cp 容器ID/容器名:容器内的文件或文件夹路径 本地文件夹或文件路径
docker cp ITPro-Nginx02:/usr/share/nginx/html Documents/Docker/Nginx01/
docker cp ITPro-Nginx02:/etc/nginx/nginx.conf Documents/Docker/Nginx01/nginx.conf
docker cp ITPro-Nginx02:/etc/nginx/conf.d Documents/Docker/Nginx01/
docker cp ITPro-Nginx02:/var/log/nginx Documents/Docker/Nginx01/
重建多端口映射的容器
# 重建之前,需要先删除现有的容器
docker rm -f ITPro-Nginx01
# 重建容器, 我这里新映射80、88、89作为示例
docker run -it --name=ITPro-Nginx01 \
-d --restart=always \
-p 8800:80 \
-p 8088:88 \
-p 8089:89 \
-v /home/jason/Documents/Docker/Nginx01/html:/usr/share/nginx/html \
-v /home/jason/Documents/Docker/Nginx01/nginx.conf:/etc/nginx/nginx.conf \
-v /home/jason/Documents/Docker/Nginx01/conf.d:/etc/nginx/conf.d \
-v /home/jason/Documents/Docker/Nginx01/log:/var/log/nginx \
nginx:stable
如果你在测试环境中,想后期随时新增自定义的端口映射,可以将-p 8800:80
替换为一条参数--net host
即可。
修改现有容器的配置文件
# 容器对应目录内包含config.v2.json和hostconfig.json两个配置文件
# 其默认路径为: /var/lib/docker/containers/\[hash_of_the_container\]/hostconfig.json
查看现有容器的配置文件路径
docker inspect ITPro-Nginx01 | grep HostsPath
# "HostsPath": "/var/lib/docker/containers/bccfa701497db030db03f8f80a64bf29036a88407316e76c093063c045781fd4/hosts"
# 这里需要切换为root权限然后访问hosts上一层目录即可
sudo su
cd /var/lib/docker/containers/bccfa701497db030db03f8f80a64bf29036a88407316e76c093063c045781fd4/
停止当前容器并编辑配置文件
# docker stop 容器ID/容器名
docker stop ITPro-Nginx01
# 分别编辑config.v2.json和hostconfig.json两个配置文件
在hostconfig.json
配置文件中修改PortBindings{}
中的内容,参考以下格式添加所需的端口
在config.v2.json
配置文件中需要修改2处,分配ExposedPorts{}
和Ports{}
处
重新启动该容器
# docker start $ContainerName
docker start ITPro-Nginx01
构建自定义镜像
停止当前容器
docker stop ITPro-Nginx01
提交原有docker容器为自定义镜像
通过docker commit
将原有容器及容器中的文件、配置信息commit为新的自定义镜像,然后再通过这个自定义镜像创建容器。在docker run
创建并运行容器的时候,通过-p
指定所需的端口映射规则,具体操作如下:
docker commit [OPTIONS] $container [REPOSITORY[:TAG]]
OPTIONS说明:
-a :提交的镜像作者;
-c :使用Dockerfile指令来创建镜像;
-m :提交时的说明文字;
-p :在commit时,将容器暂停
docker commit -a "Jason" -m "update Nginx ports for ITPro.cc" ITPro-Nginx01 itpro-nginx01:v2
这里需要注意REPOSITORY
参数不能是大写,否则将会出现如下错误
提交成功后,可以通过以下命令查看:
docker image ls
基于自定义镜像创建容器
# docker run -it --name $new_containername -p 80:80 $imagename:tag
docker run -it --name itpro-nginx02 -p 9090:90 -p 9443:443 itpro-nginx01:v2
到这里,添加指定端口映射的新容器就可以使用了
总结
综上,以上三种方式均可实现为运行中的容器调整端口映射规则,三种方式的优劣对比如下:
- 优势
- 通过删除原有容器并重建新容器的方式实现调整端口,操作简单、直接。
- 修改配置文件的方式没有副作用,无需重新配置容器。
- 通过构建自定义镜像、重建容器的的方式,操作简单且不会影响同一宿主机上的其他容器。
- 劣势
- 方案1重建容器后需要重新配置容器,比较麻烦。
- 方案2修改配置文件后,需要重启整个docker服务,如果在同一个宿主机上运行着多个容器服务的话,会影响其他容器服务。
- 方案3实现方式曲折,在管理上会略显混乱