wake-up-neo.net

Docker Compose vs. Dockerfile - was ist besser?

Ich habe nachgelesen und etwas über Docker gelernt und versuche, das zu verwendende Django-Setup korrekt auszuwählen. Bisher gibt es entweder:

Docker Compose oder Dockerfile

Ich verstehe, dass Dockerfiles in Docker Compose verwendet werden, aber ich bin nicht sicher, ob es eine gute Praxis ist, alles in ein großes Dockerfile mit mehreren FROM Befehlen für die verschiedenen Bilder zu packen.

Ich möchte verschiedene Bilder verwenden, darunter:

uwsgi
nginx
postgres
redis
rabbitmq
celery with cron

Informieren Sie sich über bewährte Methoden zum Einrichten dieser Art von Umgebung mit Docker .

Wenn es hilft, bin ich auf einem Mac, also benutze ich boot2docker .

Einige Probleme, die ich hatte:

  1. Docker Compose ist nicht mit Python3 kompatibel
  2. Ich möchte mein Projekt containerisieren. Wenn also eine große Docker-Datei nicht ideal ist, muss sie meiner Meinung nach mit Docker Compose aufgelöst werden
  3. Ich bin in der Lage, das Projekt Py2 & Py3 kompatibel zu machen, also neige ich zu Django-Compose
297
Aaron Lelevier

Die Antwort ist weder.

Docker Compose (hier als Compose bezeichnet) verwendet die Docker-Datei, wenn Sie den Befehl build zum docker-compose.yml Ihres Projekts hinzufügen.

Ihr Docker-Arbeitsablauf sollte darin bestehen, für jedes zu erstellende Bild ein geeignetes Dockerfile zu erstellen und die Bilder mit dem Befehl build zusammenzusetzen.

Sie können den Pfad zu Ihren individuellen Docker-Dateien mit build /path/to/dockerfiles/blah angeben, wobei /path/to/dockerfiles/blah der Wohnort von blahs Dockerfile ist.

186
booyaa

Dockerfile

enter image description here

Eine Docker-Datei ist eine einfache Textdatei, die die Befehle enthält, die ein Benutzer zum Zusammenstellen eines Bildes aufrufen kann.

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

  • ist ein Tool zum Definieren und Ausführen von Docker-Anwendungen mit mehreren Containern.

  • definieren Sie die Services, aus denen Ihre App besteht, in docker-compose.yml, damit sie in einer isolierten Umgebung zusammen ausgeführt werden können.

  • starte eine App mit einem einzigen Befehl, indem du docker-compose up ausführst

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

Die Compose -Datei beschreibt den Container in seinem laufenden Zustand, wobei die Details zur Erstellung des Containers bis Dockerfiles verbleiben . http://deninet.com/blog/1587/docker-scratch-part-4-compose-and-volumes

Wenn Sie Ihre App mit Compose in der Entwicklung definieren, können Sie diese Definition verwenden, um Ihre Anwendung in verschiedenen Umgebungen auszuführen, z. B. CI, Staging und Produktion =. https://docs.docker.com/compose/production/

Es scheint auch, dass Compose als produktionssicher ab 1.11 gilt, da https://docs.docker.com/v1.11/compose/production/ nicht mehr hat Eine Warnung, es nicht in der Produktion zu verwenden, wie https://docs.docker.com/v1.10/compose/production/ .

81
Peeter Kokk

docker-compose gibt es, damit Sie eine Menge Befehle schreiben müssen, die Sie mit docker-cli benötigen würden.

mit docker-compose ist es auch einfach, mehrere Container gleichzeitig zu starten und sie automatisch über eine Netzwerkverbindung miteinander zu verbinden.

Der Zweck von Docker-Compose besteht darin, als Docker-CLI zu fungieren, aber mehrere Befehle viel schneller auszuführen.

Um Docker-Compose nutzen zu können, müssen Sie die zuvor ausgeführten Befehle in eine docker-compose.yml -Datei codieren.

Sie werden nicht nur kopiert, sondern auch in die yaml-Datei eingefügt. Es gibt eine spezielle Syntax.

Einmal erstellt, müssen Sie es an die Docker-Compose-Cli weiterleiten, und es liegt an der Cli, die Datei zu analysieren und alle verschiedenen Container mit der von uns angegebenen korrekten Konfiguration zu erstellen.

Sie haben also separate Container, zum Beispiel, einer ist redis-server und der zweite ist node-app und Sie möchten, dass dieser Container mit Dockerfile in Ihrem aktuellen Verzeichnis erstellt wird.

Nachdem Sie diesen Container erstellt haben, ordnen Sie dem lokalen Computer einen Port zu, um auf alle darin ausgeführten Komponenten zuzugreifen.

Für Ihre docker-compose.yml -Datei möchten Sie die erste Zeile also wie folgt beginnen:

version: '3'

Das teilt Docker mit, welche Version von docker-compose Sie verwenden möchten. Danach müssen Sie hinzufügen:

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

Bitte beachten Sie den Einzug, sehr wichtig. Beachten Sie auch, dass ich für einen Dienst ein Image greife, für einen anderen Dienst jedoch docker-compose anweise, in das aktuelle Verzeichnis zu schauen, um das Image zu erstellen, das für den zweiten Container verwendet wird.

Dann möchten Sie alle verschiedenen Ports angeben, die für diesen Container geöffnet werden sollen.

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

Bitte beachten Sie den Bindestrich, ein Bindestrich in einer Yaml-Datei gibt ein Array an. In diesem Beispiel ordne ich 8081 auf meinem lokalen Computer 8081 auf dem Container wie folgt zu:

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

Der erste Port ist also Ihr lokaler Computer, und der andere ist der Port im Container. Sie können also auch zwischen beiden unterscheiden, um Verwechslungen zu vermeiden:

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

Wenn Sie Ihre docker-compose.yml -Datei so entwickeln, werden diese Container im Wesentlichen im selben Netzwerk erstellt, und sie haben freien Zugriff darauf, auf beliebige Weise miteinander zu kommunizieren und so viele Informationen auszutauschen, wie sie möchten.

Wenn die beiden Container mit docker-compose erstellt werden, benötigen wir keine Portdeklarationen.

In meinem Beispiel müssen wir nun eine Codekonfiguration in der Nodejs-App vornehmen, die ungefähr so ​​aussieht:

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

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

Ich verwende das obige Beispiel, um Sie darauf aufmerksam zu machen, dass möglicherweise zusätzlich zu der für Ihr Projekt spezifischen Datei docker-compose.yml eine bestimmte Konfiguration erforderlich ist.

Wenn Sie jemals mit einer Nodejs-App arbeiten und erneut versuchen, sicherzustellen, dass Sie den von Nodejs verwendeten Standardport kennen, füge ich Folgendes hinzu:

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

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

Docker wird also sehen, dass die App Node nach redis-server sucht und diese Verbindung zu diesem laufenden Container umleitet.

Die ganze Zeit enthält das Dockerfile nur Folgendes:

FROM node:Alpine

WORKDIR '/app'

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

CMD ["npm", "start"]

Während Sie docker run myimage ausführen müssten, um eine Instanz aller Container oder Dienste in der Datei zu erstellen, können Sie stattdessen docker-compose up ausführen und müssen kein Image angeben, da Docker dies tut Suchen Sie im aktuellen Arbeitsverzeichnis nach einer docker-compose.yml -Datei.

Vor docker-compose.yml mussten wir uns mit zwei getrennten Befehlen von docker build . und docker run myimage befassen, aber in der docker-compose Welt, wenn Sie Ihre Bilder neu erstellen möchten, schreiben Sie docker-compose up --build. Das weist Docker an, die Container neu zu starten, sie jedoch neu zu erstellen, um die neuesten Änderungen zu erhalten.

So erleichtert docker-compose das Arbeiten mit mehreren Containern. Wenn Sie diese Gruppe von Containern das nächste Mal im Hintergrund starten müssen, können Sie docker-compose up -d ausführen und um sie zu stoppen, können Sie docker-compose down ausführen.

43
Daniel

In meinem Workflow füge ich für jeden Teil meines Systems eine Docker-Datei hinzu und konfiguriere sie so, dass jeder Teil einzeln ausgeführt werden kann. Dann füge ich eine docker-compose.yml hinzu, um sie zusammenzuführen und zu verknüpfen.

Größter Vorteil (meiner Meinung nach): Wenn Verknüpfung der Container , können Sie einen Namen definieren und Ihre Container mit diesem Namen pingen. Daher ist Ihre Datenbank möglicherweise unter dem Namen db und nicht mehr über ihre IP erreichbar.

41
n2o

"besser" ist relativ. Es hängt alles von Ihren Bedürfnissen ab. Docker Compose dient zum Orchestrieren mehrerer Container. Wenn diese Bilder bereits in der Docker-Registrierung vorhanden sind, ist es besser, sie in der Erstellungsdatei aufzulisten. Wenn diese Bilder oder einige andere Bilder aus Dateien auf Ihrem Computer erstellt werden müssen, können Sie die Prozesse zum Erstellen dieser Bilder in einer Docker-Datei beschreiben.

Ich verstehe, dass Docker-Dateien in Docker Compose verwendet werden, bin mir aber nicht sicher, ob es sinnvoll ist, alle Dateien in einer großen Docker-Datei mit mehreren FROM-Befehlen für die verschiedenen Bilder abzulegen.

Die Verwendung mehrerer FROM in einer einzigen Docking-Datei ist nicht sehr sinnvoll, da vorgeschlagen wird, diese Funktion zu entfernen. 13026

Wenn Sie beispielsweise eine Anwendung andocken möchten, die eine Datenbank verwendet und die Anwendungsdateien auf Ihrem Computer hat, können Sie eine Erstellungsdatei zusammen mit einer Andockdatei wie folgt verwenden

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

Stellen Sie sich vor, Sie sind Manager eines Softwareunternehmens und haben gerade einen brandneuen Server gekauft. Nur die Hardware.

Stellen Sie sich Dockerfile als eine Reihe von Anweisungen vor, die Sie Ihrem Systemadministrator mitteilen würden was zu installieren ist auf diesem brandneuen Server. Zum Beispiel:

  • Wir brauchen ein Debian-Linux
  • fügen Sie einen Apache-Webserver hinzu
  • wir brauchen auch postgresql
  • installieren Sie den Midnight Commander
  • wenn alles erledigt ist, kopiere alle * .php, * .jpg, etc. Dateien unseres Projekts in die Webroot des Webservers (/var/www)

Stellen Sie sich dagegen docker-compose.yml als eine Reihe von Anweisungen vor, die Sie Ihrem Systemadministrator mitteilen würden wie der Server mit dem Rest der Welt interagieren kann. Zum Beispiel,

  • es hat Zugriff auf einen freigegebenen Ordner von einem anderen Computer,
  • der Port 80 entspricht dem Port 8000 des Host-Computers.
  • und so weiter.

(Dies ist keine genaue Erklärung, aber gut genug, um damit zu beginnen.)

6
Csongor Halmai

Dockerfiles sollen ein Image zum Beispiel aus einem Bare-Bone-Ubuntu erstellen. Sie können mysql mit dem Namen mySQL auf einem Image und mywordpress auf einem zweiten Image mit dem Namen mywordpress hinzufügen.

Zum Erstellen von YAML-Dateien müssen diese Bilder erstellt und zusammenhängend ausgeführt werden. Zum Beispiel, wenn Sie in Ihrer docker-compose.yml -Datei einen Serviceabruf db haben:

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

und ein Dienst namens worpress wie:

wordpress: 
    image: mywordpress

dann können Sie innerhalb des mywordpress-Containers db verwenden, um eine Verbindung zu Ihrem mySQL-Container herzustellen. Diese Magie ist möglich, weil Ihr Docker-Host eine Netzwerkbrücke erstellt (Netzwerk-Overlay).

3
Hugo R