更新后通过存储在 php-fpm 容器中的 nginx 提供新的静态文件
Serving new static files via nginx stored in php-fpm container after update
我有以下容器:
nginx:latest
myapp
容器(源自 php-fpm:alpine)
目前我有一个带有 CI 管道的虚拟项目,它在构建时编译资源的生产变体 (images/js/css,...)。构建文件最终位于 (/public/build) 中。在 CI 管道的最后,我将所有内容打包成 Docker 图像并将其上传到 Hub。
nginx
和 myapp
都设置了卷(未绑定安装)并指向 /opt/ci-test/public/build
。
这是第一次成功。
但是假设我添加了一个新文件 new.css
- 我的 docker 图像的新版本将包含 new.css
.
的构建变体
运行 具有预先存在的卷的新容器不会显示新文件我知道它不应该。。我可以创建一个新卷 my_app_v2
。
此时 nginx
没有看到这个新卷,必须将其删除并重新 运行(使用新卷)才能生效。
有没有简单的方法可以解决这个问题?
我的意图是将 nginx
容器用于多个 PHP 应用程序,并且我需要避免在更新其中一个正在提供服务的应用程序时终止它。这是一个错误的决定吗?
编辑:
我设法找出的一个解决方法是从附加卷中删除所有文件并启动新的 myapp
容器。这会将所有最新文件镜像到该卷。但这感觉很脏...
编辑 2:
相关问题(案例 3):https://github.com/moby/moby/issues/18670#issuecomment-165059630
编辑 3:
Docker文件
FROM php:7.2.30-fpm-alpine3.11
COPY . /opt/ci-test
WORKDIR /opt/ci-test
VOLUME /opt/ci-test/public/build
到目前为止,我没有 docker-composer
并且我通过命令手动 运行 容器:
docker run -it -d --name php71alp -v shr_test:/opt/ci-test/public/build -p 9000:9000 <myaccount>/citest
docker run -it -d --name nginx -v shr_test:/var/www/citest -p 80:80 nginx:latest
第一个选项:不使用卷。如果您希望从映像构建中访问文件,并且不需要持久性,那么卷对您的工作流程没有帮助。
第二个选项:在运行之间删除之前的卷并使用命名卷,docker 将使用图像内容进行初始化。
第三个选项:修改镜像构建和容器入口点以在构建过程中将目录保存到不同的位置,并在入口点的容器启动时将该位置恢复到卷中。我在 save-volume and load-volume scripts in my base image 中实现了这个。当您想要将卷的内容与主机的内容合并时,它会变得更加复杂,您需要决定如何处理文件被删除以及要保存之前运行的哪些更改。
干脆不要为此使用音量。
您应该将 docker 图像视为包含您的依赖项 (nginx) 和应用程序文件(图像、js、css...)的 "monolithic packages"。无需像对待 nginx 本身那样对待您的应用程序文件,它们都是单个 docker 图像的一部分。
没有卷,你 运行 你的图像的 v1,nginx 看到 v1 文件。你 运行 你的图像的 v2,nginx 看到 v2 文件。
当您实际想要在容器版本(例如数据库、文件上传...)之间保留文件时,可以使用卷。不适用于您网站的静态资产。
My intention is to use nginx container for multiple PHP apps and I need to refrain from killing it whenever I update one of the apps being served. Is this a bad decision?
是的,这是糟糕的设计。如果你想 运行 多个应用程序,你应该 运行 每个应用程序 1 Docker 个容器。这样,当您发布一个应用程序的新版本时,您只需要重新启动该容器即可。容器不应该像传统的虚拟机那样被对待 "SSH into" 并手动配置东西。容器 "throw-away"。应用程序的新版本?只需将容器替换为具有较新图像的新容器即可。
我有以下容器:
nginx:latest
myapp
容器(源自 php-fpm:alpine)
目前我有一个带有 CI 管道的虚拟项目,它在构建时编译资源的生产变体 (images/js/css,...)。构建文件最终位于 (/public/build) 中。在 CI 管道的最后,我将所有内容打包成 Docker 图像并将其上传到 Hub。
nginx
和 myapp
都设置了卷(未绑定安装)并指向 /opt/ci-test/public/build
。
这是第一次成功。
但是假设我添加了一个新文件 new.css
- 我的 docker 图像的新版本将包含 new.css
.
运行 具有预先存在的卷的新容器不会显示新文件我知道它不应该。。我可以创建一个新卷 my_app_v2
。
此时 nginx
没有看到这个新卷,必须将其删除并重新 运行(使用新卷)才能生效。
有没有简单的方法可以解决这个问题?
我的意图是将 nginx
容器用于多个 PHP 应用程序,并且我需要避免在更新其中一个正在提供服务的应用程序时终止它。这是一个错误的决定吗?
编辑:
我设法找出的一个解决方法是从附加卷中删除所有文件并启动新的 myapp
容器。这会将所有最新文件镜像到该卷。但这感觉很脏...
编辑 2:
相关问题(案例 3):https://github.com/moby/moby/issues/18670#issuecomment-165059630
编辑 3:
Docker文件
FROM php:7.2.30-fpm-alpine3.11
COPY . /opt/ci-test
WORKDIR /opt/ci-test
VOLUME /opt/ci-test/public/build
到目前为止,我没有 docker-composer
并且我通过命令手动 运行 容器:
docker run -it -d --name php71alp -v shr_test:/opt/ci-test/public/build -p 9000:9000 <myaccount>/citest
docker run -it -d --name nginx -v shr_test:/var/www/citest -p 80:80 nginx:latest
第一个选项:不使用卷。如果您希望从映像构建中访问文件,并且不需要持久性,那么卷对您的工作流程没有帮助。
第二个选项:在运行之间删除之前的卷并使用命名卷,docker 将使用图像内容进行初始化。
第三个选项:修改镜像构建和容器入口点以在构建过程中将目录保存到不同的位置,并在入口点的容器启动时将该位置恢复到卷中。我在 save-volume and load-volume scripts in my base image 中实现了这个。当您想要将卷的内容与主机的内容合并时,它会变得更加复杂,您需要决定如何处理文件被删除以及要保存之前运行的哪些更改。
干脆不要为此使用音量。
您应该将 docker 图像视为包含您的依赖项 (nginx) 和应用程序文件(图像、js、css...)的 "monolithic packages"。无需像对待 nginx 本身那样对待您的应用程序文件,它们都是单个 docker 图像的一部分。
没有卷,你 运行 你的图像的 v1,nginx 看到 v1 文件。你 运行 你的图像的 v2,nginx 看到 v2 文件。
当您实际想要在容器版本(例如数据库、文件上传...)之间保留文件时,可以使用卷。不适用于您网站的静态资产。
My intention is to use nginx container for multiple PHP apps and I need to refrain from killing it whenever I update one of the apps being served. Is this a bad decision?
是的,这是糟糕的设计。如果你想 运行 多个应用程序,你应该 运行 每个应用程序 1 Docker 个容器。这样,当您发布一个应用程序的新版本时,您只需要重新启动该容器即可。容器不应该像传统的虚拟机那样被对待 "SSH into" 并手动配置东西。容器 "throw-away"。应用程序的新版本?只需将容器替换为具有较新图像的新容器即可。