Siguiendo Docker + Laravel =? Quiero hablar sobre una forma bastante inusual de usar la utilidad docker-compose.
Para empezar, para aquellos que no saben por qué se necesita docker-compose. Esta es una utilidad que le permite ejecutar en un host separado un conjunto de servicios relacionados empaquetados en contenedores acoplables. La versión inicial fue escrita en python y podría instalarse de dos maneras:
- a través del administrador de paquetes del sistema operativo (
apt install docker-compose
para Ubuntu y yum install docker-compose.noarch
para Centos) - a través del administrador de dependencias de python (
pip install docker-compose
)
El problema con el primer método es que generalmente se encuentra en los repositorios del sistema operativo docker-compose de la versión anterior. Este es un problema si necesita usar la última versión del demonio docker o usar características específicas de una versión específica del formato de archivo docker-compose.yaml (la matriz de características compatibles por versiones de formato y versiones de la utilidad docker-compose se puede encontrar en el sitio web oficial de docker).
Ahora desarrolladores de Docker reescribió la utilidad sobre la marcha , cometió un error, en realidad empaquetó el script de Python con el entorno en un solo paquete y lo proporcionó como un archivo binario, lo que le permite instalarlo de la siguiente manera (este es el método recomendado actualmente):
Miramos la última versión en https://github.com/docker/compose/releases y la descargamos
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
establecer los derechos para ejecutar la aplicación
$ sudo chmod +x /usr/local/bin/docker-compose
Además, puede configurar la finalización automática para los intérpretes de comandos bash y zsh
verificar instalación
$ docker-compose --version docker-compose version 1.22.0, build 1719ceb
Creo que un solo binario es genial, porque no necesitamos extraer dependencias de python. Sí, y en general, ¡tal vez nuestro entorno de Python esté completamente roto en la máquina de destino, que queremos configurar!

Ejemplo de confusión en entorno python
Pero todavía hay un cuarto camino, del que quería hablar. Esta es la capacidad de ejecutar docker-compose a través de docker. De hecho, ya hay imágenes oficiales recopiladas en Docker Hub ( https://hub.docker.com/r/docker/compose/ ). ¿Por qué podrían ser necesarios?
- si queremos trabajar con varias versiones de docker-compose al mismo tiempo (aunque generalmente la última versión estable es suficiente)
- si no tenemos Python o no queremos usarlo (por ejemplo, tenemos una distribución ligera de CoreOS Container Linux )
- uso en tuberías de CI / CD.
¡Intentémoslo!
Como solíamos lanzar contenedores:
$ docker-compose up -d
A través de una utilidad empaquetada en un contenedor acoplable:
$ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v "$PWD:/rootfs/$PWD" -w="/rootfs/$PWD" docker/compose:1.13.0 up -d
Demasiado detallado, ¿eh? El cerebro puede romperse para recordar todos estos parámetros. Por lo tanto, intentaremos hacer nuestra vida más fácil y escribir un contenedor en lenguaje shell. Pero primero, veamos los parámetros pasados:
--rm
- elimina el contenedor temporal después de detenerse, es decir no dejamos basura en el sistema-v /var/run/docker.sock:/var/run/docker.sock
: sin esto, docker-compose no podrá conectarse al docker daemon en el host-v "$PWD:/rootfs/$PWD" -w="/rootfs/$PWD"
- le permite reenviar el directorio actual dentro del contenedor para que la utilidad vea el archivo docker-compose
Todavía nos falta la capacidad de interpolar valores en el archivo docker-compose. Este es el proceso mediante el cual la utilidad sustituye las variables de entorno en un archivo YAML. Por ejemplo, en un fragmento
version: "2.1" services: pg: image: postgres:9.6 environment: POSTGRES_USER: ${POSTGRES_DB_USER} POSTGRES_PASSWORD: ${POSTGRES_DB_PASSWORD}
las variables POSTGRES_DB_USER
y POSTGRES_DB_PASSWORD
se leerán del entorno. Esto hace posible crear plantillas de archivos compuestos por docker con un cierto grado de conveniencia. Es decir necesitamos capturar el entorno de la máquina host y transferirlo dentro del contenedor.
Resolvamos el problema escribiendo un script bash.
#!/bin/sh # TMPFILE=$(mktemp) # env > "${TMPFILE}" # VERSION="1.13.0" # docker-compose docker run \ --rm \ -e PWD="$PWD" \ --env-file "${TMPFILE}" \ -v /var/run/docker.sock:/var/run/docker.sock \ -v "$PWD:/rootfs/$PWD" \ -w="/rootfs/$PWD" \ docker/compose:"${VERSION}" \ "$@" # rm "{$TMPFILE}"
Líneas adicionales aparecieron:
-e PWD="$PWD"
- por si acaso, reenvíe el directorio actual--env-file "${TMPFILE}"
- aquí todas las demás variables de entorno se transfieren desde la máquina hostdocker/compose:"${VERSION}"
- el nombre de la imagen, toma la versión de la variable"$@"
: esta construcción le permite usar el script como si fuera la utilidad docker-compose, es decir pasa sus argumentos de forma transparente al contenedor acoplable.
Podemos guardar el script, por ejemplo, en /usr/local/bin/docker-compose
, establecer el indicador eXecute en él y usarlo. El script anterior no pretende estar 100% libre de errores o deficiencias y es más bien una ilustración del método.
Nosotros mismos usamos las canalizaciones de CI / CD de esta manera. Esto incluso ahorra algo de tráfico en cierta medida. La imagen de destino de la ventana acoplable se toma del caché local.