як отримати docker-compose для використання останнього зображення зі сховища


89

Я не знаю, що я роблю неправильно, але я просто не можу docker-compose upвикористовувати останнє зображення з нашого реєстру, не попередньо повністю видаливши старі контейнери з системи. Схоже, компонування використовує попередньо розпочате зображення, навіть незважаючи на те, що витягування докером-композицією отримало нове зображення.

Я розглянув Як змусити docker-compose завжди відтворювати контейнери зі свіжих зображень? що здавалося схоже на мою проблему, але жодне із запропонованих рішень не працює для мене, оскільки я шукаю рішення, яке я можу використовувати на робочому сервері, і там я не хочу видаляти всі контейнери перед їх запуском знову (можлива втрата даних?). Я хотів би для compose лише виявити нову версію змінених зображень, витягнути їх, а потім перезапустити служби з цими новими зображеннями.

Я створив простий тестовий проект для цього, в якому єдиною метою є отримання версії nr, яка збільшується при кожній новій побудові. Версія nr відображається, якщо я переглядаю створений сервер nginx (це працює локально).

версія docker: 1.11.2 версія docker-compose: 1.7.1 ОС: тестована як на CentOS 7, так і на OS X 10.10 за допомогою docker-toolbox

Мій 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

на нашому сервері jenkins я запускаю наступне для побудови та позначення зображення

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

здається, це робить те, що повинно бути, оскільки я отримую новий тег версії у нашому сховищі кожного разу, коли завершується збірка і версія nr стикається

Якщо я зараз біжу

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

у папці на моєму комп’ютері, де вмістом є лише docker-compose.yml та необхідні файли Docker для створення служб nginx та php, результат, який я отримую, не є останньою версією номера, яка була позначена в реєстрі або показана у docker-compose.yml (0.1.8), але версія до цього, яка становить 0.1.7. Однак вихід команди pull висловлює припущення про те, що було завантажено нову версію зображення:

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

Тільки якщо я біжу

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

а потім запустіть docker-compose upкоманду, чи отримаю я, що нова версія відображається на екрані, як очікувалося.

Це передбачувана поведінка докера-композитора? тобто я повинен завжди робити a docker-compose rm -fперед запуском upзнову, навіть на робочих серверах? Або я тут роблю щось проти зерна, через що воно не працює?

Мета полягає в тому, щоб побудувати наш процес побудови та створити позначені версії зображень, необхідних у docker-compose.yml, перенести їх до нашого приватного реєстру, а потім для "звільнення до виробничого кроку" просто скопіювати docker-compose. yml на робочий сервер і запустіть a docker-compose pull && docker-compose -f docker-compose.yml up -dдля запуску нового образу у виробництво. Якщо хтось має поради щодо цього або може вказати на підручник з найкращих практик для такого роду налаштування, який також був би дуже вдячний.


2
docker-compose up -d --force-recreateне працював?
BMitch

Щоб уникнути ризику втрати даних під час видалення / відтворення контейнерів, використовуйте хост або іменований том. Схоже, ви вже використовуєте томи хостів для інших контейнерів. Порожній іменований том ініціалізується вмістом обсягу зображення при першому використанні.
BMitch

--force-recreated не спрацював, ні :( Я використовую томи для зберігання даних, тому частина втрати даних, можливо, не така актуальна. Але я все ще бентежусь щодо необхідності робити rm-compose rm раніше повторний запуск контейнерів. Чи не слід команді up, особливо з примусовим відтворенням, подбати про повідомлення нового зображення, використовуючи це? Напевно, неправильно, що мені доведеться змусити видалити робочий сервер
Jens Wegar

Якщо --force-recreateконтейнери не відтворюються, можливо, вам доведеться подати звіт про помилку docker-compose. Майте на увазі, що використання нового зображення означало б відтворення контейнера, який би його видалив. І якщо ви не видалите жодних конкретних томів контейнера в процесі, ви можете отримати досить довгий звисаючий список даних, в якому ви більше ніколи не використовуєте docker volume ls -f dangling=true. Отже, ваше виправлення - це перша половина того, що докер-композиція повинна робити для вас.
BMitch

Добре, дякую! Мені доведеться ще трохи возитися, щоб переконатись, що я розумію процес (все ще новачок, коли справа стосується Docker), але схоже на docker-compose rm -f перед тим, як будувати - це те, що мені тоді потрібно буде зробити.
Jens Wegar

Відповіді:


68

для того, щоб переконатися, що ви використовуєте останню версію для вашого :latestтегу з вашого реєстру (наприклад, докер-концентратор), вам потрібно також знову витягти найновіший тег. у випадку, якщо він змінився, різниця буде завантажена і запущена, коли ви docker-compose upзнову.

отже, це був би шлях:

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

я приклеїв це до зображення, яке я запускаю, щоб розпочати компонування докера та переконатися, що зображення залишаються в актуальному стані: https://hub.docker.com/r/stephanlindauer/docker-compose-updater/


40
docker-compose pull && docker-compose up -dдостатньо. Він автоматично перевіряє, чи запущені контейнери застарілі, і якщо це так, відтворює їх за допомогою найновіших зображень
Mindaugas Varkalys

@MindaugasVarkalys, ваш коментар повинен був бути прийнятою відповіддю, сер. Працює як шарм.
Юрій Позняк

37

Щоб отримати найновіші зображення, використовуйте docker-compose build --pull

Я використовую команду нижче, яка насправді є 3 в 1

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

Ця команда зупинить служби, витягує останнє зображення, а потім запускає служби.


Можливо, вам слід додати docker-compose pullдля оновлення зображень для служб із зображенням: замість build: in docker-compose.ymlчи docker-compose build --pullзробите це?
oceanBT

Я отримую nginx uses an image, skippingпри використанні docker-compose build --pull Таким чином, зображення не оновлюється.
Антоніо Араухо,

23

Щоб закрити це питання, те, що, здавалося, спрацювало, справді працює

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

Тобто витягніть контейнери перед запуском upзнову.

Що потрібно пам’ятати, роблячи це так, це те, що контейнери обсягу даних також видаляються, якщо ви просто запускаєте rm -f . Щоб запобігти тому, що я чітко вказую кожен контейнер для видалення:

docker-compose rm -f application nginx php

Як я вже сказав у своєму запитанні, я не знаю, чи це правильний процес. Але це, здається, працює для нашого випадку використання, тому поки ми не знайдемо кращого рішення, ми будемо використовувати це.


Що робити, якщо ви хочете повернутися до попередньої версії контейнера? Полоскати, повторювати?
Вісімдесят вісім

1
Не пробував, але так, я припускаю стільки ж. Оскільки версія контейнера повинна бути визначена в docker-compose.yml (наприклад, myimage: 2.0.1), якщо ви хочете відмовитись, ви оновите docker-compose.yml до версії, до якої ви хочете повернутися (наприклад, 2.0 .0) і повторіть той самий процес повторного полоскання ще раз.
Jens Wegar

якщо я хочу повернутись назад, я просто скасую коміт, дозвольте побудувати концентратор докера, а потім почекайте, поки програма оновлення підніме його. мабуть, не найскладніша система, але вона працює для моїх вільних проектів.
stephanlindauer

Видалити все не схоже на рішення, а більше на хитромудре.
PierrickM

3

Я бачив, як це відбувається в нашій 7-8 виробничій системі виробництва докерів. Ще одне рішення, яке працювало для мене на виробництві, - це працювати

docker-compose down
docker-compose up -d

це видаляє контейнери і, здається, придумує створення нових із останнього зображення.

Це ще не вирішує моєї мрії про зниження + вгору за КОЖНИЙ змінений контейнер (послідовно, менше часу простою), але це працює, щоб змусити оновити контейнери.


docker-compose downafaik також видаляє будь-які контейнери обсягу даних, пов'язані з запущеними контейнерами. Тож не проблема, якщо томи даних містять лише речі, які можна відтворити із запущеного контейнера. Але слід бути обережним, якщо томи містять дані, які ви хочете зберегти.
Jens Wegar

1
downвидаляє за замовчуванням та поточний документ: контейнери, мережі та мережі за замовчуванням. Док каже: "Мережі та томи, визначені як зовнішні, ніколи не видаляються". Працює у мене з іменованими томами (і, мабуть, це стосується і іменованих мереж).
arminfro

3

Варіант downвирішення цієї проблеми

Я запускаю свій файл створення:

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

потім видаляю все за допомогою 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

3

Я провів півдня з цією проблемою. Причиною було те, що обов’язково перевірте, де записано обсяг.

томи: - api-data: / src / pattern

Але справа в тому, що в цьому місці був код, який ми змінили. Але при оновленні докера код не змінився.

Тому, якщо ви перевіряєте чужий код і з якихось причин не оновлюєтесь, перевірте це.

Отже, загалом такий підхід працює:

докер-скласти вниз

docker-compose build

docker-compose up -d


0

Документація щодо складання докера для команди 'up' чітко вказує, що вона оновлює контейнер у разі зміни зображення після того, як було виконано останнє 'up':

Якщо для служби є існуючі контейнери, а конфігурація або зображення служби були змінені після створення контейнера, docker-compose up збирає зміни, зупиняючи та відтворюючи контейнери (зберігаючи змонтовані томи).

Отже, використовуючи "стоп", а потім "тягнути", а потім "вгору", це повинно уникати проблем втрачених томів для запущених контейнерів, крім звичайно, для контейнерів, зображення яких оновлено.

Зараз я експериментую з цим процесом і незабаром включу свої результати в цей коментар.


Навіть просто натягування докера-композиції з подальшим складанням
докера

0

Якщо конфігурація складання докера знаходиться у файлі, просто запустіть:

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


-3

Я використовую наступну команду, щоб отримати останні зображення

sudo docker-compose down -rmi all

sudo docker-compose up -d

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.