web-dev-qa-db-fra.com

Docker Compose contre Dockerfile - quel est le meilleur?

Je lisais et apprenais sur Docker , et j'essaie de choisir correctement la configuration Django à utiliser. Jusqu'à présent, il y a soit:

Docker Compose ou Dockerfile

Je comprends que Dockerfiles sont utilisés dans Docker Compose, mais je ne suis pas sûr que ce soit une bonne pratique de tout mettre dans un grand fichier Docker avec plusieurs commandes FROM pour les différentes images?

Je veux utiliser plusieurs images différentes, notamment:

uwsgi
nginx
postgres
redis
rabbitmq
celery with cron

Veuillez indiquer quelles sont les meilleures pratiques pour configurer ce type d’environnement à l’aide de Docker .

Si cela peut aider, je suis sur un Mac, donc j'utilise boot2docker .

Quelques problèmes que j'ai eu:

  1. Docker Compose n'est pas compatible avec Python3
  2. Je souhaite conteneuriser mon projet. Par conséquent, si un fichier Docker de grande taille n'est pas idéal, je pense que je devrais le décomposer à l'aide de Docker Compose.
  3. Je suis d'accord pour rendre le projet Py2 & Py3 compatible, donc penchez-vous vers Django-compose
297
Aaron Lelevier

La réponse est non plus.

Docker Compose (appelé ci-après composera) utilisera le fichier Docker si vous ajoutez la commande de construction au fichier docker-compose.yml de votre projet.

Votre flux de travail Docker doit consister à créer un Dockerfile approprié pour chaque image à créer, puis à utiliser Composer pour assembler les images à l'aide de la commande build.

Vous pouvez spécifier le chemin d'accès à vos fichiers Docker individuels en utilisant build /path/to/dockerfiles/blah/path/to/dockerfiles/blah est le lieu de résidence de blah's Dockerfile.

186
booyaa

Dockerfile

enter image description here

Un fichier Dockerfile est un simple fichier texte contenant les commandes qu'un utilisateur peut appeler pour assembler une image.

Exemple, 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

enter image description here

Docker Compose

  • est un outil permettant de définir et d’exécuter des applications Docker contenant plusieurs conteneurs.

  • définissez les services qui composent votre application dans docker-compose.yml afin qu'ils puissent être exécutés ensemble dans un environnement isolé.

  • obtenir une application en cours d'exécution dans une commande en exécutant simplement docker-compose up

Exemple, docker-compose.yml

version: "3"
services:
  web:
    build: .
    ports:
    - '5000:5000'
    volumes:
    - .:/code
    - logvolume01:/var/log
    links:
    - redis
  redis:
    image: redis
    volumes:
      logvolume01: {}
413
kyo

Le fichier Compose décrit le conteneur dans son état d'exécution , en laissant les détails. sur comment construire le conteneur en Dockerfiles . http://deninet.com/blog/1587/docker-scratch-part-4-compose-and-volumes

Lorsque vous définissez votre application avec Compose en développement, , vous pouvez utiliser cette définition pour exécuter votre application en mode différents environnements tels que , mise en scène et production . https://docs.docker.com/compose/production/

Il semble également que Compose soit considéré comme sûr de production à compter de 1.11 , puisque https://docs.docker.com/v1.11/compose/production / ne plus avertissement de ne pas l'utiliser en production comme https://docs.docker.com/v1.10/compose/production/ le fait.

81
Peeter Kokk

docker-compose existe pour que vous ayez à écrire une tonne de commandes avec docker-cli.

docker-compose facilite également le démarrage de plusieurs conteneurs à la fois et les connecte automatiquement avec une forme de mise en réseau.

Le but de docker-compose est de fonctionner comme docker cli mais d’émettre plusieurs commandes beaucoup plus rapidement.

Pour utiliser docker-compose, vous devez encoder les commandes que vous avez exécutées auparavant dans un fichier docker-compose.yml.

Vous n'allez pas simplement copier-coller dans le fichier yaml, il existe une syntaxe spéciale.

Une fois créé, vous devez l'envoyer à la cli docker-compose et ce sera à la cli d'analyser le fichier et de créer tous les différents conteneurs avec la configuration correcte spécifiée.

Donc vous aurez des conteneurs séparés, disons par exemple, l’un est redis-server et le second est node-app et vous voulez le créer avec le Dockerfile de votre répertoire actuel.

De plus, après avoir créé ce conteneur, vous devez mapper un port du conteneur sur la machine locale pour accéder à tout ce qui se passe à l'intérieur.

Donc, pour votre fichier docker-compose.yml, vous voudriez commencer la première ligne comme suit:

version: '3'

Cela indique à Docker la version de docker-compose que vous souhaitez utiliser. Après cela, vous devez ajouter:

version: '3'
services: 
  redis-server: 
    image: 'redis'
  node-app:
    build: .

S'il vous plaît noter l'indentation, très important. En outre, notez que pour un service, je suis en train de récupérer une image, mais pour un autre service, je dis à docker-compose de regarder dans le répertoire en cours pour créer l'image qui sera utilisée pour le second conteneur.

Ensuite, vous voulez spécifier tous les différents ports que vous voulez ouvrir sur ce conteneur.

version: '3'
services: 
  redis-server: 
    image: 'redis'
  node-app:
    build: .
    ports:
      -

Veuillez noter le tiret, un tiret dans un fichier yaml est la façon dont nous spécifions un tableau. Dans cet exemple, je mappe 8081 sur ma machine locale à 8081 sur le conteneur de la manière suivante:

version: '3'
services: 
  redis-server: 
    image: 'redis'
  node-app:
    build: .
    ports:
      - "8081:8081"

Ainsi, le premier port est votre machine locale et l’autre est le port du conteneur. Vous pouvez également distinguer les deux pour éviter toute confusion, de la manière suivante:

version: '3'
services:
  redis-server:
    image: 'redis'
  node-app:
    build: .
    ports:
      - "4001:8081"

En développant votre fichier docker-compose.yml comme celui-ci, il créera ces conteneurs sur le même réseau et leur permettra de communiquer librement les uns avec les autres et d’échanger autant d’informations qu’ils le souhaitent.

Lorsque les deux conteneurs sont créés à l'aide de docker-compose, nous n'avons besoin d'aucune déclaration de port.

Maintenant, dans mon exemple, nous devons faire une configuration de code dans l'application Nodejs qui ressemble à ceci:

const express = require('express');
const redis = require('redis');

const app = express();
const client = redis.createClient({
  Host: 'redis-server'
});

J'utilise cet exemple ci-dessus pour vous informer que vous devrez peut-être effectuer une configuration spécifique en plus du fichier docker-compose.yml qui peut être spécifique à votre projet.

Maintenant, si vous vous retrouvez avec une application Nodejs et que vous voulez bien vous assurer que vous êtes au courant du port par défaut utilisé par Nodejs, je vais ajouter ceci:

const express = require('express');
const redis = require('redis');

const app = express();
const client = redis.createClient({
  Host: 'redis-server',
  port: 6379
});

Donc, Docker va voir que l'application Node cherche redis-server et redirige cette connexion vers ce conteneur en cours d'exécution.

Tout le temps, la Dockerfile ne contient que ceci:

FROM node:Alpine

WORKDIR '/app'

COPY /package.json ./
RUN npm install
COPY . .

CMD ["npm", "start"]

Ainsi, alors qu'avant, vous devriez exécuter docker run myimage pour créer une instance de tous les conteneurs ou services du fichier que vous pouvez exécuter, docker-compose up et vous n'avez pas à spécifier d'image car Docker regardez dans le répertoire de travail actuel et cherchez un fichier docker-compose.yml à l'intérieur.

Avant docker-compose.yml, nous devions traiter deux commandes distinctes de docker build . et docker run myimage, mais dans le monde docker-compose si vous voulez reconstruire vos images, vous écrivez docker-compose up --build. Cela demande à Docker de redémarrer les conteneurs mais de le reconstruire pour obtenir les dernières modifications.

Donc, docker-compose facilite le travail avec plusieurs conteneurs. La prochaine fois que vous devrez démarrer ce groupe de conteneurs en arrière-plan, vous pourrez effectuer docker-compose up -d et pour les arrêter, vous pourrez effectuer docker-compose down.

43
Daniel

Dans mon flux de travail, j'ajoute un fichier Docker pour chaque partie de mon système et le configure pour que chaque partie puisse être exécutée individuellement. Ensuite, j'ajoute un fichier docker-compose.yml pour les réunir et les lier.

Le plus gros avantage (à mon avis): quand reliant les conteneurs , vous pouvez définir un nom et envoyer une requête ping à vos conteneurs avec ce nom. Par conséquent, votre base de données peut être accessible avec le nom db et non plus par son adresse IP.

41
n2o

"mieux" est relatif. Tout dépend de vos besoins. Docker compose est destiné à orchestrer plusieurs conteneurs. Si ces images existent déjà dans le registre de docker, il est préférable de les répertorier dans le fichier de composition. Si ces images ou d'autres images doivent être créées à partir de fichiers de votre ordinateur, vous pouvez décrire le processus de création de ces images dans un fichier Docker.

Je comprends que les fichiers Dockerfiles sont utilisés dans Docker Compose, mais je ne suis pas sûr que ce soit une bonne pratique de tout mettre dans un grand fichier Dockerfile avec plusieurs commandes FROM pour les différentes images?

L'utilisation de plusieurs FROM dans un seul fichier docker n'est pas une très bonne idée car il est proposé de supprimer la fonctionnalité. 13026

Si, par exemple, vous souhaitez dockériser une application qui utilise une base de données et que les fichiers de l’application se trouvent sur votre ordinateur, vous pouvez utiliser un fichier de composition avec un fichier docker comme suit:

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
28
Akongnwi Devert

Imaginez que vous dirigiez une société de logiciels et que vous venez d’acheter un nouveau serveur. Juste le matériel.

Pensez à Dockerfile comme à un ensemble d’instructions à adresser à votre administrateur système ce qu’il faut installer sur ce tout nouveau serveur. Par exemple:

  • Nous avons besoin d'un linux Debian
  • ajouter un serveur web Apache
  • nous avons aussi besoin de postgresql
  • installer le commandant de minuit
  • quand tout est terminé, copiez tous les fichiers * .php, * .jpg, etc. de notre projet dans la racine du serveur Web (/var/www)

En revanche, considérez docker-compose.yml comme un ensemble d’instructions à adresser à votre administrateur système comment le serveur peut-il interagir avec le reste du monde. Par exemple,

  • il a accès à un dossier partagé depuis un autre ordinateur,
  • son port 80 est identique à celui du port 8000 de l'ordinateur hôte,
  • etc.

(Ce n'est pas une explication précise mais suffisante pour commencer.)

6
Csongor Halmai

Les fichiers Dock doivent créer une image, par exemple, à partir d’un os simple Ubuntu. Vous pouvez ajouter mysql appelé mySQL sur une image et mywordpress sur une deuxième image appelée mywordpress.

Les fichiers YAML composés doivent prendre ces images et les exécuter de manière cohérente. Par exemple, si vous avez dans votre fichier docker-compose.yml un appel de service db:

services:
   db:
     image: mySQL  --- image that you built.

et un service appelé worpress tel que:

wordpress: 
    image: mywordpress

ensuite, dans le conteneur mywordpress, vous pouvez utiliser db pour vous connecter à votre conteneur mySQL. Cette magie est possible parce que votre hôte docker crée un pont réseau (superposition réseau).

3
Hugo R