jak uzyskać docker-compose, aby używał najnowszego obrazu z repozytorium

89

Nie wiem, co robię źle, ale po prostu nie mogę docker-compose upużyć najnowszego obrazu z naszego rejestru bez uprzedniego całkowitego usunięcia starych kontenerów z systemu. Wygląda na to, że redagowanie używa wcześniej uruchomionego obrazu, mimo że docker-compose pull pobrał nowszy obraz.

Przyjrzałem się, jak sprawić, by docker-compose zawsze odtwarzał kontenery ze świeżych obrazów? który wydawał się być podobny do mojego problemu, ale żadne z dostarczonych tam rozwiązań nie działa dla mnie, ponieważ szukam rozwiązania, którego mogę użyć na serwerze produkcyjnym i tam nie chcę usuwać wszystkich kontenerów przed ich uruchomieniem ponownie (możliwa utrata danych?). Chciałbym tylko komponować, aby wykryć nową wersję zmienionych obrazów, wyciągnąć je, a następnie ponownie uruchomić usługi z tymi nowymi obrazami.

Stworzyłem do tego prosty projekt testowy, w którym jedynym celem jest uzyskanie numeru wersji do zwiększania przy każdej nowej kompilacji. Numer wersji jest wyświetlany, jeśli przejdę do utworzonego serwera nginx (działa to zgodnie z oczekiwaniami lokalnie).

wersja docker: 1.11.2 wersja docker-compose: 1.7.1 System operacyjny: przetestowano zarówno na CentOS 7, jak i OS X 10.10 przy użyciu docker-toolbox

Mój 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

na naszym serwerze jenkins uruchamiam następujące polecenie, aby zbudować i otagować obraz

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

wydaje się, że robi to, co powinno, ponieważ dostaję tag nowej wersji w naszym repozytorium za każdym razem, gdy kompilacja się kończy, a wersja nr została zderzona.

Jeśli teraz biegnę

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

w folderze na moim komputerze, w którym zawartość zawiera tylko plik docker-compose.yml i niezbędne pliki Dockerfiles do zbudowania usług nginx i php, otrzymany wynik nie jest najnowszym numerem wersji, który został oznaczony w rejestrze lub jest pokazany w docker-compose.yml (0.1.8), ale wcześniejsza wersja, czyli 0.1.7. Jednak wynik polecenia pull sugerowałby, że została pobrana nowa wersja obrazu:

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

Tylko jeśli biegnę

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

a następnie uruchom docker-compose uppolecenie, czy nowa wersja pojawi się na ekranie zgodnie z oczekiwaniami.

Czy to zamierzone zachowanie docker-compose? tj. czy powinienem zawsze zrobić docker-compose rm -fprzed upponownym uruchomieniem , nawet na serwerach produkcyjnych? A może robię coś pod prąd i dlatego to nie działa?

Celem jest zbudowanie naszego procesu kompilacji i utworzenie oznaczonych wersji obrazów potrzebnych w pliku docker-compose.yml, przekazanie ich do naszego prywatnego rejestru, a następnie „wydanie do etapu produkcji”, aby po prostu skopiować plik docker-compose. yml na serwer produkcyjny i uruchom docker-compose pull && docker-compose -f docker-compose.yml up -dnowy obraz, aby rozpocząć produkcję. Jeśli ktoś ma wskazówki na ten temat lub może wskazać samouczek najlepszych praktyk dla tego rodzaju konfiguracji, również byłby bardzo wdzięczny.

Jens Wegar
źródło
2
docker-compose up -d --force-recreatenie działa?
BMitch
Aby uniknąć ryzyka utraty danych podczas usuwania / odtwarzania kontenerów, użyj hosta lub nazwanego woluminu. Wygląda na to, że używasz już woluminów hosta dla innych kontenerów. Pusty nazwany wolumin zostanie zainicjowany zawartością woluminu obrazu przy pierwszym użyciu.
BMitch
--force-recated nie zadziałało, nie :( Używam woluminów do przechowywania danych, więc część dotycząca utraty danych może nie jest aż tak istotna. Ale nadal jestem zdezorientowany, że muszę wcześniej wykonać rm docker-compose ponowne uruchomienie kontenerów. Czy polecenie up, command, zwłaszcza w przypadku force-reate, nie powinno zadbać o powiadomienie o nowym obrazie i zamiast tego użyć go? To źle, że musiałbym wymusić usunięcie na serwerze produkcyjnym
Jens Wegar
Jeśli --force-recreatekontenery nie są odtwarzane, może być konieczne zgłoszenie błędu docker-compose. Pamiętaj, że użycie nowego obrazu oznaczałoby odtworzenie kontenera, co spowodowałoby jego usunięcie. A jeśli w tym procesie nie usuniesz żadnych woluminów określonych dla kontenerów, możesz uzyskać dość długą listę danych, których nigdy więcej nie użyjesz docker volume ls -f dangling=true. Więc twoja poprawka to pierwsza połowa tego, co docker-compose powinno dla ciebie zrobić.
BMitch
Ok dziękuję! Będę musiał trochę więcej bawić się, aby upewnić się, że rozumiem proces (nadal jestem nowicjuszem, jeśli chodzi o Dockera), ale wygląda na to, że docker-compose rm -f przed kompilacją muszę wtedy zrobić.
Jens Wegar

Odpowiedzi:

68

aby upewnić się, że używasz najnowszej wersji :latesttagu z rejestru (np. docker hub), musisz również ponownie pobrać najnowszy tag. w przypadku zmiany, plik różnicowy zostanie pobrany i uruchomiony docker-compose upponownie.

więc to byłaby droga:

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

przykleiłem to do obrazu, który uruchamiam, aby rozpocząć docker-compose i upewnić się, że obrazy są aktualne: https://hub.docker.com/r/stephanlindauer/docker-compose-updater/

stephanlindauer
źródło
40
docker-compose pull && docker-compose up -dwystarczy. Automatycznie sprawdza, czy uruchomione kontenery są nieaktualne, a jeśli tak jest, odtwarza je z najnowszymi obrazami
Mindaugas Varkalys
@MindaugasVarkalys, twój komentarz powinien być zaakceptowaną odpowiedzią, sir. Działa jak urok.
Yuriy Pozniak
37

Aby uzyskać najnowsze obrazy, użyj kompilacji docker-compose --pull

Używam poniższego polecenia, które jest naprawdę 3 w 1

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

To polecenie zatrzyma usługi, pobierze najnowszy obraz, a następnie uruchomi usługi.

Abhishek Galoda
źródło
Może powinieneś dodać, docker-compose pullaby zaktualizować obrazy dla usług z obrazem: zamiast wbudować: w docker-compose.ymlczy docker-compose build --pullzrobisz to?
oceanBT
Otrzymuję nginx uses an image, skipping, używając kompilacji docker-compose --pull W ten sposób nie aktualizuje obrazów.
Antonio Araujo,
23

Aby zamknąć to pytanie, to, co wydawało się działać, rzeczywiście działa

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

To znaczy usuń pojemniki przed upponownym uruchomieniem .

Robiąc to w ten sposób, należy pamiętać o tym, że kontenery woluminów danych są również usuwane, jeśli po prostu uruchomisz rm -f. Aby temu zapobiec, wyraźnie określam każdy kontener do usunięcia:

docker-compose rm -f application nginx php

Jak powiedziałem w swoim pytaniu, nie wiem, czy to jest właściwy proces. Ale wydaje się, że działa to w naszym przypadku użycia, więc dopóki nie znajdziemy lepszego rozwiązania, będziemy korzystać z tego.

Jens Wegar
źródło
A co jeśli chcesz wrócić do poprzedniej wersji kontenera? Płukać, powtórzyć?
Osiemdziesiąt osiem
1
Nie próbowałem tego, ale tak, zakładam tak dużo. Ponieważ wersja kontenera powinna być zdefiniowana w docker-compose.yml (np. Myimage: 2.0.1), jeśli chcesz wycofać, zaktualizujesz docker-compose.yml do wersji, do której chcesz przywrócić (np. 2.0 .0) i powtórz ten sam proces płukania.
Jens Wegar
Jeśli chcę wycofać zmiany, po prostu cofam zatwierdzenie, pozwól Docker Hub zbudować, a następnie poczekaj, aż aktualizator go podniesie. prawdopodobnie nie jest to najbardziej rozbudowany system, ale działa w moich projektach w wolnym czasie.
stephanlindauer
Usuń wszystko nie wydaje się rozwiązaniem, ale bardziej podejrzanym.
PierrickM
3

Widziałem to w naszym systemie produkcyjnym 7-8 docker. Innym rozwiązaniem, które sprawdziło się na produkcji, było uruchomienie

docker-compose down
docker-compose up -d

usuwa to kontenery i wydaje się tworzyć nowe z najnowszego obrazu.

To jeszcze nie rozwiązuje mojego marzenia o obniżeniu + w górę za KAŻDY zmieniony kontener (seryjnie, mniej przestojów), ale działa, aby wymusić „w górę”, aby zaktualizować pojemniki.

Danku
źródło
docker-compose downafaik usuwa również wszelkie kontenery woluminów danych połączone z uruchomionymi kontenerami. Nie ma więc problemu, jeśli woluminy danych zawierają tylko rzeczy, które można odtworzyć z uruchomionego kontenera. Należy jednak zachować ostrożność, jeśli woluminy zawierają dane, które chcesz zachować.
Jens Wegar
1
downusuwa domyślnie i aktualny dokument: kontenery, sieci i domyślne sieci. Dokument mówi: „Sieci i woluminy zdefiniowane jako zewnętrzne nigdy nie są usuwane”. Działa dla mnie z nazwanymi woluminami (i myślę, że dotyczy to również nazwanych sieci).
arminfro
3

Opcja downrozwiązania tego problemu

Uruchamiam mój plik tworzenia:

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

następnie usuwam wszystko za pomocą 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
źródło
3

Spędziłem z tym problemem pół dnia. Powodem było to, że koniecznie sprawdź, gdzie nagrano głośność.

woluminy: - api-data: / src / patterns

Ale faktem jest, że w tym miejscu był kod, który zmieniliśmy. Ale podczas aktualizacji dockera kod się nie zmienił.

Dlatego jeśli sprawdzasz kod innej osoby iz jakiegoś powodu nie aktualizujesz, sprawdź to.

Generalnie więc to podejście działa:

docker-compose down

kompilacja docker-compose

docker-compose up -d

user8928128
źródło
0

Dokumentacja docker-compose dla polecenia „up” jasno stwierdza, że ​​aktualizuje ono kontener w przypadku zmiany obrazu od ostatniego „up”:

Jeśli istnieją kontenery dla usługi, a konfiguracja lub obraz usługi zostały zmienione po utworzeniu kontenera, docker-compose up przejmuje zmiany, zatrzymując i ponownie kontenery (zachowując zamontowane woluminy).

Tak więc użycie „stop”, a następnie „pull”, a następnie „up” powinno w ten sposób uniknąć problemów z utraconymi wolumenami dla działających kontenerów, z wyjątkiem oczywiście kontenerów, których obrazy zostały zaktualizowane.

Obecnie eksperymentuję z tym procesem i wkrótce zamieszczę moje wyniki w tym komentarzu.

Paul Pritchard
źródło
Nawet samo ściągnięcie docker-compose, a następnie docker-compose up będzie działać bez uprzedniego zatrzymania
jflsitecore
0

Jeśli konfiguracja docker compose znajduje się w pliku, po prostu uruchom:

docker-compose -f appName.yml down && docker-compose -f appName.yml pull && docker-compose -f appName.yml up -d
njeru
źródło
-3

Używam następującego polecenia, aby uzyskać najnowsze obrazy

sudo docker-compose down -rmi all

sudo docker-compose up -d

illum1n4ti
źródło