代码之家  ›  专栏  ›  技术社区  ›  Kana

从docker访问装入的卷以便在生成时安装作曲家/npm?

  •  1
  • Kana  · 技术社区  · 7 年前

    我正在寻找一个更好的解决方案来安装composer或npm包到通过docker compose挂载的主机卷内。

    在docker-compose.yml中,我有:

    volumes:
      - ./app:/var/www/app
      ...
    

    在我的Dockerfile中,我想使用这个卷来安装:

    VOLUME ["/var/www/app"]
    RUN composer install -d /var/www/app
    

    但据我所知,当容器从dockerfile构建时,docker compose中装载的卷尚不可用。

    所以我下一次尝试是在容器启动时:

    CMD bash -c "composer install -d /var/www/app && /usr/sbin/apache2ctl -DFOREGROUND"
    

    这至少起到了作用,但它每次运行容器时都调用composer install,这是多余的。

    因此,我目前的想法是使用一个专用的composer映像,将composer.json装入其中进行安装,然后将完成的供应商从composer容器复制到容器中的某个位置并链接到需要的位置这样地:

    FROM composer as composer
    COPY ./app/composer.json /app
    COPY ./app/composer.lock /app
    RUN composer install --ignore-platform-reqs --no-scripts
    
    FROM library/ubuntu:jessie
    # ... do other stuff with the main image ...
    
    COPY --from=composer /app/vendor /var/www/composer/vendor
    CMD bash -c "ln -s /var/www/composer/vendor /var/www/app/vendor  && /usr/sbin/apache2ctl -DFOREGROUND"
    

    但对于这样一个普通的问题来说,这仍然是一种权宜之计。有没有更好的方法来解决这个问题或任何已知的良好实践?

    1 回复  |  直到 7 年前
        1
  •  0
  •   David Maze    7 年前

    我认为最好的做法,以及我在专业上所做的,是在这种情况下根本不使用卷。我的档案 COPY 在生成时在应用程序代码中。我有一个正在工作的主机开发设置(唯一真正的主机依赖关系是节点本身;其他的都在 node_modules 如果有问题,我可以在本地环境中复制、调试和编写测试。只有这样我才能回到码头。

    FROM ???
    WORKDIR /var/www/app
    COPY app/composer.json app/composer.lock ./
    RUN composer install --ignore-platform-reqs --no-scripts
    COPY app/ ./
    ...
    CMD ["apache2ctl", "-DFOREGROUND"]
    

    否则,Docker volumes有几点需要记住:

    • dockerfile中的所有内容都发生在 docker-compose.yml 文件甚至被考虑在内。如果您的目标是填充一个卷,那么就不能在Dockerfile中执行此操作(而这通常在Docker中很难实现;请使用本机主机工具)。

    • 如果将卷装入容器目录,它将完全隐藏已经存在的内容。我看到很多关于Dockerfiles的问题,它们只在本地容器中工作 /app 目录,然后绑定挂载本地源代码树;这基本上使Dockerfile成为no-op。

    • 如果你有 VOLUME 在Dockerfile中,不能再对图像中的目录进行任何更改(在你的问题中,跑步 composer 之后 音量 指令将不起作用。)

    • 无论卷是否声明为 音量 . 我建议你不要宣布 音量 在Dockerfiles中,尤其是对于包含代码的目录(您 希望 当容器被删除并重新创建时,这些将用新的图像代码更新)。