Почему композитор не может найти файл composer.json внутри моего контейнера Docker?

У меня есть довольно простой Dockerfile, основанный на Thelia's и Композитор. Я хочу, чтобы он выполнил как можно больше настроек, поэтому я устанавливаю composer в PATH внутри контейнера, а затем пытаюсь запустить composer install. Однако в этот момент кажется, что мои локальные / смонтированные файлы еще не существуют в контейнере (см. Вывод RUN echo pwd: ... ниже).

Сбой сборки с этим сообщением об ошибке:

Композитор не смог найти файл composer.json в / var / www / html

Чтобы инициализировать проект, создайте файл composer.json, как описано в https://getcomposer.org/ Начало работы раздел

ОШИБКА: не удалось создать службу 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 файлов явно

Я добавил COPY . /var/www/html после инструкций VOLUME и WORKDIR и заметил кое-что странное. Теперь команда RUN pwd: ... отзывается эхом:

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 COPY из контекста, в котором я запускаю docker-compose? Я думал, что это поведение по умолчанию для docker-compose, и именно так оно работало для меня в прошлых проектах. ..


person acobster    schedule 10.02.2017    source источник
comment
Попробуйте: RUN /usr/local/bin/composer install   -  person k0pernikus    schedule 10.02.2017
comment
Либо так, либо вы не скопировали свои локальные файлы внутри области докера. Вы устанавливаете рабочий каталог, но я не вижу, чтобы вы копировали туда соответствующие файлы.   -  person k0pernikus    schedule 10.02.2017
comment
@ k0pernikus, указание абсолютного пути к composer дает ту же ошибку. Я добавил COPY инструкцию и заметил кое-что странное ... см. Edit.   -  person acobster    schedule 10.02.2017


Ответы (1)


Вы определяете файл docker-compose 1.7 с помощью:

web:
  build: ./docker/php

что приводит в основном к:

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

Таким образом, в основном путь сборки является контекстом процесса сборки.

Если вы действительно хотите определить контекст, вам необходимо обновить определение docker-compose как минимум до v2 или v3.

Там вы должны уметь:

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

Я бы посоветовал этого не делать, так как:

  • всякий раз, когда кто-то редактирует этот Dockerfile, вы всегда должны помнить контекстную структуру родительской папки, которую будет довольно сложно поддерживать
  • по мере того, как контекст становится все больше, вы замедляете процесс сборки, отправляя огромное количество данных в контекст сборки контейнера. Файл .dockerignore может помочь, но вам придется использовать его как белый список вместо черного.

Если вы хотите создать несколько контейнеров php, которые все устанавливают зависимости с вашим файлом docker-php-pecl-install, я советую вам не вводить контекст бога, а лучше создать базовый образ php из его собственного файла Docker, на который вы затем ссылаетесь в другом файле Dockerfile контейнеров в качестве FROM источника. Этот базовый образ может быть несвязанным проектом, все, что вам нужно, - это создать образ и повторно использовать его в других проектах php.

Если вы хотите повторно использовать этот образ во всей своей компании, полезно настроить частный реестр докеров, из которого вы и ваша команда можете загружать и извлекать образы.

person k0pernikus    schedule 10.02.2017
comment
Просто чтобы убедиться, что я понимаю, когда вы говорите, что помните структуру контекста родительской папки, вы имеете в виду что-то вроде того, что COPY ./docker/php/docker-php-pecl-install /usr/local/bin/ указывает путь относительно проекта внутри Dockerfile? - person acobster; 10.02.2017
comment
@acobster Я имею в виду, когда вы меняете контекст, всякий раз, когда вы редактируете Dockerfile, вы не сразу узнаете, что означает ./. Если контекст равен пути сборки, это просто: контекст будет там, где также находится Dockerfile. Если кто-то еще хочет использовать ваш Dockerfile в качестве отправной точки, они должны переназначить ваш пользовательский контекст на свой. Это просто больно. (Я был там.) - person k0pernikus; 10.02.2017
comment
Ах я вижу. Да, даже в процессе экспериментов с тем контекстом бога, который вы не рекомендуете, я выстрелил себе в ногу. :) Поскольку пока это просто для проверки концепции, я собираюсь использовать пластырь. Но если он когда-либо станет Dockerfile, который, как я ожидаю, будут использовать другие, я обязательно создам базовый образ, который просто абстрагируется от сценария pecl-install. Спасибо! - person acobster; 10.02.2017