¿Cuál es la diferencia entre Docker Compose y Dockerfile?

Resuelto Aaron Lelevier asked hace 9 años • 12 respuestas

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 FROMcomandos 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:

  1. Docker Compose no es compatible con Python3
  2. Quiero contener mi proyecto, por lo que si un Dockerfile grande no es ideal, entonces creo que necesitaría dividirlo usando Docker Compose.
  3. Estoy bien para hacer que el proyecto Py2 y Py3 sea compatible, así que me inclino por django-compose
Aaron Lelevier avatar Apr 07 '15 04:04 Aaron Lelevier
Aceptado

archivo acoplable

ingrese la descripción de la imagen aquí

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

ingrese la descripción de la imagen aquí

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.ymlpara 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: {}
code-8 avatar Aug 07 '2017 14:08 code-8

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 Dockerfilepara cada imagen que desee crear y luego usar componer para ensamblar las imágenes usando el buildcomando.

Puede especificar la ruta a sus Dockerfiles individuales usando build /path/to/dockerfiles/blahdónde vive /path/to/dockerfiles/blahBlah Dockerfile.

booyaa avatar Apr 07 '2015 08:04 booyaa

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.ymlarchivo.

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-servery el segundo node-app, y desea que se creen usando Dockerfileen 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.ymlarchivo, querrás comenzar la primera línea así:

version: '3'

Eso le dice a Docker la versión que docker-composedesea 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-composeque 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 8081mi máquina local al 8081contenedor 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.ymlarchivo 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.ymlarchivo 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-servery 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 myimagepara crear una instancia de todos los contenedores o servicios dentro del archivo, puedes ejecutarlo docker-compose upy no tienes que especificar una imagen porque Docker buscará en el directorio de trabajo actual y buscará una docker-compose.ymlarchivo 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-composemundo, 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-composefacilita 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.

Daniel avatar Dec 21 '2018 14:12 Daniel