Контекст
Недавно я настроил приложение PHP для работы в док-контейнере, подключенном к базе данных в другом контейнере.
В производстве мы используем единую контейнерную среду, поскольку она просто подключается к базе данных, которая размещена где-то еще. Тем не менее, мы решили использовать два контейнера и docker-compose локально для облегчения процесса разработки.
Проблема
Проблема, с которой мы столкнулись, заключается в том, что в первый раз, когда мы собираем и запускаем приложение через docker-compose up --build
каталог vendor
Composer, недоступен в контейнере, даже если у нас была RUN composer install
конкретная строка в Dockerfile
. Мы должны были бы выполнить composer install
из контейнера, как только он был запущен.
Решение найдено
После долгих поисков мы решили, что у нас есть два возможных решения:
- измените команду по умолчанию нашего образа Docker на следующую:
bash -c "composer install && /usr/sbin/apache2ctl -D FOREGROUND"
- Или просто переопределить команду по умолчанию для контейнера с помощью команды docker-compose
command
.
Разница в том, что если мы переопределим команду с помощью docker-compose, при развертывании приложения на нашем сервере оно будет работать без проблем, как и должно, но при изменении команды по умолчанию в Dockerfile
оно получит 1 минутное время простоя при каждом развертывании.
Это помогло во время этого процесса:
- Запуск установки composer в Dockerfile
Некоторые (возможно, неправильные) выводы
Я пришел к выводу, что эта минута простоя была вызвана тем, что контейнеру пришлось установить все зависимости через composer перед запуском сервера Apache, а не просто запустив сервер.
Кроме того, еще один вывод, который я сделал из всего этого, заключается в том, что причина, по которой docker-compose up --build
не установил зависимости компоновщика, заключалась в том, что у нас был указан том в docker-compose.yml
, который переопределял каталоги в контейнере.
Это помогло:
https://stackoverflow.com/a/38817651/4700998
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