Как автоматически обновлять контейнеры докеров, если базовые изображения обновляются

Скажем, у меня есть тривиальный контейнер, основанный на ubuntu:latest. Теперь есть обновление для системы безопасности и ubuntu:latest обновляются в репозитории Docker.

  1. Откуда мне знать, что мой локальный образ и его контейнеры работают позади?

  2. Существуют ли некоторые рекомендации по автоматическому обновлению локальных образов и контейнеров в соответствии с обновлениями репозитория Docker, которые на практике дадут вам те же тонкости, что и автоматические обновления, работающие на обычной машине с Ubuntu

Ответ 1

Один из способов сделать это - провести через систему CI/CD. Как только ваше родительское изображение будет создано, сделайте что-то, что сканирует ваши git-репозитории на изображения с использованием этого родителя. Если он найден, вы бы отправили запрос на получение новых версий изображения. Запрос на включение, если все тесты пройдены, будет объединен, и у вас будет новое дочернее изображение на основе обновленного родительского. Пример инструмента, который использует этот подход, можно найти здесь: https://engineering.salesforce.com/open-sourcing-dockerfile-image-update-6400121c1a75.

Если вы не управляете своим родительским изображением, как в случае, если вы зависите от официального изображения ubuntu, вы можете написать некоторые инструменты, которые обнаруживают изменения в теге родительского изображения и вызывают соответствующие сборки дочерних изображений.

Ответ 2

Мы используем script, который проверяет, запущен ли запущенный контейнер с последним изображением. Мы также используем upstart init scripts для запуска изображения докеров.

#!/usr/bin/env bash
set -e
BASE_IMAGE="registry"
REGISTRY="registry.hub.docker.com"
IMAGE="$REGISTRY/$BASE_IMAGE"
CID=$(docker ps | grep $IMAGE | awk '{print $1}')
docker pull $IMAGE

for im in $CID
do
    LATEST=`docker inspect --format "{{.Id}}" $IMAGE`
    RUNNING=`docker inspect --format "{{.Image}}" $im`
    NAME=`docker inspect --format '{{.Name}}' $im | sed "s/\///g"`
    echo "Latest:" $LATEST
    echo "Running:" $RUNNING
    if [ "$RUNNING" != "$LATEST" ];then
        echo "upgrading $NAME"
        stop docker-$NAME
        docker rm -f $NAME
        start docker-$NAME
    else
        echo "$NAME up to date"
    fi
done

И init выглядит как

docker run -t -i --name $NAME $im /bin/bash

Ответ 3

A 'docker way' будет использовать концентратор докеров автоматические сборки. Функция Repository Links будет восстанавливать ваш контейнер, когда восходящий контейнер будет перестроен, а Webhooks отправит вам уведомление.

Похоже, что веб-узлы ограничены вызовами HTTP POST. Вам нужно будет настроить службу, чтобы поймать их, или, возможно, использовать один из POST для почтовых служб там.

Я не изучал его, но новый Docker Universal Control Plane мог бы иметь функцию для обнаружения обновленных контейнеров и повторного развертывания.

Ответ 4

Вы можете использовать Сторожевую башню, чтобы следить за обновлениями образа, из которого создается контейнер, и автоматически извлекать обновление и перезапускать контейнер, используя обновленное изображение. Тем не менее, это не решает проблему восстановления ваших собственных пользовательских изображений, когда есть изменения в исходном изображении, на котором оно основано. Вы можете рассматривать это как проблему, состоящую из двух частей: (1) зная, когда был обновлен исходный образ, и (2) выполняя фактическое восстановление образа. (1) может быть решено довольно легко, но (2) во многом зависит от вашей локальной среды/практики сборки, поэтому, вероятно, гораздо сложнее создать обобщенное решение для этого.

Если вы можете использовать автоматические сборки Docker Hub, вся проблема может быть решена относительно чисто с помощью функции ссылок на репозиторий, которая позволяет автоматически запускать перестройку при обновлении связанного репозитория (возможно, вышестоящего). Вы также можете настроить веб-крючок, чтобы уведомлять вас, когда происходит автоматическая сборка. Если вам нужно уведомление по электронной почте или SMS, вы можете подключить веб-крючок к IFTTT Maker. Я нахожу, что пользовательский интерфейс IFTTT немного сбивает с толку, но вы должны настроить веб-крючок Docker для публикации на https://maker.ifttt.com/trigger/ docker_xyz_image_built/with/key/your_key.

Если вам необходимо выполнить локальную сборку, вы можете, по крайней мере, решить проблему получения уведомлений при обновлении исходного изображения, создав фиктивное репо в Docker Hub, связанное с интересующими вас репозиториями. Единственная цель фиктивного репо - запуск веб-крюка при его восстановлении (что означает, что одно из связанных репо было обновлено). Если вы можете получить этот веб-крючок, вы даже можете использовать его, чтобы вызвать перестройку на своей стороне.

Ответ 5

У меня была такая же проблема, и я думал, что ее можно просто решить с помощью задания cron, вызывающего unattended-upgrade ежедневно.

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

Также возможно автоматизировать сборку и развертывание изображений с помощью Github hooks

Я создал базовое изображение докеры, которое автоматически проверяет и устанавливает обновления безопасности ежедневно (может выполняться непосредственно docker run itech/docker-unattended-upgrade).

Я также столкнулся с другим методом , чтобы проверить, нуждается ли контейнер в обновлении.

Моя полная реализация:

Dockerfile

FROM ubuntu:14.04   

RUN apt-get update \
&& apt-get install -y supervisor unattended-upgrades \
&& rm -rf /var/lib/apt/lists/*

COPY install /install
RUN chmod 755 install
RUN /install

COPY start /start
RUN chmod 755 /start

Скрипты помощника

установить

#!/bin/bash
set -e

cat > /etc/supervisor/conf.d/cron.conf <<EOF
[program:cron]
priority=20
directory=/tmp
command=/usr/sbin/cron -f
user=root
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
EOF

rm -rf /var/lib/apt/lists/*

ENTRYPOINT ["/start"]

старт

#!/bin/bash

set -e

echo "Adding crontab for unattended-upgrade ..."
echo "0 0 * * * root /usr/bin/unattended-upgrade" >> /etc/crontab

# can also use @daily syntax or use /etc/cron.daily

echo "Starting supervisord ..."
exec /usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf

Edit

Я разработал небольшой инструмент docker-run, который работает как контейнер докеров и может использоваться для обновления пакетов во всех или выбранных запущенных контейнерах. также может использоваться для выполнения любых произвольных команд.

Может быть легко протестирован с помощью следующей команды:

docker run --rm -v /var/run/docker.sock:/tmp/docker.sock itech/docker-run exec

который по умолчанию выполнит команду date во всех работающих контейнерах и отобразит результаты. Если вы пройдете update вместо exec, он выполнит apt-get update, а затем apt-get upgrade -y во всех работающих контейнерах

Ответ 6

Вы не знали бы, что ваш контейнер стоит, не выполнив "docker pull" . Затем вам нужно rebuild или перекомпонировать ваш изображение.

docker pull image:tag
docker-compose -f docker-compose.yml -f production.yml up -d --build

Команды могут быть помещены в script вместе с чем-либо еще, необходимым для завершения обновления, хотя для соответствующего контейнера ничего не потребуется.

Ответ 7

Другой подход может заключаться в том, чтобы предположить, что ваш базовый образ будет довольно быстро (и, что очень вероятно, произойдет), и заставит другую структуру изображений вашего приложения периодически (например, каждую неделю), а затем повторно разверните ее, если она изменилась.

Насколько я могу судить, популярные базовые изображения, такие как официальный Debian или Java, обновляют их теги для исправления безопасности, поэтому теги не являются неизменяемыми (если вы хотите получить более сильную гарантию того, что вам нужно использовать ссылку [изображение: @digest], доступный в более поздних версиях Docker). Поэтому, если вы должны были создать свое изображение с помощью docker build --pull, ваше приложение должно получить самый последний и самый лучший тег базового изображения, на который вы ссылаетесь.

Так как изменяемые теги могут вводить в заблуждение, лучше всего увеличивать номер версии вашего приложения каждый раз, когда вы это делаете, чтобы по крайней мере на вашей стороне все было чище.

Поэтому я не уверен, что script, предложенный в одном из предыдущих ответов, выполняет задание, поскольку он не перестраивает ваш образ приложения - он просто обновляет тег базового изображения, а затем перезапускает контейнер, но новый контейнер по-прежнему ссылается на старый хэш-код базового изображения.

Я бы не выступал за выполнение заданий типа cron в контейнерах (или каких-либо других процессов, если это действительно необходимо), поскольку это противоречит мантре запуска только одного процесса на контейнер (есть различные аргументы в пользу того, почему это лучше, поэтому я не буду вдаваться в него здесь).

Ответ 8

Я не собираюсь задавать вопрос о том, хотите ли вы автоматические обновления в производстве (я думаю, что нет). Я просто оставляю это здесь для справки, если кто-то сочтет это полезным. Обновите все ваши изображения докеров до последней версии с помощью следующей команды в вашем терминале:

# docker images | awk '(NR>1) && ($2!~/none/) {print $1":"$2}' | xargs -L1 docker pull

Ответ 9

Управление зависимостями для изображений Docker является реальной проблемой. Я являюсь частью команды, которая построила инструмент MicroBadger, чтобы помочь в этом, отслеживая изображения контейнеров и проверяя метаданные. Одна из его функций - позволить вам настроить веб-хост уведомления, который вызывается, когда изменяется изображение, которое вас интересует (например, базовое изображение).

Ответ 10

Здесь много ответов, но ни один из них не отвечал моим потребностям. Я хотел получить реальный ответ на вопрос №1. Как узнать, когда изображение обновлено на hub.docker.com?

Ниже script можно запускать ежедневно. При первом запуске он получает базовые значения тегов и даты обновления из реестра HUB и сохраняет их локально. С этого момента каждый раз, когда он запускается, он проверяет реестр на новые теги и даты обновления. Поскольку это изменяется каждый раз, когда новое изображение существует, оно сообщает нам, изменилось ли базовое изображение. Вот script:

#!/bin/bash

DATAPATH='/data/docker/updater/data'

if [ ! -d "${DATAPATH}" ]; then
        mkdir "${DATAPATH}";
fi
IMAGES=$(docker ps --format "{{.Image}}")
for IMAGE in $IMAGES; do
        ORIGIMAGE=${IMAGE}
        if [[ "$IMAGE" != *\/* ]]; then
                IMAGE=library/${IMAGE}
        fi
        IMAGE=${IMAGE%%:*}
        echo "Checking ${IMAGE}"
        PARSED=${IMAGE//\//.}
        if [ ! -f "${DATAPATH}/${PARSED}" ]; then
                # File doesn't exist yet, make baseline
                echo "Setting baseline for ${IMAGE}"
                curl -s "https://registry.hub.docker.com/v2/repositories/${IMAGE}/tags/" > "${DATAPATH}/${PARSED}"
        else
                # File does exist, do a compare
                NEW=$(curl -s "https://registry.hub.docker.com/v2/repositories/${IMAGE}/tags/")
                OLD=$(cat "${DATAPATH}/${PARSED}")
                if [[ "${VAR1}" == "${VAR2}" ]]; then
                        echo "Image ${IMAGE} is up to date";
                else
                        echo ${NEW} > "${DATAPATH}/${PARSED}"
                        echo "Image ${IMAGE} needs to be updated";
                        H=`hostname`
                        ssh -i /data/keys/<KEYFILE> <USER>@<REMOTEHOST>.com "{ echo \"MAIL FROM: [email protected]${H}\"; echo \"RCPT TO: <USER>@<EMAILHOST>.com\"; echo \"DATA\"; echo \"Subject: ${H} - ${IMAGE} needs update\"; echo \"\"; echo -e \"\n${IMAGE} needs update.\n\ndocker pull ${ORIGIMAGE}\"; echo \"\"; echo \".\"; echo \"quit\"; sleep 1; } | telnet <SMTPHOST> 25"
                fi

        fi
done;

Вам нужно изменить переменную DATAPATH вверху и изменить команду уведомления по электронной почте в конце в соответствии с вашими потребностями. Для меня у меня есть SSH на сервере в другой сети, где находится мой SMTP. Но вы также можете легко использовать команду mail.

Теперь вы также хотите проверить обновления пакетов внутри самих контейнеров. На самом деле это, вероятно, более эффективно, чем "вытягивание", когда ваши контейнеры работают. Здесь script отключить:

#!/bin/bash


function needsUpdates() {
        RESULT=$(docker exec ${1} bash -c ' \
                if [[ -f /etc/apt/sources.list ]]; then \
                grep security /etc/apt/sources.list > /tmp/security.list; \
                apt-get update > /dev/null; \
                apt-get upgrade -oDir::Etc::Sourcelist=/tmp/security.list -s; \
                fi; \
                ')
        RESULT=$(echo $RESULT)
        GOODRESULT="Reading package lists... Building dependency tree... Reading state information... Calculating upgrade... 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded."
        if [[ "${RESULT}" != "" ]] && [[ "${RESULT}" != "${GOODRESULT}" ]]; then
                return 0
        else
                return 1
        fi
}

function sendEmail() {
        echo "Container ${1} needs security updates";
        H=`hostname`
        ssh -i /data/keys/<KEYFILE> <USRER>@<REMOTEHOST>.com "{ echo \"MAIL FROM: [email protected]${H}\"; echo \"RCPT TO: <USER>@<EMAILHOST>.com\"; echo \"DATA\"; echo \"Subject: ${H} - ${1} container needs security update\"; echo \"\"; echo -e \"\n${1} container needs update.\n\n\"; echo -e \"docker exec ${1} bash -c 'grep security /etc/apt/sources.list > /tmp/security.list; apt-get update > /dev/null; apt-get upgrade -oDir::Etc::Sourcelist=/tmp/security.list -s'\n\n\"; echo \"Remove the -s to run the update\"; echo \"\"; echo \".\"; echo \"quit\"; sleep 1; } | telnet <SMTPHOST> 25"
}

CONTAINERS=$(docker ps --format "{{.Names}}")
for CONTAINER in $CONTAINERS; do
        echo "Checking ${CONTAINER}"
        if needsUpdates $CONTAINER; then
                sendEmail $CONTAINER
        fi
done

Ответ 11

Помещение к моему ответу:

  • Контейнеры запускаются с тегами.
  • Тот же тег можно указать на другой UUID изображения, как мы считаем/считаем нужным.
  • Обновления, сделанные для изображения, могут быть привязаны к новому слою изображения

Подход

  • Создайте все контейнеры в первую очередь с обновлением обновления безопасности script
  • Создайте автоматизированный процесс для следующих
    • Запустите существующее изображение в новый контейнер с патчем безопасности script как команду
    • Зафиксировать изменения изображения как
      • существующий тег → , за которым следует перезапуск контейнеров по одному
      • тег новой версии → заменить несколько контейнеров новым тегом → validate → переместить все контейнеры в новый тег

Кроме того, базовое изображение может быть обновлено/контейнер с полным новым базовым изображением может быть создан через регулярные промежутки времени, так как он нуждается в необходимости

<сильные > Преимущества

  • Мы сохраняем старую версию изображения при создании нового исправленного файла безопасности, поэтому при необходимости мы можем откат к предыдущему запущенному изображению
  • Мы сохраняем кеш докера, а значит, и меньшую передачу сети (только на смену слом попадает)
  • Процесс обновления может быть проверен в процессе, прежде чем переходить к prod
  • Это может быть контролируемый процесс, поэтому исправления безопасности только тогда, когда это необходимо/считается важным, можно нажать.

Ответ 12

ОБНОВЛЕНИЕ: используйте Dependabot - https://dependabot.com/docker/

BLUF: найти правильную точку вставки для мониторинга изменений в контейнере - это непростая задача. Было бы здорово, если бы DockerHub решил эту проблему. (Ссылки на репозиторий были упомянуты, но обратите внимание при их настройке в DockerHub - "Запускать сборку в этом репозитории всякий раз, когда базовый образ обновляется в Docker Hub. Работает только для неофициальных изображений".)

Пытаясь решить эту проблему самостоятельно, я увидел несколько рекомендаций для веб-зацепок, поэтому я хотел бы остановиться на нескольких решениях, которые я использовал.

  1. Используйте microbadger.com, чтобы отслеживать изменения в контейнере и использовать его функция уведомлений для запуска действия. Я настроил это с zapier.com (но вы можете использовать любой настраиваемый сервис webhook) создать новую проблему в моем репозитории GitHub, который использует Alpine в качестве базовое изображение.

    • Плюсы: вы можете просмотреть изменения, о которых сообщил microbadger в github, прежде чем предпринимать какие-либо действия.
    • Минусы: Microbadger не позволяет отслеживать конкретный тег. Похоже, он отслеживает только "последние".
  2. Отслеживайте RSS-канал для git коммитов в вышестоящий контейнер. ех. https://github.com/gliderlabs/docker-alpine/commits/rootfs/library-3.8/x86_64. Я использовал zapier.com для мониторинга этого канала и запуска автоматической сборки моего контейнера в Travis-CI каждый раз, когда что-то совершается. Это немного экстремально, но вы можете изменить триггер, чтобы делать другие вещи, такие как открытие проблемы в вашем git-репозитории для ручного вмешательства.

    • Плюсы: ближе к автоматизированному pipeопроводу. Сборка Travis-CI просто проверяет, есть ли у вашего контейнера проблемы с тем, что было зафиксировано в репозитории базовых образов. Вам решать, если ваша служба CI предпримет какие-либо дальнейшие действия.
    • Минусы: отслеживание коммитов не идеально. В хранилище добавляется множество вещей, которые не влияют на сборку базового образа. Не учитывает никаких проблем с частотой/количеством коммитов и регулированием API.

Ответ 13

Выше Ответы также верны

Есть два подхода

  1. Используйте веб-крючки
  2. Запускайте скрипт на каждую конкретную минуту, чтобы получить свежее изображение с докером

Я просто делюсь сценарием, может быть, это будет полезно для вас! Вы можете использовать его с cronjob, я успешно попробовал на OSX

#!/bin/bash
##You can use below commented line for setting cron tab for running cron job and to store its O/P in one .txt file  
#* * * * * /usr/bin/sudo -u admin -i bash -c /Users/Swapnil/Documents/checkimg.sh > /Users/Swapnil/Documents/cron_output.log 2>&1
# Example for the Docker Hub V2 API
# Returns all images and tags associated with a Docker Hub organization account.
# Requires 'jq': https://stedolan.github.io/jq/

# set username, password, and organization
# Filepath where your docker-compose file is present
FILEPATH="/Users/Swapnil/Documents/lamp-alpine"
# Your Docker hub user name
UNAME="ur username"
# Your Docker hub user password
UPASS="ur pwd"
# e.g organisation_name/image_name:image_tag
ORG="ur org name"
IMGNAME="ur img name"
IMGTAG="ur img tag"
# Container name
CONTNAME="ur container name"
# Expected built mins
BUILDMINS="5"
#Generally cronjob frequency
CHECKTIME="5"
NETWORKNAME="${IMGNAME}_private-network"
#After Image pulling, need to bring up all docker services?
DO_DOCKER_COMPOSE_UP=true
# -------
echo "Eecuting Script @ date and time in YmdHMS: $(date +%Y%m%d%H%M%S)"
set -e
PIDFILE=/Users/Swapnil/Documents/$IMGNAME/forever.pid
if [ -f $PIDFILE ]
then
  PID=$(cat $PIDFILE)
  ps -p $PID > /dev/null 2>&1
  if [ $? -eq 0 ]
  then
    echo "Process already running"
    exit 1
  else
    ## Process not found assume not running
    echo $$
    echo $$ > $PIDFILE
    if [ $? -ne 0 ]
    then
      echo "Could not create PID file"
      exit 1
    fi
  fi
else
  echo $$ > $PIDFILE
  if [ $? -ne 0 ]
  then
    echo "Could not create PID file"
    exit 1
  fi
fi

# Check Docker is running or not; If not runing then exit
if docker info|grep Containers ; then
    echo "Docker is running"
else
    echo "Docker is not running"
    rm $PIDFILE
    exit 1
fi

# Check Container is running or not; and set variable
CONT_INFO=$(docker ps -f "name=$CONTNAME" --format "{{.Names}}")
if [ "$CONT_INFO" = "$CONTNAME" ]; then
    echo "Container is running"
    IS_CONTAINER_RUNNING=true
else
    echo "Container is not running"
    IS_CONTAINER_RUNNING=false
fi


# get token
echo "Retrieving token ..."
TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${UNAME}'", "password": "'${UPASS}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token)

# get list of repositories
echo "Retrieving repository list ..."
REPO_LIST=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/${ORG}/?page_size=100 | jq -r '.results|.[]|.name')

# output images & tags
echo "Images and tags for organization: ${ORG}"
echo
for i in ${REPO_LIST}
do
  echo "${i}:"
  # tags
  IMAGE_TAGS=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/${ORG}/${i}/tags/?page_size=100 | jq -r '.results|.[]|.name')
  for j in ${IMAGE_TAGS}
  do
    echo "  - ${j}"
  done
  #echo
done

# Check Perticular image is the latest or not
#imm=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/${ORG}/${IMGNAME}/tags/?page_size=100)
echo "-----------------"
echo "Last built date details about Image ${IMGNAME} : ${IMGTAG} for organization: ${ORG}"
IMAGE_UPDATED_DATE=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/${ORG}/${IMGNAME}/tags/?page_size=100 | jq -r '.results|.[]|select(.name | contains("'${IMGTAG}'")).last_updated')
echo "On Docker Hub IMAGE_UPDATED_DATE---$IMAGE_UPDATED_DATE"
echo "-----------------"

IMAGE_CREATED_DATE=$(docker image inspect ${ORG}/${IMGNAME}:${IMGTAG} | jq -r '.[]|.Created')
echo "Locally IMAGE_CREATED_DATE---$IMAGE_CREATED_DATE"

updatedDate=$(date -jf '%Y-%m-%dT%H:%M' "${IMAGE_UPDATED_DATE:0:16}" +%Y%m%d%H%M%S) 
createdDate=$(date -jf '%Y-%m-%dT%H:%M' "${IMAGE_CREATED_DATE:0:16}" +%Y%m%d%H%M%S)
currentDate=$(date +%Y%m%d%H%M%S)

start_date=$(date -jf "%Y%m%d%H%M%S" "$currentDate" "+%s")
end_date=$(date -jf "%Y%m%d%H%M%S" "$updatedDate" "+%s")
updiffMins=$(( ($start_date - $end_date) / (60) ))
if [[ "$updiffMins" -lt $(($CHECKTIME+1)) ]]; then
        if [ ! -d "${FILEPATH}" ]; then
            mkdir "${FILEPATH}";
        fi
        cd "${FILEPATH}"
        pwd
        echo "updatedDate---$updatedDate" > "ScriptOutput_${currentDate}.txt"
        echo "createdDate---$createdDate" >> "ScriptOutput_${currentDate}.txt"
        echo "currentDate---$currentDate" >> "ScriptOutput_${currentDate}.txt"
        echo "Found after regular checking time -> Docker hub latest updated image is new; Diff ${updiffMins} mins" >> "ScriptOutput_${currentDate}.txt"
        echo "Script is checking for latest updates after every ${CHECKTIME} mins" >> "ScriptOutput_${currentDate}.txt"
        echo "Fetching all new"
        echo "---------------------------"
        if $IS_CONTAINER_RUNNING ; then
            echo "Container is running"         
        else
            docker-compose down
            echo "Container stopped and removed; Network removed" >> "ScriptOutput_${currentDate}.txt"
        fi
        echo "Image_Created_Date=$currentDate" > ".env"
        echo "ORG=$ORG" >> ".env"
        echo "IMGNAME=$IMGNAME" >> ".env"
        echo "IMGTAG=$IMGTAG" >> ".env"
        echo "CONTNAME=$CONTNAME" >> ".env"
        echo "NETWORKNAME=$NETWORKNAME" >> ".env"
        docker-compose build --no-cache
        echo "Docker Compose built" >> "ScriptOutput_${currentDate}.txt"
        if $DO_DOCKER_COMPOSE_UP ; then
            docker-compose up -d
            echo "Docker services are up now, checked in" >> "ScriptOutput_${currentDate}.txt"  
        else
            echo "Docker services are down, checked in" >> "ScriptOutput_${currentDate}.txt"
        fi
elif [[ "$updatedDate" -gt "$createdDate" ]]; then 
    echo "Updated is latest"
    start_date=$(date -jf "%Y%m%d%H%M%S" "$updatedDate" "+%s")
    end_date=$(date -jf "%Y%m%d%H%M%S" "$createdDate" "+%s")
    diffMins=$(( ($start_date - $end_date) / (60) ))
    if [[ "$BUILDMINS" -lt "$diffMins" ]]; then
        if [ ! -d "${FILEPATH}" ]; then
            mkdir "${FILEPATH}";
        fi
        cd "${FILEPATH}"
        pwd
        echo "updatedDate---$updatedDate" > "ScriptOutput_${currentDate}.txt"
        echo "createdDate---$createdDate" >> "ScriptOutput_${currentDate}.txt"
        echo "currentDate---$currentDate" >> "ScriptOutput_${currentDate}.txt"
        echo "Found after comparing times -> Docker hub latest updated image is new; Diff ${diffMins} mins" >> "ScriptOutput_${currentDate}.txt"
        echo "Actual image built time is less i.e. ${diffMins} mins than MAX expexted BUILD TIME i.e. ${BUILDMINS} mins" >> "ScriptOutput_${currentDate}.txt"
        echo "Fetching all new" >> "ScriptOutput_${currentDate}.txt"
        echo "-----------------------------"
        if $IS_CONTAINER_RUNNING ; then
            echo "Container is running"         
        else
            docker-compose down
            echo "Container stopped and removed; Network removed" >> "ScriptOutput_${currentDate}.txt"
        fi
        echo "Image_Created_Date=$currentDate" > ".env"
        echo "ORG=$ORG" >> ".env"
        echo "IMGNAME=$IMGNAME" >> ".env"
        echo "IMGTAG=$IMGTAG" >> ".env"
        echo "CONTNAME=$CONTNAME" >> ".env"
        echo "NETWORKNAME=$NETWORKNAME" >> ".env"
        docker-compose build --no-cache
        echo "Docker Compose built" >> "ScriptOutput_${currentDate}.txt"
        if $DO_DOCKER_COMPOSE_UP ; then
            docker-compose up -d
            echo "Docker services are up now" >> "ScriptOutput_${currentDate}.txt"  
        else
            echo "Docker services are down" >> "ScriptOutput_${currentDate}.txt"
        fi
    elif [[ "$BUILDMINS" -gt "$diffMins" ]]; then
        echo "Docker hub latest updated image is NOT new; Diff ${diffMins} mins"
        echo "Docker images not fetched"
    else
        echo "Docker hub latest updated image is NOT new; Diff ${diffMins} mins"
        echo "Docker images not fetched"
    fi
elif [[ "$createdDate" -gt "$updatedDate" ]]; then 
    echo "Created is latest"
    start_date=$(date -jf "%Y%m%d%H%M%S" "$createdDate" "+%s")
    end_date=$(date -jf "%Y%m%d%H%M%S" "$updatedDate" "+%s")
    echo "Docker hub has older docker image than local; Older than $(( ($start_date - $end_date) / (60) ))mins"
fi
echo 
echo "------------end---------------"
rm $PIDFILE

Вот мой файл docker-compose

version:  "3.2"
services:
  lamp-alpine:
    build:
      context: .
    container_name: "${CONTNAME}"
    image: "${ORG}/${IMGNAME}:${IMGTAG}"
    ports:
      - "127.0.0.1:80:80"
    networks:
      - private-network 

networks:
  private-network:
    driver: bridge

Ответ 14

Вот самый простой способ автоматического обновления Docker-контейнера.

Поместите задание через $ crontab -e:

0 * * * * sh ~/.docker/cron.sh

Создайте dir ~/.docker с файлом cron.sh:

#!/bin/sh
if grep -Fqe "Image is up to date" << EOF
'docker pull ubuntu:latest'
EOF
then
    echo "no update, just do cleaning"
    docker system prune --force
else
    echo "newest exist, recompose!"
    cd /path/to/your/compose/file
    docker-compose down --volumes
    docker-compose up -d
fi

Ответ 15

Простое и отличное решение - пастух

Ответ 16

Вы пробовали это: https://github.com/v2tec/watchtower. Это простой инструмент, работающий в Docker-контейнере, наблюдающий за другими контейнерами; если их базовое изображение изменилось, он извлечет и повторно развернет.