Php 我应该在docker构建中运行composer install吗

Php 我应该在docker构建中运行composer install吗,php,docker,Php,Docker,我可能有一个docker文件,如下所示: COPY . ./ RUN composer install --no-dev --no-interaction -o 但是我的composer.json中有私有repo,这需要我复制ssh密钥,以便docker构建正常工作。我觉得在php应用程序docker映像中打包ssh密钥很不舒服 或者,我可以在docker构建之外运行composer install(例如在build.sh bash脚本中),并在填充vendor/之后复制目录。这是正确的方法吗

我可能有一个docker文件,如下所示:

COPY . ./
RUN composer install --no-dev --no-interaction -o
但是我的composer.json中有私有repo,这需要我复制ssh密钥,以便docker构建正常工作。我觉得在php应用程序docker映像中打包ssh密钥很不舒服

或者,我可以在docker构建之外运行composer install(例如在build.sh bash脚本中),并在填充vendor/之后复制目录。这是正确的方法吗


有没有其他方法来处理这个问题

我认为在您描述的情况下,在docker构建之外安装composer是有意义的

你通常会有一个初始构建过程来构建你的应用程序代码。此构建可能会运行一些linting或自动测试,然后生成一个工件,其中包含运行应用程序所需的所有代码。这将包括您的源代码、供应商文件夹和任何自动生成的代码(ORM类、缓存等)。这些工件通常是tar文件


然后,您将在后续docker构建中将该代码工件复制到docker容器中。

您始终可以创建一个构建,该构建将复制~/.ssh,运行composer安装,然后运行rm密钥。。。在此之后,如果以后需要在docker compose中使用ssh(或者通常使用-v),您只需在运行期间使用volume/-v在本地装载.ssh:)

这是一个非常好的问题,它描述了我现在几次遇到的原则,实际上是两个独立但相关的问题:

1.)如何最好地处理Docker中的临时文件

Docker擅长封装环境的全部和彻底的娱乐。如果您在容器“外部”处理部分流程,即在
docker build
流程外部运行
composer install
,则生成流程的可移植性较差,因为您可能引入了您不知道的机器/环境依赖项

如果您总是在Docker中重建完整的环境,那么您可以保证您的依赖关系始终得到满足,并且您可以将dockerfile提供给其他任何人,他们也将非常有信心能够在本地重建而不会出现问题

瞬态文件非常适合在Docker中构建!所以我会尽可能在容器中构建它们

2.)如何将授权与Docker构建过程分离

这就引出了第二个问题,如何将授权与构建分离

选项1-为专用构建用户烘焙具有creds的composer auth.json:

正如其他答案所说,您可以“烘焙”凭证,然后再次删除它们。但是,您不希望“烘焙”像ssh密钥这样敏感的东西。 Composer支持一个文件,那么为什么不创建一个专用的构建用户并将其cred(而不是您的)存储在auth.json文件中呢?如果密码被泄露,您可以更改密码。composer安装完成后,删除或覆盖该文件

COPY . ./
RUN composer install --no-dev --no-interaction -o
RUN rm -f ./auth.json
选项2-使用Docker exec使Cred自身暂时化并将其传递到Docker容器中:

我还没有完全测试过这种方法,但我不明白为什么这样的方法不起作用

1.)构建一个能够运行“composer安装”的基本PHP容器(或使用docker hub提供的容器)

2.)旋转此基本容器,使其运行

3.)您可以使用docker exec将您的creds传递给已烘焙到容器中的包装器脚本。包装器脚本将运行composer安装 使用HTTP基本身份验证-它已经烘焙了用户名,因此您只需按照

4.)将此容器作为新映像提交

docker commit --change "composer install" ${CONTAINER_ID} my_installed_image:1.0

好笑。仅在发布此问题几天后,Docker 17.05就发布了,并提供了解决方案:。只需将您的composer内容放入dockerfile并构建您的应用程序。然后,开始第二阶段,并将应用程序复制为第一阶段的构建工件。

我倾向于这种方法。我可能希望在映像构建之后测试它,而不是之前,考虑到我可能需要运行一个mysql容器,更是如此。我为什么要给文件加焦油?我的最后一个映像可能是一个php/apache映像。因此,构建内部映像的主要参数是在映像中包含我需要的所有依赖项?为什么不创建一个私有镜像来复制创建的工件呢。这样,我的构建过程与所有内容都是一致的,没有现成的cred或ssh密钥,而且我部署的映像中没有像composer这样的不必要的层。是的,映像中的所有依赖项都可以为您提供一致性和可移植性。为什么不让我们的docker容器创建工件?好问题,这是另一个好方法!这是我以前尝试过的Maven docker映像,您可以将POM文件传递给它,它可以工作,注意事项是1。)如果身份验证在docker之外,您如何让其他人(包括构建服务器/管道)也构建您的映像?2.)如何从容器中提取工件?(您可以使用卷装载来实现这一点,但这可能会引入特定于环境的依赖关系)+1向NiRR和Greensterox投票:我同意使用私有docker容器的方法,因为1)您仍然可以获得一致性和可移植性,但2)作为私有,您的生产容器中没有composer—composer(PHP composer)维护人员建议不要在生产容器中使用composer:
docker commit --change "composer install" ${CONTAINER_ID} my_installed_image:1.0