Wie bekomme ich Docker-Compose, um das neueste Image aus dem Repository zu verwenden?

80

Ich weiß nicht, was ich falsch mache, aber ich kann einfach nicht docker-compose updas neueste Image aus unserer Registrierung verwenden, ohne zuerst die alten Container vollständig aus dem System zu entfernen. Es sieht so aus, als würde Compose das zuvor gestartete Image verwenden, obwohl Docker-Compose Pull ein neueres Image abgerufen hat.

Ich habe mir angesehen, wie man Docker-Compose dazu bringt, Container immer aus frischen Bildern neu zu erstellen. Das schien meinem Problem ähnlich zu sein, aber keine der dort bereitgestellten Lösungen funktioniert für mich, da ich nach einer Lösung suche, die ich auf dem Produktionsserver verwenden kann, und dort nicht alle Container entfernen möchte, bevor ich sie starte wieder (möglicher Datenverlust?). Ich möchte nur komponieren, um die neue Version der geänderten Bilder zu erkennen, sie abzurufen und dann die Dienste mit diesen neuen Bildern neu zu starten.

Ich habe dafür ein einfaches Testprojekt erstellt, bei dem das einzige Ziel darin besteht, eine Version nr zu erhalten, die bei jedem neuen Build erhöht wird. Die Version nr wird angezeigt, wenn ich zu dem erstellten nginx-Server navigiere (dies funktioniert lokal wie erwartet).

Docker-Version: 1.11.2 Docker-Compose-Version: 1.7.1 Betriebssystem: Getestet unter CentOS 7 und OS X 10.10 mit Docker-Toolbox

Meine docker-compose.yml:

version: '2'
services:
  application:
    image: ourprivate.docker.reg:5000/ourcompany/buildchaintest:0.1.8-dev
    volumes:
      - /var/www/html
    tty: true

  nginx:
    build: nginx
    ports:
      - "80:80"
    volumes_from:
      - application
    volumes:
      - ./logs/nginx/:/var/log/nginx
  php:
    container_name: buildchaintest_php_1
    build: php-fpm
    expose:
      - "9000"
    volumes_from:
      - application
    volumes:
      - ./logs/php-fpm/:/var/www/logs

Auf unserem Jenkins-Server führe ich Folgendes aus, um das Image zu erstellen und zu markieren

cd $WORKSPACE && PROJECT_VERSION=$(cat VERSION)-dev
/usr/local/bin/docker-compose rm -f
/usr/local/bin/docker-compose build
docker tag ourprivate.docker.reg:5000/ourcompany/buildchaintest ourprivate.docker.reg:5000/ourcompany/buildchaintest:$PROJECT_VERSION
docker push ourprivate.docker.reg:5000/ourcompany/buildchaintest

Dies scheint das zu tun, was es sein soll, da ich jedes Mal, wenn der Build abgeschlossen ist und die Version nr gestoßen wurde, ein neues Versions-Tag in unserem Repository erhalte.

Wenn ich jetzt renne

docker-compose pull && docker-compose -f docker-compose.yml up -d

In einem Ordner auf meinem Computer, in dem der Inhalt nur die Datei docker-compose.yml und die zum Erstellen der Nginx- und PHP-Dienste erforderlichen Docker-Dateien enthält, ist die Ausgabe, die ich erhalte, nicht die neueste Versionsnummer, die in der Registrierung markiert wurde oder angezeigt wird in der docker-compose.yml (0.1.8), aber die Version davor, die 0.1.7 ist. Die Ausgabe des Pull-Befehls würde jedoch darauf hindeuten, dass eine neue Version des Bildes abgerufen wurde:

Pulling application (ourprivate.docker.reg:5000/ourcompany/buildchaintest:latest)...
latest: Pulling from ourcompany/buildchaintest
Digest: sha256:8f7a06203005ff932799fe89e7756cd21719cccb9099b7898af2399414bfe62a
Status: Downloaded newer image for docker.locotech.fi:5000/locotech/buildchaintest:0.1.8-dev

Nur wenn ich renne

docker-compose stop && docker-compose rm -f

Führen Sie dann den docker-compose upBefehl aus, damit die neue Version wie erwartet auf dem Bildschirm angezeigt wird.

Ist das beabsichtigtes Verhalten von Docker-Compose? dh sollte ich immer eine machen, docker-compose rm -fbevor ich upwieder laufe , auch auf Produktionsservern? Oder mache ich hier etwas gegen den Strich, weshalb es nicht funktioniert?

Das Ziel ist es, unseren Build-Prozess zu erstellen und markierte Versionen der in einer docker-compose.yml benötigten Images zu erstellen, diese in unsere private Registrierung zu verschieben und dann für den "Release to Production-Step" einfach das Docker-Compose zu kopieren. yml zum Produktionsserver und führen Sie a docker-compose pull && docker-compose -f docker-compose.yml up -daus, damit das neue Image in der Produktion gestartet wird. Wenn jemand Tipps dazu hat oder auf ein Best Practices-Tutorial für diese Art von Setup verweisen kann, wäre dies ebenfalls sehr willkommen.

Jens Wegar
quelle
1
docker-compose up -d --force-recreatehat nicht funktioniert?
BMitch
Verwenden Sie einen Host oder ein benanntes Volume, um das Risiko eines Datenverlusts beim Entfernen / Neuerstellen von Containern zu vermeiden. Anscheinend verwenden Sie bereits Host-Volumes für die anderen Container. Ein leeres benanntes Volume wird bei der ersten Verwendung mit dem Inhalt des Image-Volumes initialisiert.
BMitch
--force-neu erstellt hat nicht funktioniert, nein :( Ich verwende Volumes für die Datenspeicherung, daher ist der Datenverlust-Teil möglicherweise nicht so relevant. Aber ich bin immer noch verwirrt darüber, dass ich vorher einen Docker-Compose-RM erstellen muss Starten Sie die Container neu. Sollte der Befehl up, insbesondere bei Force-Recreate, nicht dafür sorgen, dass ein neues Image benachrichtigt und stattdessen verwendet wird? Es fühlt sich falsch an, dass ich eine Entfernung auf einem Produktionsserver erzwingen müsste
Jens Wegar
Wenn --force-recreatedie Container nicht neu erstellt werden, müssen Sie möglicherweise einen Fehlerbericht einreichen docker-compose. Beachten Sie, dass bei Verwendung eines neuen Bildes der Container neu erstellt und entfernt wird. Und wenn Sie dabei keine container-spezifischen Volumes entfernen, erhalten Sie eine ziemlich lange Liste von Daten, in denen Sie nie wieder verwendet werden docker volume ls -f dangling=true. Ihr Fix ist also die erste Hälfte dessen, was Docker-Compose für Sie tun sollte.
BMitch
OK danke! Ich muss ein bisschen mehr herumfummeln, um sicherzugehen, dass ich den Prozess verstehe (immer noch ein Neuling, wenn es um Docker geht), aber es sieht so aus, als ob Docker-Compose RM-F vor dem Erstellen das ist, was ich dann tun muss.
Jens Wegar

Antworten:

65

Um sicherzustellen, dass Sie die neueste Version für Ihr :latestTag aus Ihrer Registrierung verwenden (z. B. Docker-Hub), müssen Sie auch das neueste Tag erneut abrufen. Falls es sich geändert hat, wird das Diff heruntergeladen und bei Ihnen docker-compose uperneut gestartet .

Das wäre also der richtige Weg:

docker-compose stop
docker-compose rm -f
docker-compose pull   
docker-compose up -d

Ich habe dies in ein Bild geklebt, das ich starte, um Docker-Compose zu starten und sicherzustellen, dass die Bilder auf dem neuesten Stand bleiben: https://hub.docker.com/r/stephanlindauer/docker-compose-updater/

stephanlindauer
quelle
27
docker-compose pull && docker-compose up -dreicht. Es überprüft automatisch, ob die laufenden Container veraltet sind, und erstellt sie in diesem Fall mit den neuesten Bildern neu
Mindaugas Varkalys
@ MindaugasVarkalys Ihr Kommentar hätte die akzeptierte Antwort sein sollen, Sir. Funktioniert wie Charme.
Yuriy Pozniak
36

Um die neuesten Bilder zu erhalten, verwenden Sie docker-compose build --pull

Ich benutze den folgenden Befehl, der wirklich 3 in 1 ist

docker-compose down && docker-compose build --pull && docker-compose up -d

Dieser Befehl stoppt die Dienste, ruft das neueste Image ab und startet dann die Dienste.

Abhishek Galoda
quelle
Vielleicht sollten Sie hinzufügen docker-compose pull, um Bilder für Dienste mit Bild zu aktualisieren: anstatt zu bauen: in docker-compose.ymloder wird dies docker-compose build --pulltun?
oceanBT
Ich bekomme nginx uses an image, skippingbei Verwendung von Docker-Compose Build --pull Somit werden die Bilder nicht aktualisiert.
Antonio Araujo
24

Um diese Frage zu schließen, läuft das, was anscheinend funktioniert hat, tatsächlich

docker-compose stop
docker-compose rm -f
docker-compose -f docker-compose.yml up -d

Dh entfernen Sie die Behälter, bevor Sie upwieder laufen .

Wenn Sie dies tun, müssen Sie berücksichtigen, dass Datenvolumencontainer ebenfalls entfernt werden, wenn Sie sie nur ausführen rm -f. Um dies zu verhindern, gebe ich explizit jeden zu entfernenden Container an:

docker-compose rm -f application nginx php

Wie ich in meiner Frage sagte, weiß ich nicht, ob dies der richtige Prozess ist. Dies scheint jedoch für unseren Anwendungsfall zu funktionieren. Bis wir eine bessere Lösung gefunden haben, werden wir diese verwenden.

Jens Wegar
quelle
Was ist, wenn Sie auf die vorherige Containerversion zurücksetzen möchten? Spülen, wiederholen?
Achtundachtzig
1
Habe es nicht ausprobiert aber ja, das nehme ich auch an. Da die Containerversion in der Datei docker-compose.yml (z. B. myimage: 2.0.1) definiert werden sollte, wenn Sie ein Rollback durchführen möchten, aktualisieren Sie die Datei docker-compose.yml auf die Version, auf die Sie ein Rollback durchführen möchten (z. B. 2.0) .0) und wiederholen den gleichen Spülvorgang erneut.
Jens Wegar
Wenn ich ein Rollback durchführen möchte, setze ich einfach das Commit zurück, lasse den Docker-Hub erstellen und warte, bis der Updater ihn abholt. wahrscheinlich nicht das aufwändigste System, aber es funktioniert für meine Freizeitprojekte.
stephanlindauer
3

Ich habe dies in unserem 7-8 Docker-Produktionssystem gesehen. Eine andere Lösung, die für mich in der Produktion funktioniert hat, war das Ausführen

docker-compose down
docker-compose up -d

Dadurch werden die Container entfernt und es scheint, als würden aus dem neuesten Image neue erstellt.

Dies löst noch nicht meinen Traum von Down + Up pro JEDEM geänderten Container (seriell, weniger Ausfallzeit), aber es funktioniert, um 'Up' zu zwingen, die Container zu aktualisieren.

Danku
quelle
docker-compose downafaik entfernt auch alle Datenvolumencontainer, die mit den laufenden Containern verknüpft sind. Kein Problem also, wenn die Datenvolumes nur Inhalte enthalten, die aus einem laufenden Container neu erstellt werden können. Sie sollten jedoch vorsichtig sein, wenn die Volumes Daten enthalten, die Sie behalten möchten.
Jens Wegar
downEntfernt standardmäßig und aktuell doc: Container, Netzwerke und Standardnetzwerke. Der Arzt sagt, dass Netzwerke und Volumes, die als extern definiert sind, niemals entfernt werden. Funktioniert für mich mit benannten Volumes (und ich denke, das gilt auch für benannte Netzwerke).
Arminfro
3

Option downdieses Problem beheben

Ich führe meine Erstellungsdatei aus:

docker-compose -f docker/docker-compose.yml up -d

dann lösche ich alle mit down --rmi all

docker-compose -f docker/docker-compose.yml down --rmi all

Stops containers and removes containers, networks, volumes, and images
created by `up`.

By default, the only things removed are:

- Containers for services defined in the Compose file
- Networks defined in the `networks` section of the Compose file
- The default network, if one is used

Networks and volumes defined as `external` are never removed.

Usage: down [options]

Options:
    --rmi type          Remove images. Type must be one of:
                        'all': Remove all images used by any service.
                        'local': Remove only images that don't have a custom tag
                        set by the `image` field.
    -v, --volumes       Remove named volumes declared in the `volumes` section
                        of the Compose file and anonymous volumes
                        attached to containers.
    --remove-orphans    Remove containers for services not defined in the
                        Compose file
Slavik Muz
quelle
2

Ich habe einen halben Tag mit diesem Problem verbracht. Der Grund war, dass Sie unbedingt überprüfen müssen, wo die Lautstärke aufgenommen wurde.

Volumes: - API-Daten: / src / patterns

Tatsache ist jedoch, dass an dieser Stelle der Code geändert wurde. Beim Aktualisieren des Dockers hat sich der Code jedoch nicht geändert.

Wenn Sie den Code einer anderen Person überprüfen und aus irgendeinem Grund nicht aktualisieren, überprüfen Sie dies.

Und so funktioniert dieser Ansatz im Allgemeinen:

Docker-Compose Down

Docker-Compose-Build

Docker-Compose -d

user8928128
quelle
0

In der Docker-Compose-Dokumentation für den Befehl 'up' wird eindeutig angegeben, dass der Container aktualisiert wird, falls das Image seit dem letzten 'up' geändert wird:

Wenn für einen Dienst bereits Container vorhanden sind und die Konfiguration oder das Image des Dienstes nach der Erstellung des Containers geändert wurde, übernimmt Docker-Compose die Änderungen, indem die Container gestoppt und neu erstellt werden (Beibehalten der bereitgestellten Volumes).

Wenn Sie also 'stop' gefolgt von 'pull' und dann 'up' verwenden, sollten Sie Probleme mit verlorenen Volumes für die laufenden Container vermeiden, außer natürlich für Container, deren Images aktualisiert wurden.

Ich experimentiere derzeit mit diesem Prozess und werde meine Ergebnisse in Kürze in diesen Kommentar aufnehmen.

Paul Pritchard
quelle
0

Wenn sich die Docker Compose-Konfiguration in einer Datei befindet, führen Sie einfach Folgendes aus:

docker-compose -f appName.yml down && docker-compose -f appName.yml pull && docker-compose -f appName.yml up -d
njeru
quelle
-3

Ich verwende den folgenden Befehl, um die neuesten Bilder zu erhalten

sudo docker-compose down -rmi all

sudo docker-compose up -d

illum1n4ti
quelle