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



我快疯了。

我一直在为我的项目处理一个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文件如何过时?它从哪里获取过时的文件,因为它不再存在于任何图像或缓存中?
  2. TF 如何设法使用这个过时的 composer.json 文件安装最新的依赖项,但随后不使用它们,实际上恢复了 composer.json 文件和依赖项?

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

您可以尝试使用多阶段构建或类似的东西:

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

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

好吧,我终于解决了这个问题,尽管我原始问题的某些部分仍然让我感到困惑。

以下是我学到的:

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

  1. 如果映像已存在,请使用它,即使 Dockerfile(或其使用的文件)已更改。(这可以通过docker-compose up --build避免)。
  2. 如果没有现有映像,请从 Dockerfile 生成映像。
  3. 挂载 docker 撰写文件中指定的卷。

我的问题的很大一部分是我认为卷是在构建过程之前挂载的,并且由于这些命令,我的应用程序将安装到此卷中:

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"

相关内容

  • 没有找到相关文章

最新更新