docker-compose переопределяет каталоги в контейнере - PullRequest
0 голосов
/ 20 июня 2019

Контекст

Недавно я настроил приложение PHP для работы в док-контейнере, подключенном к базе данных в другом контейнере.

В производстве мы используем единую контейнерную среду, поскольку она просто подключается к базе данных, которая размещена где-то еще. Тем не менее, мы решили использовать два контейнера и docker-compose локально для облегчения процесса разработки.

Проблема

Проблема, с которой мы столкнулись, заключается в том, что в первый раз, когда мы собираем и запускаем приложение через docker-compose up --build каталог vendor Composer, недоступен в контейнере, даже если у нас была RUN composer install конкретная строка в Dockerfile. Мы должны были бы выполнить composer install из контейнера, как только он был запущен.

Решение найдено

После долгих поисков мы решили, что у нас есть два возможных решения:

  1. измените команду по умолчанию нашего образа Docker на следующую:
bash -c "composer install && /usr/sbin/apache2ctl -D FOREGROUND"
  1. Или просто переопределить команду по умолчанию для контейнера с помощью команды docker-compose command.

Разница в том, что если мы переопределим команду с помощью docker-compose, при развертывании приложения на нашем сервере оно будет работать без проблем, как и должно, но при изменении команды по умолчанию в Dockerfile оно получит 1 минутное время простоя при каждом развертывании.

Это помогло во время этого процесса:

  1. Запуск установки composer в Dockerfile

Некоторые (возможно, неправильные) выводы

Я пришел к выводу, что эта минута простоя была вызвана тем, что контейнеру пришлось установить все зависимости через composer перед запуском сервера Apache, а не просто запустив сервер.

Кроме того, еще один вывод, который я сделал из всего этого, заключается в том, что причина, по которой docker-compose up --build не установил зависимости компоновщика, заключалась в том, что у нас был указан том в docker-compose.yml, который переопределял каталоги в контейнере.

Это помогло:

  1. https://stackoverflow.com/a/38817651/4700998

  2. https://stackoverflow.com/a/48589910/4700998

Актуальный вопрос

Я надеялся, что кто-то сможет пролить свет на все это, так как я не совсем понимаю, что происходит полностью - почему запуск docker-compose не установил бы зависимости PHP, но включение composer install в команду по умолчанию и почему лучше добавить composer install к docker-compose.yml. Кроме того, как объемы входят во все это, и это - реальная причина всех хлопот.

Наш текущий файл Docker выглядит так:

FROM php:7.1.27-apache-stretch

ENV DEBIAN_FRONTEND=noninteractive

# install some stuff, PHP, Apache, etc.

WORKDIR /srv/app
COPY . .

RUN composer install

RUN service apache2 restart

EXPOSE 80

CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]

А наши текущие docker-compose.yml вот так:

version: '3'
services:
  database:
    image: mysql:5.7
    container_name: container-cool-name
    command: mysqld --user=root --sql_mode=""
    ports:
      - "3306:3306"
    volumes:
      - ./db_backup.sql:/tmp/db_backup.sql
      - ./.docker/import.sh:/tmp/import.sh
    environment:
      MYSQL_DATABASE: my_db
      MYSQL_USER: my_user
      MYSQL_PASSWORD: password
      MYSQL_ROOT_PASSWORD: test

  app:
    build:
      context: .
      dockerfile: Dockerfile
    image: image-name
    command: bash -c "composer install && /usr/sbin/apache2ctl -D FOREGROUND"
    ports:
      - 8080:80
    volumes:
      - .:/srv/app
    links:
      - database:db
    depends_on:
      - database
    environment:
      DB_HOST: db
      DB_PORT: 3306
      DB_DATABASE: my_db
      DB_USER: my_user
      DB_PASSWORD: password

1 Ответ

1 голос
/ 20 июня 2019

Ваш первый composer install в пределах Dockerfile работает нормально, и ваше результирующее изображение имеет vendor/ и т. Д.

Но позже вы создаете контейнер из этого образа, и этот контейнер выполняется, а весь каталог заменяется на хост dir mount:

volumes:
      - .:/srv/app

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

Мой совет:

  • не добавлять вторую сборку команды к Dockerfile
  • монтирование отдельных папок в вашем контейнере, т.е. не .:/srv/app, а ./src:/srv/app/src и т. Д.
  • или сопоставить всю папку, но скопировать файлы поставщика из образа / контейнера на хост
  • или используйте стороннюю утилиту для решения именно этой проблемы, например, http://docker -sync.io или многие другие
...