Compose: Wie man Docker-Compose - Force-Recreate erstellt, ohne vorherige Volumes wiederzuverwenden

Erstellt am 2. Okt. 2015  ·  23Kommentare  ·  Quelle: docker/compose

Mit Docker-Compose 1.4.2 und Docker 1.8.2
Sie können unten sehen, dass der erste Band e583c6a8 ... 5a93788a0 wiederverwendet wird

 $ sudo docker-compose up -d --force-recreate
   Recreating remotetransmission_torrent_1...

 $ docker inspect remotetransmission_torrent_1 | grep volumes
   "/mnt/docker/volumes/e583c6a87437a5b4b1af50ee2693bd3e5dce574ec72d60dce1311215a93788a0/_data:/home/transmission/.config/transmission-daemon:rw",
   "/mnt/docker/volumes/cefce79850d7162f4f99541559c2dfc7315c83db717a7a5953118bd3c4b273e0/_data:/home/transmission/Downloads:rw"
   "Source": "/mnt/docker/volumes/e583c6a87437a5b4b1af50ee2693bd3e5dce574ec72d60dce1311215a93788a0/_data",
   "Source": "/mnt/docker/volumes/cefce79850d7162f4f99541559c2dfc7315c83db717a7a5953118bd3c4b273e0/_data",

 $ sudo docker-compose up -d --force-recreate
   Recreating remotetransmission_torrent_1...

 $ docker inspect remotetransmission_torrent_1 | grep volumes
   "/mnt/docker/volumes/e583c6a87437a5b4b1af50ee2693bd3e5dce574ec72d60dce1311215a93788a0/_data:/home/transmission/.config/transmission-daemon:rw",
   "/mnt/docker/volumes/cefce79850d7162f4f99541559c2dfc7315c83db717a7a5953118bd3c4b273e0/_data:/home/transmission/Downloads:rw"
   "Source": "/mnt/docker/volumes/e583c6a87437a5b4b1af50ee2693bd3e5dce574ec72d60dce1311215a93788a0/_data",
   "Source": "/mnt/docker/volumes/cefce79850d7162f4f99541559c2dfc7315c83db717a7a5953118bd3c4b273e0/_data",

Ich bin gezwungen, stop dann rm , um einige neue Volumes zu erstellen

 $ sudo docker-compose stop 
   Stopping remotetransmission_torrent_1... done

 $ sudo docker-compose rm
   Going to remove remotetransmission_torrent_1
   Are you sure? [yN] y
   Removing remotetransmission_torrent_1... done

 $ sudo docker-compose up -d --force-recreate
   Creating remotetransmission_torrent_1...

 $ docker inspect remotetransmission_torrent_1 | grep volumes
   "Source": "/mnt/docker/volumes/c5bb9a8f7b68c762c42e9c0ee92afbca3aa0d7ff9d09aaf45fd260f6fc663ec9/_data",
   "Source": "/mnt/docker/volumes/9dcce8440bafc8893e07352111d1aefb625c36df10da6dc4eaa593220266ea31/_data",

_
Gibt es einen besseren Weg als die stop/rm -Methode?

areup kindocs kinquestion

Hilfreichster Kommentar

Diese Richtlinie scheint gegen die Best Practices von Docker zu verstoßen und hat uns unzählige Kopfschmerzen bei der Fehlerbehebung verursacht, warum die Neuerstellung von Containern undicht war. Wenn ich Docker anweise, neu zu erstellen, bedeutet dies nicht, dass "einige Daten über die Containerläufe hinweg beibehalten, aber die Prozesse in den Containern neu gestartet werden". Es bedeutet, die Erde zu ebnen und von vorne zu beginnen. Wenn ich die Volumes speichern wollte, würde ich explizit Volumes bereitstellen. Ich erwarte nie, dass automatisch gemountete Volumes jeglicher Art über Containerläufe hinweg bestehen bleiben.

Alle 23 Kommentare

stop/rm ist der richtige Weg. Die Daten in Volumes könnten wichtig sein, daher möchten wir es schwierig machen, sie versehentlich zu entfernen.

Wir könnten das wahrscheinlich etwas besser dokumentieren.

Diese Richtlinie scheint gegen die Best Practices von Docker zu verstoßen und hat uns unzählige Kopfschmerzen bei der Fehlerbehebung verursacht, warum die Neuerstellung von Containern undicht war. Wenn ich Docker anweise, neu zu erstellen, bedeutet dies nicht, dass "einige Daten über die Containerläufe hinweg beibehalten, aber die Prozesse in den Containern neu gestartet werden". Es bedeutet, die Erde zu ebnen und von vorne zu beginnen. Wenn ich die Volumes speichern wollte, würde ich explizit Volumes bereitstellen. Ich erwarte nie, dass automatisch gemountete Volumes jeglicher Art über Containerläufe hinweg bestehen bleiben.

Das Fortbestehen von Daten über Läufe hinweg ist wirklich der einzige Grund, Volumes zu verwenden. Wenn Sie keine dauerhaften Daten möchten, warum legen Sie sie in einem Volume ab?

Ich richte keine Lautstärke ein. Mein docker-compose.yml hat keine Volumes eingerichtet und ich übergebe nichts an docker-compose.yml , um Volumes anzuhängen.

Befehl:

docker-compose up --force-recreate --abort-on-container-exit --build foo

docker-compose.yml:

version: '2'
services:
  foo:
    build:
      context: .
      dockerfile: src/integration/foo/Dockerfile
    ports:
      - "3306:3306"
      - "33060:33060"

Dockerfile:

FROM mysql:5.7

COPY schema/foo/migration.sql /data/db_schema.sql
COPY src/integration/foo/create_test_db.sh /docker-entrypoint-initdb.d/create_test_db.sh
ENV MYSQL_ALLOW_EMPTY_PASSWORD true

EXPOSE 3306 33060

create_test_db.sh:

#!/bin/bash
set -e
mysql --no-defaults -u root -e "drop database if exists agent_state; create database foo"
mysql --no-defaults -u root foo < "/data/db_schema.sql"

Wenn ich das oben genannte ausführe, schreibe ich ein paar Dinge in die Datenbank, dann SIG_INT, und führe den Befehl erneut aus. Die Daten, die ich in die Datenbank eingefügt habe, bleiben während des gesamten Laufs erhalten.

Das ist ein Problem mit dem MySQL-Image. Es wird ein Volume in der Basis erstellt
Bild. Sie können das Problem umgehen, indem Sie entweder ein anderes MySQL verwenden
Bild oder möglicherweise durch Erzwingen, einen anderen Pfad für die Daten zu verwenden.

Am 19. Oktober 2016, 18:36 Uhr, schrieb "Micah Zoltu" [email protected] :

Ich richte keine Lautstärke ein. Meine docker-compose.yml hat keine
Volumes einrichten und ich übergebe nichts an docker-compose.yml an
Fügen Sie alle Volumes hinzu.

Befehl:

docker-compose up --force-recreate --abort-on-container-exit --build foo

docker-compose.yml:

Version 2'
Dienstleistungen:
foo:
bauen:
Kontext :.
Docker-Datei: src / Integration / foo / Docker-Datei
Häfen:
- 3306: 3306
- 33060: 33060

Dockerfile:

VON MySQL: 5.7

KOPIEREN Sie das Schema / foo / migration.sql /data/db_schema.sql
COPY src / integration / foo / create_test_db.sh /docker-entrypoint-initdb.d/create_test_db.sh
ENV MYSQL_ALLOW_EMPTY_PASSWORD true

EXPOSE 3306 33060

create_test_db.sh:

! / bin / bash

setze -e
mysql --no-defaults -u root -e "Datenbank löschen, falls vorhanden agent_state; Datenbank foo erstellen"
mysql --no-defaults -u root foo <"/data/db_schema.sql"

Wenn ich das oben genannte ausführe, schreibe ich ein paar Sachen in die Datenbank, dann SIG_INT und dann das
Befehl erneut Die Daten, die ich in die Datenbank eingegeben habe, bleiben während des Laufs erhalten.

- -
Sie erhalten dies, weil Sie kommentiert haben.
Antworte direkt auf diese E-Mail und sieh sie dir auf GitHub an
https://github.com/docker/compose/issues/2127#issuecomment -254986952,
oder schalten Sie den Thread stumm
https://github.com/notifications/unsubscribe-auth/AAa_RG_pJj0i-OSCfcBlG__8ToFDtGKMks5q1sWlgaJpZM4GHruC
.

Hmm, das verstößt gegen mein Verständnis von Docker-Containern. Wie wird ein Volume bereitgestellt, ohne dass ich einen Pfad auf dem Host angegeben habe? Mein Verständnis ist, dass Docker-Container kurzlebig sind, es sei denn, Sie stellen explizit ein Volume bereit?

Ein Volume benötigt keinen Hostpfad. Es gibt drei Arten von Bänden:

  • Host-Bindungs-Mounts ( -v /host:/container )
  • benannte Volumes ( -v name:/container , erstellt mit docker volume create )
  • anonyme Volumes ( -v /container oder VOLUME innerhalb eines Dockerfile )

Das MySQL-Image verwendet ein anonymes Volume. Zur Laufzeit können Sie den Container anweisen, ein anderes Volume für diesen Pfad im Container zu verwenden. Andernfalls ist das anonyme Volume noch vorhanden.

Anonyme Bände sind nicht großartig. Sie sind die ältesten der drei, und ein Großteil ihres Verhaltens ist Legacy-Material, das nur aus Gründen der Abwärtskompatibilität aufbewahrt wird.

Zumindest eine Befehlszeilenoption a la "--recreate-volume" wäre schön ...

OK, Leute, hier ist der Fall zu denken:

1) Ich möchte mein öffentliches Rails-Verzeichnis erneut in den Nginx-Container einbinden, damit einige statische Daten direkt von Nginx bereitgestellt werden können.
2) Ich weise / usr / local / app / app / public ein "anonymes" (nicht vom Host bereitgestelltes, nicht benanntes) Volume zu und teile es nginx über "volume_from" mit.
3) "öffentliche" Inhalte werden bei Image-Builds häufig geändert - nicht nur Dateien der obersten Ebene, sondern auch einige Dateien in Unterverzeichnissen (dies ist wichtig).

Wenn ich Container neu erstelle, erhalte ich derzeit die alte Version von "public" - Inhalte im Bild werden einfach ignoriert. Ja, Docker soll fehlende Dateien auf das anonyme Volume kopieren, aber aus verschiedenen Gründen kommt dies nicht immer vor (ich vermute, es gibt keine gründliche Überprüfung der Struktur der Unterverzeichnisse).

Daher bin ich entweder gezwungen, eine "Stop-RM-Up" -Sequenz durchzuführen (was in der Produktion nicht so praktisch ist) oder ein separates Verzeichnis als freigegebenes Volume zu verwenden und explizit "rsync" für den Start des Anwendungscontainers aufzurufen, um es zu füllen / zu aktualisieren.

Wenn es eine Möglichkeit gäbe, nur anonymes Volume mit dem übergeordneten Container zu verbinden, wäre dies eine große Verbesserung.

Verwenden Sie keine Volumes für Code (oder statische Assets). Volumes beziehen sich auf Daten, die Sie zwischen Bereitstellungen beibehalten möchten. Dies ist das Gegenteil von dem, was Sie hier möchten. Erstellen Sie entweder das Nginx-Image mit den statischen Assets oder vertreten Sie einen Webserver-Container, der diese enthält.

Danke für den Standpunkt! Ich habe noch nicht aus dieser Perspektive gedacht.

Es scheint eines der konzeptionellen Probleme mit der (sich noch entwickelnden) Docker-Architektur zu sein. Wir haben bisher die Entwicklung des Datenvolumenkonzepts gesehen (z. B. von "Datencontainern" zu "benannten Volumes") und wahrscheinlich ist es noch nicht abgeschlossen.

Wenn Sie sich https://docs.docker.com/engine/tutorials/dockervolumes/#/data -volumes ansehen, werden Sie feststellen, dass die meisten beschriebenen Vorteile (Umgehen von AUFS, Freigabe) nicht unbedingt mit der Datenpersistenz verbunden sind ( für welche Bände ursprünglich gedacht).

Kein Wunder also, dass Leute (einschließlich ich) versuchen, Volumes auf verschiedene Arten zu verwenden, die über ihren ursprünglichen Zweck hinausgehen. Zum Beispiel, um kurzlebige oder bildgesteuerte Daten von einem Container in einen anderen zu übertragen, ohne viel explizites Kopieren.

Vielleicht werden wir eines Tages herausfinden, wie dies standardmäßig üblich ist. :) Bisher ist es möglich, einige ziemlich einfache Problemumgehungen zu verwenden, die oben beschrieben wurden. Nicht ideal, aber akzeptabel, solange die architektonischen Erwartungen richtig gesetzt sind.

Nochmals vielen Dank für Ihre Antwort, Klarstellung und für die großartige Arbeit, die Sie leisten!

Ich bin heute auf dieses Problem gestoßen, danke für die großartigen Erklärungen hier, alle haben mir definitiv geholfen, das Problem zu verstehen.

Ein Hauptverwirrungspunkt für mich war das Verständnis, dass das VOLUME -Tag in einer Docker-Datei dazu führt, dass ein konsistentes anonymes Volume erstellt wird. Ich habe es möglicherweise in der Dokumentation verpasst, konnte es aber nicht erwähnen.

@nephin

Wie bereits erwähnt @ hleb-rubanau. Einzelcontainer mit Rails und Nginx zu betreiben, ist die Lösung? (So: https://docs.docker.com/engine/admin/multi-service_container/?)

Sollte ich die Best Practices brechen ("Jeder Container sollte nur ein Problem haben
") nur für Portionsvermögen? :(

Für Interessierte ergab sich Folgendes:

1) In meinen Setups verwende ich jetzt immer bind-gemountete (auch als host-gemountete) Volumes. Anonyme und benannte Volumes haben zu viel spezielle / nicht offensichtliche / bedingte / inkonsistente / implizite Logik, um berücksichtigt zu werden. Ja, es ist leicht, die Besonderheiten des Lebenszyklus und der Verwaltung jedes Typs zu verstehen, aber ich fand es einfacher für mich, über Architektur nachzudenken, wenn ich nicht über all diese irrelevanten Unterschiede besorgt bin. Für verteilte FS funktioniert Gluster einwandfrei (wird aus Docker-Sicht immer noch gebunden).

2) Das freigegebene Volume ist ein gebundenes Volume, und es ist nicht das Verzeichnis, in dem Assets im Image gespeichert sind. Zu Beginn (am Einstiegspunkt) führe ich lokales rsync aus, sodass Assets aus dem Image-Verzeichnis in den gebundenen gemeinsam genutzten Speicherpfad kopiert / rsynciert werden.

Danke @ hleb-rubanau

Ich bin mir jedenfalls nicht sicher, ob einige Orchestrierungs-Tools wie RancherOS diese Volume-Konfigurationen unterstützen oder der richtige Weg zur Skalierung sind. Am Ende ist die Bereitstellung mit Docker schwieriger ...

Ich bevorzuge anonyme Bände und säubere die Waisenkinder irgendwann.

Dies ist mein Produktionsschienenstapel: https://github.com/brunocascio/AR-MTB/blob/master/docker-compose.prod.yml

Dies verursachte mir auch eine große Verwirrung, als ich das jenkins / jenkins-Image testete und meine Änderungen aus den Dateien in / usr / share / jenkins / ref nicht berücksichtigte, da sie bereits kopiert worden waren.

Das ist eine ziemlich unerwartete Benutzererfahrung - Docker Compose erstellt in jeder Hinsicht ein "verstecktes" Volume. Wenn Sie normales docker run Sie jedes Mal ein neues Volume. Es ist ein verstecktes Volumen in dem Sinne, dass nichts in docker-compose up spricht. Wenn Sie also nicht genau wissen, was das Bild tut, müssen Sie graben.

Zumindest sollten wir eine Nachricht drucken, die besagt, dass Volume x nicht neu erstellt wird, damit andere Menschen in Zukunft keine Zeit damit verschwenden müssen, sich zu fragen, was passiert.

Hallo @dnephin ,

Ich rufe sudo rm -rf /var/lib/docker/volumes/aa_dbdatavol und jetzt kann ich meine Postgres Docker-Compose nicht mehr docker-compose up mehr.

Diesen Fehler erhalten

Erstellen des Netzwerks "aa_default" mit dem Standardtreiber
Aa_postgres_1 erstellen
FEHLER: für Postgres Container für Service-Postgres kann nicht erstellt werden: Keine solche Datei oder kein solches Verzeichnis
FEHLER: Beim Aufrufen des Projekts sind Fehler aufgetreten.
Fehlerantwort vom Daemon: Kein solcher Container: aa_postgres_1

Da Sie vielleicht eine Idee haben, um das zu umgehen, teilen Sie dies bitte mit. Vielen Dank!

https://github.com/docker/compose/issues/2127#issuecomment -347152650

Nur das Neuerstellen des Ordners behebt mein Problem.
/var/lib/docker/volumes/aa_dbdatavol/_data

Vielen Dank an Ihre Antwort hat beim ersten Mal perfekt funktioniert. Muchos gracias.

@nephin sagte:

Das Fortbestehen von Daten über Läufe hinweg ist wirklich der einzige Grund, Volumes zu verwenden. Wenn Sie keine dauerhaften Daten möchten, warum legen Sie sie in einem Volume ab?

Dateien zwischen Containern zu teilen. Gibt es eine bessere Möglichkeit, dies ohne Verwendung von Volumes zu tun?

Was meinst du mit "Dateien teilen"?

Erwarten Sie, dass ein Container in eine Datei schreibt und der andere Container diese Schreibvorgänge sieht? Ein Dateisystem ist im Allgemeinen keine gute Schnittstelle zwischen zwei Diensten. In diesem Fall kann jedoch einer der Dienste das Dateisystem "verwalten", indem er Aktualisierungen auf das Volume schreibt.

Wenn "Teilen" nur bedeutet, dass zwei Container zufällig dieselben Dateien lesen, ist kein Volume erforderlich. Fügen Sie die Datei mit COPY zu beiden Containern hinzu.

Ich verwende Docker version 18.06.1-ce, build e68fc7a und kann den folgenden Befehl verwenden, um anonyme Volumes neu zu erstellen:

docker-compose up -d --build --force-recreate --renew-anon-volumes db

Es scheint, dass die Flagge --renew-anon-volumes kürzlich hinzugefügt wurde

Ich verwende Docker version 18.06.1-ce, build e68fc7a und kann den folgenden Befehl verwenden, um anonyme Volumes neu zu erstellen:

docker-compose up -d --build --force-recreate --renew-anon-volumes db

Es scheint, dass die Flagge --renew-anon-volumes kürzlich hinzugefügt wurde

Vielen Dank, dass Sie diese Option zugelassen haben.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen