Php docker使用旧卷编写

Php docker使用旧卷编写,php,docker,docker-compose,volumes,Php,Docker,Docker Compose,Volumes,我正在尝试使用docker compose设置CI管道,并且正在努力理解命名卷是如何工作的 作为Dockerfile的一部分,我复制应用程序文件,然后运行composer install安装应用程序依赖项。我希望与正在运行/设置为运行以执行实用程序进程(例如运行数据库迁移)的其他容器共享applicaton文件的一些元素和依赖项。请参见下面的示例: Dockerfile: FROM php:5.6-apache # Install dependencies COPY composer.* /a

我正在尝试使用docker compose设置CI管道,并且正在努力理解命名卷是如何工作的

作为Dockerfile的一部分,我复制应用程序文件,然后运行
composer install
安装应用程序依赖项。我希望与正在运行/设置为运行以执行实用程序进程(例如运行数据库迁移)的其他容器共享applicaton文件的一些元素和依赖项。请参见下面的示例:

Dockerfile:

FROM php:5.6-apache

# Install dependencies
COPY composer.* /app/
RUN composer install --no-dev

# Copy application files
COPY bin bin
COPY environment.json environment.json

VOLUME /app
docker-compose.yml

 web:
    build:
      context: .
      dockerfile: docker/web/Dockerfile
    volumes:
      - app:/app
      - ~/.cache/composer:/composer/cache

  migrations:
    image: my-image
    depends_on:
      - web
    environment:
      - DB_DRIVER=pdo_mysql
      - AUTOLOADER=../../../vendor/autoload.php
    volumes:
      - app:/app
    working_dir: /app/vendor/me/my-lib

volumes:  
  app:
在上面的示例中(不相关的信息省略),我有一个“迁移”服务,它从composer安装的应用程序依赖项中提取迁移。我的想法是,当我执行
docker compose build
然后执行
docker compose up
时,它将显示具有最新依赖项的最新版本的软件,并同时运行最新的迁移

这在第一次使用时效果很好。不幸的是,在后续运行中,我无法让docker compose使用新版本。如果我运行
docker compose build
,我可以看到
composer install
运行并安装所有最新的库,但是当我进入容器
docker compose run web/bin/bash
,旧的依赖项就在那里!如果我直接用docker run web_1运行图像,我可以看到所有最新的文件,没有问题。所以这绝对是一个特定的问题

我想我需要做一些事情,比如清除卷缓存,但是我所做的一切似乎都不起作用。我只能假设我误解了体积的概念


任何帮助都将不胜感激。谢谢

这里的问题与在构建中定义的位置上装载卷有关。映像的第一次构建将
composer
的输出放入
/app
,第一次构建的第一次运行将
app
命名卷装载到
/app
。这在顶部添加了一个新的写入层,从而使
/app
的图像版本受到冲击。在映像的第二个版本上装载此命名卷将保留
/app
的原始内容

使用
volumes from
将导出的
/app
卷从
web
加载到
迁移
容器中,而不是使用命名卷

version: '2'
services:
  web:
    build:
      context: .
      dockerfile: docker/web/Dockerfile
    volumes:
      - ~/.cache/composer:/composer/cache
  migrations:
    image: docker-registry.efficio.digital:5043/doctrine-migrator:1.1
    depends_on:
      - web
    environment:
      - DB_DRIVER=pdo_mysql
      - AUTOLOADER=../../../vendor/autoload.php
    volumes_from:
      - web:ro 

我从您的问题中了解到,您希望在每次运行容器时都运行composer安装。在这种情况下,您必须使用CMD指令来执行该命令

CMD composer安装--无开发人员

RUN和CMD都是Dockerfile指令

RUN允许您在Docker映像内执行命令。这些命令在构建时执行一次,并作为新层写入Docker图像

例如,如果您想要在Docker映像中安装一个包或创建一个目录,那么RUN将是您想要使用的。例如,运行mkdir-p/path/to/folder

CMD允许您定义在容器启动时运行的默认命令


可以说CMD是Docker运行时操作,这意味着它不是在构建时执行的操作。它发生在运行图像时。运行的映像称为容器。

不,我完全理解这些命令,就像您理解它们一样。对不起,我可能没解释清楚。我知道build对迁移没有任何作用。暂时不要考虑迁移,我的问题是,当我docker编写web容器时,其中包含来自以前版本的文件,尽管正如您在我的dockerfile中看到的,依赖项安装在版本上。这有意义吗?是的,我理解。我的意思是,当您使用
docker compose run
时,您仍然在使用旧容器和旧映像。您需要停止并删除旧容器,然后使用新映像启动新容器以获取更新的依赖项。感谢您的响应。是的,我正在这样做。让我困惑的是,即使在第二次构建之后的第二次运行中,我也会得到旧文件(来自第一次构建)。即使我删除了构建之间的映像。而且它只与compose;。如果se
docker run/bin/bash
,我可以看到正确的文件。如果使用
docker compose run/bin/bash
,我可以看到一组完全不同的文件。那有帮助吗?是的,我仍然理解。使用
docker compose run
时,它不使用新图像。因为您已经使用旧图像创建了一个容器。在再次运行
docker compose run
之前,您是否尝试过运行
docker compose down
。我已经运行了
docker compose down
docker compose rm
,删除了映像,删除了所有卷,并运行了
docker system prune
。然后,如果再次运行
build
,然后再次运行
run
,我将从第一次生成中获取旧文件。不,这不是我想要做的。Composer作为构建的一部分运行,您可以从我的dockerfile中看到。问题是,即使在我首先运行docker compose build时,当我运行容器时,容器包含来自旧版本的文件,即使我可以看到dokcer compose build过程中安装的新文件。
version: '2'
services:
  web:
    build:
      context: .
      dockerfile: docker/web/Dockerfile
    volumes:
      - ~/.cache/composer:/composer/cache
  migrations:
    image: docker-registry.efficio.digital:5043/doctrine-migrator:1.1
    depends_on:
      - web
    environment:
      - DB_DRIVER=pdo_mysql
      - AUTOLOADER=../../../vendor/autoload.php
    volumes_from:
      - web:ro