Docker容器未使用最新的composer.json文件

时间:2019-06-05 00:57:33

标签: docker docker-compose composer-php

我在这里疯了

我一直在为项目制作Dockerfiledocker-compose.yml文件。我最近更新了项目的依赖关系。当我使用composer install在容器外部构建项目时,它会以正确的依赖关系进行构建。但是,当我在docker容器中构建项目时,它会下载并安装最新的依赖项,但随后又会以过时的依赖项来运行应用程序!

首先,这就是我的Dockerfile的样子:

FROM composer

# Set the working directory within the docker container
WORKDIR /app

# Copy in the app, then install dependencies.
COPY . /app
RUN composer install

我在composer.lock中排除了vendor文件和.dockerignore目录:

vendor
composer.lock

这是我的docker-compose.yml

version: "3"
services:
  app:
    build: .
    volumes:
      - app:/app
  webserver:
    image: richarvey/nginx-php-fpm
    volumes:
      - app:/var/www/html

volumes:
  app:

请注意,构建过程在app卷内进行。我认为这不应该成为问题的一部分,因为我每次运行docker system prune来清除所有现有卷。

这是我运行容器的工作。在进行故障排除时,我一直在运行以下命令以在启动容器之前消除所有缓存的文件:

$ docker system prune
$ docker-compose build --no-cache
$ docker-compose up --force-recreate

当我看到依赖项的安装和下载时,我可以看到它正在下载并安装正确的版本!因此,在此过程中的某个时刻它必须具有正确的composer.json文件

无论如何,一旦构建完成并且应用程序启动,我将收到关于过时依赖项的相同警告,而且确实可以肯定,并且容器内的composer.json也已经过时了!

所以我的问题是:

  1. 容器中composer.json文件的TF如何过时? WHERE 是从哪个文件中获取过时的文件,因为它不再存在于任何图像或缓存中?
  2. TF如何使用此过时的composer.json文件安装最新的依赖项,但随后不使用它们,实际上是还原 composer.json文件和依赖项? li>

2 个答案:

答案 0 :(得分:1)

我认为问题是,您将本地文件复制到应用程序容器中,并在此副本上运行composer install。由于这不会影响您的主机系统,因此实际上将为您的项目服务的Web服务器仍将使用过时的本地版本,而不是其他映像的副本。

您可以尝试使用multi-stage builds或类似的方法:

COPY FROM app:latest /app /var/www/html

这会将工件从您的“构建容器”(即您的应用程序中具有已安装的依赖项)复制到运行代码的实际容器(即Web服务器)中。不幸的是,我认为这不适用于您的设置(将卷安装到该位置)。

答案 1 :(得分:0)

好吧,尽管我最初的部分问题仍然使我感到困惑,但我终于解决了这个问题。

这是我学到的东西:

docker-compose up过程按以下顺序进行:

  1. 如果映像已经存在,请使用它,即使Dockerfile(或它使用的文件)已更改。 (使用docker-compose up --build可以避免这种情况。)
  2. 如果没有现有映像,请从Dockerfile构建映像。
  3. 安装docker-compose文件中指定的卷。

我的很大一部分问题是我认为在构建过程之前 已安装了卷,并且由于以下命令,我的应用程序也将安装到该卷中:

COPY . /app
RUN composer install

但是,这些文件后来在将卷安装在容器(/app)的相同位置时被覆盖。

现在,由于我没有装载主机目录,而只是临时名称卷,因此/app目录应该为空。考虑到我在每次构建之前都用docker system prune清除了现有的Docker卷,我仍然不明白为什么不是这样。随便。

最后,我使用了@dbrumann的解决方案。这更简单,不需要使用任何Docker卷,并且避免在构建过程完成后使用活动的composer容器(这对生产不利)。我的Dockerfile现在看起来像这样:

Dockerfile

# Install dependencies using the composer image
FROM composer AS composer

# Set the working directory within the docker container
WORKDIR /app

# Copy in the app, then install dependencies.
COPY . .
RUN composer install

# Start the nginx server
FROM richarvey/nginx-php-fpm

# Copy over files from the composer image, which is then discarded automatically
WORKDIR /var/www/html
COPY --from=composer /app .

还有新的docker-compose.yml

version: "3.7"
services:
  webserver:
    build: .
    tty: true
    ports:
      - "80:80"
      - "443:443"