library - Docker Compose vs. Dockerfile: ¿cuál es mejor?
download docker image (8)
El archivo Compose describe el contenedor en su estado de ejecución , dejando los detalles sobre cómo construir el contenedor en Dockerfiles . http://deninet.com/blog/1587/docker-scratch-part-4-compose-and-volumes
Cuando define su aplicación con Compose en desarrollo, puede usar esta definición para ejecutar su aplicación en diferentes entornos como CI, almacenamiento provisional y producción . https://docs.docker.com/compose/production/
También parece que Compose se considera seguro para la producción a partir de 1.11 , ya que https://docs.docker.com/v1.11/compose/production/ ya no tiene una advertencia de no usarlo en producción como https://docs.docker.com/v1.10/compose/production/ does.
He estado leyendo y aprendiendo sobre Docker , y estoy tratando de elegir correctamente la configuración de Django para usar. Hasta ahora hay:
Entiendo que los
Dockerfiles
se usan en
Docker Compose
, pero no estoy seguro de si es una buena práctica poner todo en un gran Dockerfile con múltiples comandos
FROM
para las diferentes imágenes.
Quiero usar varias imágenes diferentes que incluyen:
uwsgi
nginx
postgres
redis
rabbitmq
celery with cron
Indique cuáles son las mejores prácticas para configurar este tipo de entorno con Docker .
Si ayuda, estoy en una Mac, así que boot2docker usando boot2docker .
Algunos problemas que he tenido:
- Docker Compose no es compatible con Python3
- Quiero contener mi proyecto en contenedores, por lo que si un Dockerfile grande no es ideal, creo que tendré que romperlo con Docker Compose
- Estoy de acuerdo en hacer que el proyecto Py2 y Py3 sean compatibles, así que me estoy inclinando hacia django-compose
Dockerfile
Un Dockerfile es un archivo de texto simple que contiene los comandos que un usuario podría llamar para ensamblar una imagen.
Ejemplo, Dockerfile
FROM ubuntu:latest
MAINTAINER john doe
RUN apt-get update
RUN apt-get install -y python python-pip wget
RUN pip install Flask
ADD hello.py /home/hello.py
WORKDIR /home
Docker Compose
Docker Compose
-
es una herramienta para definir y ejecutar aplicaciones Docker de contenedores múltiples.
-
defina los servicios que componen su aplicación en
docker-compose.yml
para que puedan ejecutarse juntos en un entorno aislado. -
hacer que una aplicación se ejecute en un comando simplemente ejecutando
docker-compose up
Ejemplo, docker-compose.yml
version: "3"
services:
web:
build: .
ports:
- ''5000:5000''
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}
"mejor" es relativo. Todo depende de cuáles sean sus necesidades. Docker compose es para orquestar múltiples contenedores. Si estas imágenes ya existen en el registro de docker, es mejor enumerarlas en el archivo de redacción. Si estas imágenes u otras imágenes tienen que construirse a partir de archivos en su computadora, entonces puede describir los procesos de construcción de esas imágenes en un Dockerfile.
Entiendo que los Dockerfiles se usan en Docker Compose, pero no estoy seguro de si es una buena práctica poner todo en un gran Dockerfile con múltiples comandos FROM para las diferentes imágenes.
El uso de múltiples FROM en un solo dockerfile no es una muy buena idea porque hay una propuesta para eliminar la función. 13026
Si, por ejemplo, desea acoplar una aplicación que usa una base de datos y tener los archivos de la aplicación en su computadora, puede usar un archivo de composición junto con un dockerfile de la siguiente manera
docker-compose.yml
mysql:
image: mysql:5.7
volumes:
- ./db-data:/var/lib/mysql
environment:
- "MYSQL_ROOT_PASSWORD=secret"
- "MYSQL_DATABASE=homestead"
- "MYSQL_USER=homestead"
ports:
- "3307:3306"
app:
build:
context: ./path/to/Dockerfile
dockerfile: Dockerfile
volumes:
- ./:/app
working_dir: /app
Dockerfile
FROM php:7.1-fpm
RUN apt-get update && apt-get install -y libmcrypt-dev /
mysql-client libmagickwand-dev --no-install-recommends /
&& pecl install imagick /
&& docker-php-ext-enable imagick /
&& docker-php-ext-install pdo_mysql /
&& curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
En mi flujo de trabajo, agrego un Dockerfile para cada parte de mi sistema y lo configuro para que cada parte pueda ejecutarse individualmente. Luego agrego un docker-compose.yml para reunirlos y vincularlos.
Mayor ventaja (en mi opinión): al
vincular los contenedores
, puede definir un nombre y hacer ping a sus contenedores con este nombre.
Por lo tanto, su base de datos podría ser accesible con el nombre
db
y ya no por su IP.
Imagina que eres el gerente de una compañía de software y acabas de comprar un nuevo servidor. Solo el hardware.
Piense en
Dockerfile
como un conjunto de instrucciones que le diría a su administrador de sistema
qué instalar
en este nuevo servidor.
Por ejemplo:
- Necesitamos un linux Debian
- agregar un servidor web apache
- también necesitamos postgresql
- instalar el comandante de medianoche
-
cuando todo esté listo, copie todos los archivos * .php, * .jpg, etc. de nuestro proyecto en la raíz web del servidor web (
/var/www
)
Por el contrario, piense en
docker-compose.yml
como un conjunto de instrucciones que le diría a su administrador de sistemas
cómo el servidor puede interactuar
con el resto del mundo.
Por ejemplo,
- tiene acceso a una carpeta compartida desde otra computadora,
- su puerto 80 es el mismo que el puerto 8000 de la computadora host,
- y así.
(Esta no es una explicación precisa, pero es lo suficientemente buena para comenzar).
La respuesta es ninguno.
Docker Compose (en lo sucesivo denominado componer) usará el Dockerfile si agrega el comando de compilación al
docker-compose.yml
su proyecto.
Su flujo de trabajo de Docker debe ser crear un
Dockerfile
adecuado para cada imagen que desee crear, luego use componer para ensamblar las imágenes con el comando de
build
.
Puede especificar la ruta a sus Dockerfiles individuales usando
build /path/to/dockerfiles/blah
donde
/path/to/dockerfiles/blah
es donde vive el
Dockerfile
de blah.
Los Dockerfiles son para construir una imagen, por ejemplo, desde un Ubuntu
mywordpress
, puede agregar
mysql
llamado
mySQL
en una imagen y
mywordpress
en una segunda imagen llamada
mywordpress
.
Componer archivos YAML son para tomar estas imágenes y ejecutarlas de manera coherente.
por ejemplo, si tiene en su archivo
docker-compose.yml
una llamada de servicio
db
:
services:
db:
image: mySQL --- image that you built.
y un servicio llamado worpress como:
wordpress:
image: mywordpress
luego dentro del contenedor mywordpress puede usar
db
para conectarse a su contenedor mySQL.
Esta magia es posible porque su host Docker crea un puente de red (superposición de red).
docker-compose existe para evitar que tengas que escribir una tonelada de comandos que tendrías que hacer con docker-cli.
docker-compose también facilita el inicio de varios contenedores al mismo tiempo y los conecta automáticamente con alguna forma de red.
El propósito de docker-compose es funcionar como docker cli pero emitir múltiples comandos mucho más rápido.
Para usar docker-compose, debe codificar los comandos que estaba ejecutando antes en un archivo
docker-compose.yml
.
No solo va a copiar pegarlos en el archivo yaml, hay una sintaxis especial.
Una vez creado, debe alimentarlo al cli docker-compose y dependerá del cli analizar el archivo y crear todos los diferentes contenedores con la configuración correcta que especifiquemos.
Por lo tanto, tendrá contenedores separados, digamos, por ejemplo, uno es
redis-server
y el segundo es
node-app
y desea que se cree usando el
Dockerfile
en su directorio actual.
Además, después de hacer ese contenedor, asignaría algún puerto desde el contenedor a la máquina local para acceder a todo lo que se ejecuta dentro de él.
Entonces, para su archivo
docker-compose.yml
, querrá comenzar la primera línea de esta manera:
version: ''3''
Eso le dice a Docker la versión de
docker-compose
que desea usar.
Después de eso tienes que agregar:
version: ''3''
services:
redis-server:
image: ''redis''
node-app:
build: .
Tenga en cuenta la sangría, muy importante.
Además, observe que para un servicio estoy tomando una imagen, pero para otro servicio le estoy diciendo a
docker-compose
que busque dentro del directorio actual para construir la imagen que se usará para el segundo contenedor.
Luego, desea especificar todos los puertos diferentes que desea abrir en este contenedor.
version: ''3''
services:
redis-server:
image: ''redis''
node-app:
build: .
ports:
-
Tenga en cuenta el guión, un guión en un archivo yaml es cómo especificamos una matriz.
En este ejemplo, estoy asignando
8081
en mi máquina local a
8081
en el contenedor de esta manera:
version: ''3''
services:
redis-server:
image: ''redis''
node-app:
build: .
ports:
- "8081:8081"
Entonces, el primer puerto es su máquina local, y el otro es el puerto en el contenedor, también puede distinguir entre los dos para evitar confusión de la siguiente manera:
version: ''3''
services:
redis-server:
image: ''redis''
node-app:
build: .
ports:
- "4001:8081"
Al desarrollar su archivo
docker-compose.yml
como este, creará estos contenedores esencialmente en la misma red y tendrán acceso libre para comunicarse entre ellos de la forma que deseen e intercambiar la información que deseen.
Cuando los dos contenedores se crean usando
docker-compose
, no necesitamos ninguna declaración de puerto.
Ahora, en mi ejemplo, necesitamos hacer una configuración de código en la aplicación Nodejs que se vea así:
const express = require(''express'');
const redis = require(''redis'');
const app = express();
const client = redis.createClient({
host: ''redis-server''
});
Utilizo este ejemplo anterior para hacerle saber que puede haber alguna configuración específica que tendría que hacer además del archivo
docker-compose.yml
que puede ser específico para su proyecto.
Ahora, si alguna vez te encuentras trabajando con una aplicación Nodejs y redis, quieres asegurarte de que conoces el puerto predeterminado que usa Nodejs, así que agregaré esto:
const express = require(''express'');
const redis = require(''redis'');
const app = express();
const client = redis.createClient({
host: ''redis-server'',
port: 6379
});
Entonces, Docker verá que la aplicación Node está buscando
redis-server
y redirigirá esa conexión a este contenedor en ejecución.
Todo el tiempo, el
Dockerfile
solo contiene esto:
FROM node:alpine
WORKDIR ''/app''
COPY /package.json ./
RUN npm install
COPY . .
CMD ["npm", "start"]
Entonces, mientras que antes de tener que ejecutar
docker run myimage
para crear una instancia de todos los contenedores o servicios dentro del archivo que puede ejecutar,
docker-compose up
y no tiene que especificar una imagen porque Docker buscará en el directorio de trabajo actual y busque un archivo
docker-compose.yml
dentro de allí.
Antes de
docker-compose.yml
, teníamos que lidiar con dos comandos separados de
docker build .
de
docker build .
y
docker run myimage
, pero en el mundo de
docker-compose
si desea reconstruir sus imágenes, escriba
docker-compose up --build
.
Eso le dice a Docker que vuelva a iniciar los contenedores pero que lo reconstruya para obtener los últimos cambios.
Por lo tanto,
docker-compose
facilita el trabajo con múltiples contenedores.
La próxima vez que necesite iniciar este grupo de contenedores en segundo plano puede hacer
docker-compose up -d
y para detenerlos puede hacer
docker-compose down
.