Investigamos por diferentes espacios para de este modo traerte la solución a tu dilema, si tienes alguna inquietud puedes dejarnos la pregunta y te contestaremos porque estamos para servirte.
Solución:
En general, estoy de acuerdo con la respuesta de Chris para el desarrollo local. Voy a ofrecer algo que se combina con una característica reciente de Docker que puede establecer un camino para realizar tanto el desarrollo local como la eventual implementación de producción con la misma imagen.
Comencemos primero con la imagen que podemos construir de una manera que pueda usarse para el desarrollo local o la implementación en algún lugar que contenga el código y las dependencias. En la última versión de Docker (17.05) hay una nueva función de compilación de varias etapas que podemos aprovechar. En este caso, primero podemos instalar todas las dependencias de Composer en una carpeta en el contexto de compilación y luego copiarlas en la imagen final sin necesidad de agregar Composer a la imagen final. Esto podría verse como:
FROM composer as composer
COPY . /app
RUN composer install --ignore-platform-reqs --no-scripts
FROM php:fpm
WORKDIR /var/www/root/
RUN apt-get update && apt-get install -y
libfreetype6-dev
libjpeg62-turbo-dev
libmcrypt-dev
libpng12-dev
zip
unzip
&& docker-php-ext-install -j$(nproc) iconv mcrypt
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/
&& docker-php-ext-install -j$(nproc) gd
&& docker-php-ext-install mysqli
&& docker-php-ext-enable opcache
COPY . /var/www/root
COPY --from=composer /app/vendor /var/www/root/vendor
Esto elimina todo Composer de la imagen de la aplicación y, en su lugar, utiliza la primera etapa para instalar las dependencias en otro contexto y copiarlas en la imagen final.
Ahora, durante el desarrollo tienes algunas opciones. Basado en tu docker-compose.yml
comando parece que está montando la aplicación en el contenedor como .:/var/www/root
. Podrías agregar un composer
servicio a su docker-compose.yml
similar a mi ejemplo en https://gist.github.com/andyshinn/e2c428f2cd234b718239. Aquí, solo haces docker-compose run --rm composer install
cuando necesite actualizar las dependencias localmente (esto mantiene las dependencias creadas dentro del contenedor, lo que podría ser importante para las extensiones compiladas nativas, especialmente si está implementando como contenedores y desarrollando en Windows o Mac).
La otra opción es simplemente hacer algo similar a lo que Chris ya sugirió y usar la imagen oficial de Composer para actualizar y administrar las dependencias cuando sea necesario. He hecho algo como esto localmente antes donde tenía dependencias privadas en GitHub que requerían autenticación SSH:
docker run --rm --interactive --tty
--volume $PWD:/app:rw,cached
--volume $SSH_AUTH_SOCK:/ssh-auth.sock
--env SSH_AUTH_SOCK=/ssh-auth.sock
--volume $COMPOSER_HOME:/composer
composer:1.4 install --ignore-platform-reqs --no-scripts
En resumen, el razonamiento de este método de construir la imagen e instalar las dependencias de Composer usando un contenedor/servicio externo:
- Las dependencias específicas de la plataforma se crearán correctamente para el contenedor (arquitectura Linux frente a Windows o Mac).
- No se requiere Composer o PHP en su computadora local (todo está contenido dentro de Docker y Docker Compose).
- La imagen inicial que creó se puede ejecutar y desplegar sin necesidad de montar código en ella. En desarrollo, solo está anulando el
/var/www/root
carpeta con un volumen local.
He estado en esta madriguera de conejo durante 5 horas, todas las soluciones que existen son demasiado complicadas. La solución más sencilla es excluir del volumen los directorios de proveedor o node_modules y similares.
#docker-compose.yml
volumes:
- .:/srv/app/
- /srv/app/vendor/
Así que esto mapeará el directorio del proyecto actual pero excluirá su subdirectorio de proveedor. ¡No olvides la barra inclinada final!
Entonces, ahora puede ejecutar fácilmente la instalación del compositor en Dockerfile y cuando Docker monte su volumen, ignorará el directorio del proveedor.