¿Cuál es la diferencia entre Docker Compose y Dockerfile?
He estado leyendo y aprendiendo sobre Docker y estoy tratando de elegir correctamente la configuración de Django que usaré. Hasta ahora existe:
Docker Compose o 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 Dockerfile grande con múltiples FROM
comandos para las diferentes imágenes.
Quiero usar varias imágenes diferentes que incluyan:
uwsgi
nginx
postgres
redis
rabbitmq
celery with cron
Indique cuáles son las mejores prácticas para configurar este tipo de entorno utilizando Docker .
Si me ayuda, estoy en una Mac, así que uso boot2docker .
Algunos problemas que he tenido:
- Docker Compose no es compatible con Python3
- Quiero contener mi proyecto, por lo que si un Dockerfile grande no es ideal, entonces creo que necesitaría dividirlo usando Docker Compose.
- Estoy bien para hacer que el proyecto Py2 y Py3 sea compatible, así que me inclino por django-compose
archivo acoplable
Un Dockerfile es un archivo de texto simple que contiene los comandos que un usuario puede llamar para ensamblar una imagen.
Ejemplo, archivo Docker
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
Composición acoplable
Composición acoplable
es una herramienta para definir y ejecutar aplicaciones Docker de múltiples contenedores.
Defina los servicios que componen su aplicación
docker-compose.yml
para que puedan ejecutarse juntos en un entorno aislado.haga que una aplicación se ejecute con un solo 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: {}
La respuesta es ninguna.
Docker Compose (en adelante denominado compose) utilizará el Dockerfile si agrega el comando de compilación al archivo docker-compose.yml
.
Su flujo de trabajo de Docker debe consistir en crear una imagen adecuada Dockerfile
para cada imagen que desee crear y luego usar componer para ensamblar las imágenes usando el build
comando.
Puede especificar la ruta a sus Dockerfiles individuales usando build /path/to/dockerfiles/blah
dónde vive /path/to/dockerfiles/blah
Blah Dockerfile
.
docker-compose existe para que tengas que escribir un montón de comandos que tendrías que escribir con docker-cli.
Docker-compose también facilita el inicio de varios contenedores al mismo tiempo y los conecta automáticamente con algún tipo de red.
El propósito de docker-compose es funcionar como docker cli pero emitir múltiples comandos mucho más rápidamente.
Para utilizar Docker-Compose, debe codificar los comandos que estaba ejecutando antes en un docker-compose.yml
archivo.
No solo los copiará y pegará en el archivo yaml, hay una sintaxis especial.
Una vez creado, debe enviarlo a la CLI de Docker-Compose y dependerá de la CLI analizar el archivo y crear todos los diferentes contenedores con la configuración correcta que especifiquemos.
Entonces tendrá contenedores separados, digamos, uno redis-server
y el segundo node-app
, y desea que se creen usando Dockerfile
en su directorio actual.
Además, después de crear ese contenedor, asignará algún puerto del contenedor a la máquina local para acceder a todo lo que se ejecuta dentro de él.
Entonces, para tu docker-compose.yml
archivo, querrás comenzar la primera línea así:
version: '3'
Eso le dice a Docker la versión que docker-compose
desea usar. Después de eso, debes agregar:
version: '3'
services:
redis-server:
image: 'redis'
node-app:
build: .
Observe la sangría, muy importante. Además, observe que para un servicio estoy tomando una imagen, pero para otro servicio le digo docker-compose
que mire dentro del directorio actual para crear 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:
-
Observe el guión, un guión en un archivo yaml es la forma en que especificamos una matriz. En este ejemplo, estoy asignando 8081
mi máquina local al 8081
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 confusiones de la siguiente manera:
version: '3'
services:
redis-server:
image: 'redis'
node-app:
build: .
ports:
- "4001:8081"
Al desarrollar su docker-compose.yml
archivo de esta manera, creará estos contenedores esencialmente en la misma red y tendrán acceso libre para comunicarse entre sí de la forma que quieran e intercambiar tanta información como quieran.
Cuando los dos contenedores se crean usando docker-compose
, no necesitamos ninguna declaración de puerto.
Ahora, en mi ejemplo, necesitamos realizar una configuración de código en la aplicación Nodejs que se parece a esto:
const express = require('express');
const redis = require('redis');
const app = express();
const client = redis.createClient({
host: 'redis-server'
});
Utilizo este ejemplo anterior para informarle que es posible que deba realizar alguna configuración específica además del docker-compose.yml
archivo que puede ser específico de su proyecto.
Ahora, si alguna vez te encuentras trabajando con una aplicación de Nodejs y Redis, querrás asegurarte de conocer el puerto predeterminado que utiliza 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
único contiene esto:
FROM node:alpine
WORKDIR '/app'
COPY /package.json ./
RUN npm install
COPY . .
CMD ["npm", "start"]
Entonces, mientras que antes tendrías que ejecutar docker run myimage
para crear una instancia de todos los contenedores o servicios dentro del archivo, puedes ejecutarlo docker-compose up
y no tienes que especificar una imagen porque Docker buscará en el directorio de trabajo actual y buscará una docker-compose.yml
archivo en el interior.
Antes docker-compose.yml
, teníamos que lidiar con dos comandos separados de docker build .
y docker run myimage
, pero en el docker-compose
mundo, si quieres reconstruir tus imágenes, escribes docker-compose up --build
. Eso le dice a Docker que inicie los contenedores nuevamente pero que los reconstruya para obtener los últimos cambios.
Esto docker-compose
facilita el trabajo con múltiples contenedores. La próxima vez que necesites iniciar este grupo de contenedores en segundo plano, puedes hacerlo docker-compose up -d
; y para detenerlos, puedes hacer docker-compose down
.