对于应用程序的安装, Docker能帮助我们省略掉繁琐的安装配置步骤, 在最短时间得到一个可使用的应用程序环境. 但对于已通过Docker启动的应用程序的更新, 步骤似乎繁琐些. 查阅了官方文档, 并没有找到直接升级容器所使用镜像版本的命令, docker container update
命令也只能更改容器的设置, 不涉及版本更新.
于是我转向了Stack Overflow, 得知Docker对于容器的版本更新, 采用的是"停止旧容器, 启动新容器"的方式, 也就是说所谓的"更新", 实际上是全量替换. 其实这样做很合理, Docker旨在为开发者快速构建应用环境, 即只关注"应用"本身, 而应用的配置和文稿这类持久化数据, 在启动容器时应该使用volume
映射到宿主机的目录, 这样一来, 容器本身是无状态的, 更新操作就不存在障碍.
实际操作起来, 拿portainer作为例子, 它一直有烦人的版本更新提示, 所以拿它下手.
$ docker ps -a
CONTAINER ID IMAGE NAMES
89d5fa0663d4 portainer/portainer:1.24.0 portainer
先stop
旧容器:
$ docker stop 89d5fa0663d4
然后使用与旧容器相同的run
命令来运行新的容器. 这里可以使用runlike
工具来获取旧容器的run
命令(reference):
$ sudo pip install runlike
$ runlike 89d5fa0663d4
如果没有python环境, 或者懒得安装pip包, 可以直接用docker版本的runlike
:
$ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock assaflavie/runlike 89d5fa0663d4
这两种方法都可会输出一条docker run
命令, 只需要把--name=
后面的名字更换一下, 然后更换新镜像的tag, 再运行这条命令就可以了:
$ docker run --name=portainer_1.24.1 --hostname=519a5d62721f --env=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin --volume=/mnt/sda3/portainer:/data --volume=/var/run/docker.sock:/var/run/docker.sock --volume=/data -p 8000:8000 -p 9000:9000 --restart=always --detach=true portainer/portainer:1.24.1
新版本启动确认无误后, 可以选择把旧版本的容器删除掉, 把新容器的名字替换回来:
$ docker rm 89d5fa0663d4
$ docker rename portainer_1.24.1 portainer