简体   繁体   English

docker-compose使用旧卷

[英]docker-compose using old volumes

I am trying to set up a CI pipeline with docker-compose and am struggling to understand how named volumes work... 我正在尝试使用docker-compose建立CI管道,并且正在努力了解命名卷的工作方式...

As part of my Dockerfile, I copy in the application files and then run composer install to install the application dependencies. 作为Dockerfile的一部分,我复制了应用程序文件,然后运行composer install来安装应用程序依赖项。 There are some elements of the applicaton files and the dependencies that I want to share with the other containers that are running / are set up to be run to perform utility processes (such as running database migrations). 我想与正在运行的其他容器共享applicaton文件的某些元素以及要与之共享的依存关系,这些依存关系被设置为运行以执行实用程序过程(例如,运行数据库迁移)。 See the example below: 请参阅以下示例:

Dockerfile: 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 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:

In the example above (irrelevant information omitted), I have a "migrations" service that pulls the migrations from the application dependencies installed with composer. 在上面的示例中(省略了不相关的信息),我有一个“迁移”服务,该服务从与composer一起安装的应用程序依赖项中提取迁移。 My idea is that when I perform docker-compose build followed by docker-compose up , it will bring up the latest version of software with the latest dependencies and run the latest migrations at the same time. 我的想法是,当我执行docker-compose build之后执行docker-compose build docker-compose up ,它将调出具有最新依赖关系的最新软件版本,并同时运行最新迁移。

This works fine the first time. 第一次工作正常。 Unfortunately on subsequent runs I cannot get docker-compose to use the new versions. 不幸的是,在随后的运行中,我无法让docker-compose使用新版本。 If I run docker-compose build , I can see the composer install run and install all the latest libraries, but then when I go into the container with docker-compose run web /bin/bash , the old dependencies are in there! 如果我运行docker-compose build ,则可以看到composer install运行并安装了所有最新的库,但是当我使用docker-compose run web /bin/bash进入容器时,旧的依赖项就在其中! If I run the image directly with docker run web_1 , I can see all the latest files no problem. 如果使用docker run web_1直接docker run web_1 ,则可以看到所有最新文件。 So it's definitely a compose-specific problem. 因此,这绝对是特定于组合的问题。

I assume I need to do something like clear out the volume cache, but whatever I have tried doesn't seem to work. 我以为我需要做一些事情,例如清除卷缓存,但是我尝试过的一切似乎都行不通。 I can only assume I am misunderstanding the idea of volumes. 我只能假设我误解了卷的概念。

Any help would be hugely appreciated. 任何帮助将不胜感激。 Thanks! 谢谢!

The problem here has to do with mounting a volume over a location defined in the build. 这里的问题与在构建中定义的位置上安装卷有关。 The first build of the image has composer put its output into /app , and the first run of the first build mounts the app named volume to /app . 映像的第一个构建已将composer的输出放入/app ,并且第一个构建的首次运行将名为volume的app安装到/app This clobbers the image version of /app with a new write-layer on top. 这将掩盖/app的图像版本,并在其顶部添加一个新的写层。 Mounting this named volume on the second build of the image will keep the original contents of /app . 在映像的第二个版本上安装此命名卷将保留/app的原始内容。

Instead of using a named volume, use volumes-from to load the exported /app volume from web into the migration container. 代替使用命名卷,可以使用volumes-fromweb导出的/app卷加载到migration容器中。

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 

What I understand from your question is you want to run composer install every time you run your container. 从您的问题中我了解到的是,您希望在每次运行容器时都运行composer install。 In that case you have to use CMD instruction to execute that command. 在这种情况下,您必须使用CMD指令来执行该命令。

CMD composer install --no-dev CMD作曲家安装--no-dev

RUN and CMD are both Dockerfile instructions. RUN和CMD都是Dockerfile指令。

RUN lets you execute commands inside of your Docker image. 通过RUN,您可以在Docker映像内执行命令。 These commands get executed once at build time and get written into your Docker image as a new layer. 这些命令在构建时执行一次,并作为新层写入到您的Docker映像中。

For example if you wanted to install a package or create a directory inside of your Docker image then RUN will be what you'll want to use. 例如,如果您想在Docker映像中安装软件包或创建目录,则可以使用RUN。 For example, RUN mkdir -p /path/to/folder. 例如,运行mkdir -p / path / to / folder。

CMD lets you define a default command to run when your container starts. CMD使您可以定义在容器启动时运行的默认命令。

You could say that CMD is a Docker run-time operation, meaning it's not something that gets executed at build time. 您可以说CMD是Docker运行时操作,这意味着它不是在构建时执行的。 It happens when you run an image. 运行图像时会发生这种情况。 A running image is called a container. 运行中的映像称为容器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM