tl;博士
应用程序代码需要一个生成步骤(拉入依赖项)
多个容器需要相同的“构建”代码
问:用docker/docker compose来归档的好策略/工作流是什么。
长
我们正在对接包含多个组件(容器/服务)的PHP应用程序,例如。
工作节点(PHP进程通过supervisor保持活动)
调度程序(在cron中管理工人和运行周期性任务)
PHP-FPM/Nginx(网络接口)
服务在docker compose文件中定义。
在开发过程中,我们通过卷从每个容器中主机上的一个目录装载应用程序代码,
这样我们就可以“立即”看到每个服务的变化(
Example
). 生活很美好。
我们现在正在建立一个基于Jenkins的CI/CD环境,它应该构建(测试)容器和
稍后将推送到注册表。既然“从主机装载”已经不可能了,我现在想知道
最好的方法是将应用程序代码放在每个容器中。
在我们的设置中有两件事使这个imho特别复杂:
我们有多个需要相同应用程序代码的容器
“构建工件”不是一个单独的自容器二进制文件(例如,使用go)
但是“我们所有的代码+安装的依赖项”==>“很多文件”(慢…)
有一个构建步骤需要最终映像中不需要的软件
“3”的解决方案通常是:使用多阶段构建。我们这样做。但是:所有的例子
似乎假设生成的代码只在另一个容器中使用(在我们的例子中不是这样,请参阅1)
我们现在所做的
文件夹结构
application-code/
.docker/
builder/
Dockerfile
php-fpm/
Dockerfile
docker-compose.yml
build.sh
index.php
引入一个额外的“builder”容器来“构建”应用程序
(获取“all”应用程序代码作为生成上下文;运行“composer install”)
# ./builder/Dockerfile
COPY ./ /codebase
RUN cd /codebase && composer install
在每个需要应用程序代码的容器中(例如,通过
# ./php-fpm/Dockerfile
ARG APP_CODE_PATH="/var/www/current"
COPY --from=builder --chown=www-data /codebase ${APP_CODE_PATH}
通过docker compose编排
# ./docker-compose.yml
version: '3.7'
services:
builder-ci:
image: builder
build:
# ../ contains the "raw" application code
context: ../
dockerfile: ./.docker/builder/Dockerfile
php-fpm:
build:
context: .
dockerfile: ./php-fpm/Dockerfile
args:
- APP_CODE_PATH=/var/www/current
通过
# build.sh
## build builder
docker-compose -f ./.docker/docker-compose.yml --project-directory ./.docker build builder
## build the rest
docker-compose -f ./.docker/docker-compose.yml --project-directory ./.docker build --parallel
赞成
“较小”的图像(php fpm不会安装composer)
应用程序代码只生成一次,然后复制到
相反
生成器容器没有其他用途,只是“build”==>感觉不干净
建造“建造者”必须在建造任何其他容器之前完成
这意味着我们还有
选择
不要使用构建器容器,而是将构建步骤“合并”到“调度程序”容器中
通过使用多阶段构建(这样我们就不会在最终图像中使用composer)
去掉“builder”-但现在所有其他服务都依赖于“Scheduler”==>感觉更脏
使用卷共享代码
我们不必“复制”图像中的文件,只需“装入卷”==>感觉“干净“/不复制文件”
(我首先认为这是一个非常好的方法……)
但是:
在构建期间不能填充卷,因此需要“运行”容器才能在容器中获取appliation代码
==>我们突然不仅有一个构建器容器,而且还需要“运行”它来填充卷
容器不再是“自包含”的,即从注册表中提取“仅调度程序”将不起作用-
我们还必须将卷放在适当的位置,并且它必须由生成器填充==>编排变得更加复杂
卷不是短暂的,即在刷新之前它将包含“旧”应用程序代码==>这可能会导致
混乱和意外行为
链接