re publish docker port for docker, do not need STOP container and docker.
- 如果你运行了一个容器
docker network create mynet
docker run -d --name nginx --net mynet nginx
- 这个时候,你本地执行
curl http://localhost:80/
是失败的 - 当你想将这个nginx容器中的80端口,映射到本地主机的80端口的时候
- 你必须停止这个容器,重新运行命令
# 停止nginx容器
docker stop nginx
# 删除nginx容器
docker rm ngiinx
# 重新启动nginx容器,并且指定端口映射
docker run -d --name nginx --net mynet -p 80:80 nginx
- 当你重新启动nginx容器后,你在本地主机才可以
# 现在可以成功了
curl http://localhost:80/
- 主流办法1:停止旧容器,重新启动新容器并指定-p参数
- 主流办法2:找到nginx容器定义文件,修改定义文件,停止容器,并重启docker引擎,重启容器,参考:https://github.com/williamclarkmcbride/DockerPortRemapper
- 由于原来的作者 phyllisstein/port-forward:latest 只提供了arm镜像,因此我重做了镜像
- 最佳解决方案,jasonhu2019/port-forward:latest, 使用socat做转发
docker run --restart always -d --net mynet -e REMOTE_HOST=nginx -e REMOTE_PORT=80 -p 80:80 jasonhu2019/port-forward:latest
- 在docker中,转发的主机,如果是同一个
自定义网络
,可以通过容器名字
和containerid
,作为主机的名字解析到ip- 注意,docker缺省的
bridge
网络,是不启用Docker DNS内置机制的,无法通过容器名字和id访问到。 - 如果容器使用的bridge缺省网络,则REMOTE_HOST,只能使用容器自身的IP来指定
- 注意,docker缺省的
- 确保新的容器,和需要通讯的容器,在同一个
容器网络
中,如果不制定网络,docker run的容器,都在bridge
网络中
- 使用 socat 通用工具做转发,封装为容器,7.1M,phyllisstein/port-forward:latest
- docker hub 上提供多架构的镜像 jasonhu2019/port-forward:latest
FROM alpine:latest
# 定义构建时变量
ARG DEF_REMOTE_PORT=80
ARG DEF_LOCAL_PORT=80
# 设置环境变量
ENV REMOTE_PORT=${DEF_REMOTE_PORT} LOCAL_PORT=${DEF_LOCAL_PORT}
# 安装基础包
RUN echo "Installing base packages" \
&& apk add --update --no-cache socat ca-certificates bind-tools \
&& echo "Removing apk cache" \
&& rm -rf /var/cache/apk/
# 设置容器启动命令
CMD ["/bin/sh", "-c", "socat tcp-listen:$LOCAL_PORT,reuseaddr,fork tcp:$REMOTE_HOST:$REMOTE_PORT & pid=$! && trap \"kill $pid\" SIGINT && echo \"Socat started listening on $LOCAL_PORT: Redirecting traffic to $REMOTE_HOST:$REMOTE_PORT ($pid)\" && wait $pid"]