1

我正在尝试使用 docker-compose 设置 CI 管道,并且正在努力了解命名卷的工作原理......

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

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

码头工人-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,我可以看到所有最新的文件没有问题。所以这绝对是一个特定于撰写的问题。

我想我需要做一些事情,比如清除卷缓存,但无论我尝试过什么似乎都不起作用。我只能假设我误解了卷的概念。

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

4

2 回答 2

1

这里的问题与在构建中定义的位置安装卷有关。映像的第一个构建已将composer其输出放入/app,第一个构建的第一次运行将app命名卷安装到/app. 这破坏了图像版本,/app顶部有一个新的写入层。在镜像的第二个构建上安装这个命名卷将保留/app.

不使用命名卷,而是使用volumes-from将导出的/app卷加载webmigration容器中。

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 
于 2017-08-22T17:21:44.577 回答
0

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

CMD 作曲家安装 --no-dev

RUN 和 CMD 都是 Dockerfile 指令。

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

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

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

你可以说 CMD 是一个 Docker 运行时操作,这意味着它不是在构建时执行的东西。当您运行图像时会发生这种情况。正在运行的映像称为容器。

于 2017-08-22T19:28:24.483 回答