我在这里疯了
我一直在为项目制作Dockerfile
和docker-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
也已经过时了!
所以我的问题是:
composer.json
文件的TF如何过时?
WHERE 是从哪个文件中获取过时的文件,因为它不再存在于任何图像或缓存中?答案 0 :(得分:1)
我认为问题是,您将本地文件复制到应用程序容器中,并在此副本上运行composer install
。由于这不会影响您的主机系统,因此实际上将为您的项目服务的Web服务器仍将使用过时的本地版本,而不是其他映像的副本。
您可以尝试使用multi-stage builds或类似的方法:
COPY FROM app:latest /app /var/www/html
这会将工件从您的“构建容器”(即您的应用程序中具有已安装的依赖项)复制到运行代码的实际容器(即Web服务器)中。不幸的是,我认为这不适用于您的设置(将卷安装到该位置)。
答案 1 :(得分:0)
好吧,尽管我最初的部分问题仍然使我感到困惑,但我终于解决了这个问题。
这是我学到的东西:
docker-compose up
过程按以下顺序进行:
docker-compose up --build
可以避免这种情况。)我的很大一部分问题是我认为在构建过程之前 已安装了卷,并且由于以下命令,我的应用程序也将安装到该卷中:
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"