【问题标题】:Why can't composer find a composer.json file inside my Docker container?为什么 composer 在我的 Docker 容器中找不到 composer.json 文件?
【发布时间】:2017-06-29 04:20:08
【问题描述】:

我有一个基于Thelia'sComposer's 的非常简单的Dockerfile。我希望它进行尽可能多的设置,为此,我在容器内的PATH 中安装composer,然后尝试运行composer install。但是,此时,容器中似乎还不存在我的本地/挂载文件(请参阅下面RUN echo pwd: ... 的输出)。

构建失败并显示以下错误消息:

Composer 在 /var/www/html 中找不到 composer.json 文件

要初始化项目,请按照https://getcomposer.org/“入门”部分中的说明创建一个 composer.json 文件

错误:服务“web”构建失败:命令“/bin/sh -c composer install”返回非零代码:1

请注意,在没有 RUN composer install 指令的情况下构建然后运行 ​​docker-compose exec web composer install 可以工作。

docker-compose.yml 中声明的挂载是否要等到镜像完全构建好后才会生效?我是否需要明确地COPY 我的本地文件才能在构建过程中显示它们?

Dockerfile:

FROM php:5.6-apache
COPY docker-php-pecl-install /usr/local/bin/

RUN apt-get update && apt-get install -y \
 libfreetype6-dev \
 libjpeg62-turbo-dev \
 libmcrypt-dev \
 libpng12-dev \
 libicu-dev \
 git \
 zip \
 libzip-dev \
    && docker-php-ext-install intl pdo_mysql mcrypt mbstring zip calendar \
    && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install gd \
    && docker-php-pecl-install xdebug-2.3.3

RUN a2enmod rewrite
RUN usermod -u 1000 www-data
COPY config/php.ini /usr/local/etc/php/
COPY config/vhost/vhost.conf /etc/apache2/sites-enabled/

# Expose webroot
VOLUME /var/www/html
WORKDIR /var/www/html
COPY . /var/www/html # Added at Edit 1

# Allow Composer to be run as root
ENV COMPOSER_ALLOW_SUPERUSER 1

# Setup the Composer installer
RUN curl -o /tmp/composer-setup.php https://getcomposer.org/installer \
  && curl -o /tmp/composer-setup.sig https://composer.github.io/installer.sig \
  && php -r "if (hash('SHA384', file_get_contents('/tmp/composer-setup.php')) !== trim(file_get_contents('/tmp/composer-setup.sig'))) { unlink('/tmp/composer-setup.php'); echo 'Invalid installer' . PHP_EOL; exit(1); }" \
  && php /tmp/composer-setup.php \
  && chmod a+x composer.phar \
  && mv composer.phar /usr/local/bin/composer

# Install composer dependencies
RUN echo pwd: `pwd` && echo ls: `ls`  # outputs:
                                      # pwd: /var/www/html
                                      # ls:
RUN composer install

docker-compose.yml:

web:
  build: ./docker/php
  ports:
    - "8002:80"
  links:
    - mariaDB
  environment:
    SYMFONY_ENV: dev
  command: /usr/sbin/apache2ctl -D FOREGROUND
  volumes:
    - .:/var/www/html

mariaDB:
   ...

编辑 1 - 在 COPYing 明确文件之后

我在VOLUMEWORKDIR 指令之后添加了COPY . /var/www/html,并注意到一些奇怪的东西。现在RUN pwd: ... 指令回显:

密码:/var/www/html

ls: Dockerfile 配置 docker-php-pecl-install

这是我的 docker/php 目录的内容,不是项目根目录!

完整(ish)目录结构:

.
├── LICENSE.txt
├── Readme.md
├── Thelia
├── bin
│   └── ...
├── bootstrap.php
├── cache
│   └── ...
├── change-version.sh
├── composer.json
├── composer.lock
├── docker
│   └── php
│       ├── Dockerfile
│       ├── config
│       └── docker-php-pecl-install
├── docker-compose.yml
├── lib
│   └── Thelia
│       └── Project
├── local
│   └── ...
├── log
├── templates
│   └── ...
├── vendor
│   └── ...
└── web
    ├── favicon.ico
    ├── index.php
    ├── index_dev.php
    └── robots.txt

所以我修改后的问题是:我如何从运行 docker-compose 的上下文中告诉 Docker 到 COPY 我认为这是 docker-compose 的默认行为,那就是在过去的项目中它对我的工作方式...

【问题讨论】:

  • 试用:RUN /usr/local/bin/composer install
  • 要么是这样,要么你没有在 docker 范围内复制本地文件。您设置了工作目录,但我没有看到您在那里复制相关文件。
  • @k0pernikus,指定composer 的绝对路径会产生相同的错误。我添加了一条COPY 指令并注意到一些奇怪的东西......请参阅编辑。

标签: docker docker-volume


【解决方案1】:

你定义了一个 docker-compose 1.7 文件:

web:
  build: ./docker/php

这基本上导致:

docker build -f ./docker/php/Dockerfile ./docker/php/

所以基本上构建路径构建过程的上下文。

如果你真的想定义上下文,你必须将你的 docker-compose 定义至少升级到v2 or v3

你应该可以做到:

version: '2'
services:
  web:
    build:
      context: ./
      dockerfile: ./docker/php/Dockerfile

我不建议这样做:

  • 每当编辑该 Dockerfile 时,您始终必须记住父文件夹的上下文结构,这将很难维护
  • 随着上下文变得越来越大,您将通过将大量数据发送到容器构建的上下文中来减慢构建过程。 .dockerignore 文件会有所帮助,但您必须将其用作白名单而不是黑名单。

如果你想构建多个 php 容器,它们都使用 docker-php-pecl-install 文件安装依赖项,我建议你不要注入上帝上下文,而是从它自己的 Dockerfile 创建一个基本 php 映像,然后参考在另一个容器的 Dockerfile 中作为FROM 源。该基础镜像可以是一个不相关的项目,您需要做的就是构建一个镜像,并在不同的其他 php 项目中重用。

如果您想在整个公司中重复使用该映像,设置一个私有 Docker 注册表会很有帮助,您和您的团队可以从中推送和拉取映像。

【讨论】:

  • 只是为了确保我理解,当你说“记住父文件夹的上下文结构”时,你的意思是像 COPY ./docker/php/docker-php-pecl-install /usr/local/bin/ 这样在 Dockerfile 中指定一个项目相对路径?
  • @acobster 我的意思是当您更改上下文时,无论何时编辑Dockerfile,您都不会马上知道./ 指的是什么。如果上下文等于构建路径,这很简单:上下文也是 Dockerfile 所在的位置。如果其他人想使用您的 Dockerfile 作为起点,他们必须将您的自定义上下文重新映射到他们的。只是很痛苦。 (我去过。)
  • 啊,我明白了。是的,即使在尝试您建议反对的“上帝背景”的过程中,我也朝自己的脚开了一枪。 :) 由于这只是为了现在的概念验证,我将使用创可贴解决方案。但是,如果这成为我希望其他人使用的 Dockerfile,我肯定会创建一个基础镜像,它只是抽象出 pecl-install 脚本。谢谢!
猜你喜欢
  • 2013-12-05
  • 2015-11-01
  • 2016-04-15
  • 2020-10-10
  • 2014-02-20
  • 1970-01-01
  • 2023-01-13
  • 1970-01-01
  • 2015-06-06
相关资源
最近更新 更多