source

기본 이미지가 업데이트된 경우 도커 컨테이너를 자동으로 업데이트하는 방법

ittop 2023. 8. 5. 11:00
반응형

기본 이미지가 업데이트된 경우 도커 컨테이너를 자동으로 업데이트하는 방법

예를 들어 나는 다음을 기반으로 하는 사소한 컨테이너를 가지고 있습니다.ubuntu:latest와 이제보가있고트이데업,ubuntu:latest도커 레포에서 업데이트되었습니다.

  1. 로컬 이미지와 컨테이너가 뒤쳐지고 있는지 어떻게 알 수 있습니까?

  2. 도커 repo 업데이트를 따르도록 로컬 이미지와 컨테이너를 자동으로 업데이트하는 모범 사례가 있습니까? 실제로는 기존 우분투 컴퓨터에서 무인 업그레이드를 실행하는 것과 동일한 종류를 제공합니다.

실행 중인 컨테이너가 최신 이미지로 시작되는지 확인하는 스크립트를 사용합니다.또한 도커 이미지를 시작하기 위해 upstart init 스크립트를 사용합니다.

    #!/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

그리고 그 안에는

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

WatchTower를 사용하여 컨테이너가 인스턴스화된 이미지의 업데이트를 확인하고 업데이트된 이미지를 사용하여 자동으로 업데이트를 풀하고 컨테이너를 다시 시작할 수 있습니다.그러나 기반이 되는 업스트림 이미지가 변경된 경우 사용자 지정 이미지를 재구축하는 문제는 해결되지 않습니다.이 문제는 (1) 업스트림 이미지가 업데이트된 시기를 파악하는 것과 (2) 실제 이미지 재구축을 수행하는 것으로 볼 수 있습니다. (1) 상당히 쉽게 해결할 수 있지만 (2) 로컬 빌드 환경/프랙티스에 따라 크게 달라지므로 일반화된 솔루션을 만드는 것이 훨씬 어려울 수 있습니다.

Docker Hub의 자동 빌드를 사용할 수 있는 경우, 연결된 리포지토리(아마 업스트림 리포지토리)가 업데이트될 때 자동으로 재구성을 트리거할 수 있는 리포지토리 링크 기능을 사용하여 전체 문제를 비교적 깨끗하게 해결할 수 있습니다.자동 빌드가 발생할 때 사용자에게 알리도록 후크를 구성할 수도 있습니다.이메일 또는 SMS 알림을 원하는 경우 웹 훅을 IFTTT Maker에 연결할 수 있습니다.IFTTT 사용자 인터페이스가 좀 헷갈리긴 했지만, https://maker.ifttt.com/trigger/ 'domer_xyz_image_built'/with/key/'your_key'에 게시하도록 도커 웹 훅을 구성할 것입니다.

로컬로 빌드해야 하는 경우 관심 보고서에 연결된 Docker Hub에 더미 레포를 만들어 업스트림 이미지가 업데이트될 때 알림을 받는 문제를 해결할 수 있습니다.더미 레포의 유일한 목적은 재구축 시 웹 훅을 트리거하는 것입니다(링크된 레포 중 하나가 업데이트되었음을 의미합니다).이 웹 훅을 수신할 수 있는 경우 이를 사용하여 사용자 쪽에서 재구성을 트리거할 수도 있습니다.

'도커 방법'은 도커 허브 자동 빌드를 사용하는 것입니다.리포지토리 연결 기능은 업스트림 컨테이너가 재구성될 때 컨테이너를 재구성하고 훅 기능은 알림을 보냅니다.

웹 훅이 HTTP POST 통화로 제한되어 있는 것 같습니다.당신은 그들을 잡기 위해 서비스를 설정해야 할 것입니다. 아니면 POST 중 하나를 사용하여 서비스를 이메일로 보낼 수도 있습니다.

알아본 적은 없지만, 새로운 도커 유니버설 컨트롤 플레인에는 업데이트된 컨테이너를 감지하고 다시 배치하는 기능이 있을 수 있습니다.

이를 수행하는 방법 중 하나는 CI/CD 시스템을 통해 이를 구동하는 것입니다.상위 이미지가 작성되면 해당 상위 이미지를 사용하여 Git 저장소에서 이미지를 검색하는 기능을 사용합니다.찾은 경우 이미지의 새 버전으로 이동하기 위해 꺼내기 요청을 보냅니다.모든 테스트가 통과되면 꺼내기 요청이 병합되고 업데이트된 부모를 기반으로 새 자식 이미지가 생성됩니다.이러한 접근 방식을 사용하는 툴의 예는 https://engineering.salesforce.com/open-sourcing-dockerfile-image-update-6400121c1a75 에서 확인할 수 있습니다.

만약 당신이 당신의 부모 이미지를 통제하지 않는다면, 당신이 공식에 의존하는 경우가 있을 것입니다.ubuntu이미지, 상위 이미지 태그 또는 체크섬의 변경을 감지하는 도구(동일하지 않음, 태그는 변경 가능)를 작성하고 그에 따라 하위 이미지 빌드를 호출할 수 있습니다.

저도 같은 문제가 있었고 cron job calling으로 간단히 해결할 수 있다고 생각했습니다.unattended-upgrade매일 일어나는.

이미지를 업데이트하고 최신 보안 업데이트가 포함된 새 도커 이미지를 배포하는 데 시간이 걸릴 수 있으므로 프로덕션 컨테이너의 보안 및 업데이트를 보장하기 위한 자동 및 빠른 솔루션으로 사용하고자 합니다.

Github 후크를 사용하여 이미지 빌드 및 배포를 자동화할 수도 있습니다.

보안 업데이트를 매일 자동으로 확인하고 설치하는 기본 도커 이미지를 만들었습니다(직접 실행 가능).docker run itech/docker-unattended-upgrade).

컨테이너에 업데이트가 필요한지 확인하기 위해 다른 접근법도 발견했습니다.

완벽한 구현:

도커 파일

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

편집

나는 도커 컨테이너로 실행되는 작은 도구 도커 실행을 개발했고, 모든 또는 선택된 실행 중인 컨테이너 내부의 패키지를 업데이트하는 데 사용할 수 있으며, 임의의 명령을 실행하는 데 사용할 수 있습니다.

다음 명령을 사용하여 쉽게 테스트할 수 있습니다.

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

으로 실행할 입니다.date실행 중인 모든 컨테이너에서 명령을 실행하고 결과를 표시합니다. 당신이 면격하를 한다면.updateexec은 것다니입실행을 실행합니다.apt-get update에 뒤에apt-get upgrade -y 중인

도커 풀을 실행하지 않으면 컨테이너가 뒤에 있다는 것을 알 수 없습니다.그런 다음 이미지를 다시 작성하거나 재구성해야 합니다.

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

업그레이드를 완료하는 데 필요한 다른 모든 명령과 함께 스크립트에 명령을 넣을 수 있습니다. 그러나 적절한 컨테이너에는 추가적인 것이 필요하지 않습니다.

도커 컨테이너를 자동으로 업데이트하는 가장 간단한 방법은 다음과 같습니다.

다음을 통해 작업 수행$ crontab -e:

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

하기 성~/.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

도커 이미지에 대한 종속성 관리는 실제 문제입니다.저는 컨테이너 이미지를 모니터링하고 메타데이터를 검사함으로써 이 문제를 해결하기 위한 도구인 MicroBadger를 만든 팀의 일원입니다.이 기능 중 하나는 관심 있는 이미지(예: 기본 이미지)가 변경될 때 호출되는 알림 웹 훅을 설정할 수 있도록 하는 것입니다.

여기에는 많은 답이 있지만, 제 요구에 맞는 답은 하나도 없습니다.질문자의 1번 질문에 대한 실제 답변을 원했습니다.hub.docker.com 에서 이미지가 업데이트되는지 어떻게 알 수 있습니까?

아래 스크립트는 매일 실행할 수 있습니다.처음 실행할 때는 HUB 레지스트리에서 태그 및 업데이트 날짜의 기준선을 가져와 로컬로 저장합니다.이때부터 실행될 때마다 레지스트리에서 새 태그 및 업데이트 날짜를 확인합니다.새 이미지가 존재할 때마다 변경되므로 기본 이미지가 변경되었는지 여부를 알려줍니다.스크립트는 다음과 같습니다.

#!/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: root@${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맨 위에 변수를 표시하고, 마지막에 이메일 알림 명령을 사용자의 필요에 맞게 변경합니다.저는 SMTP가 위치한 다른 네트워크의 서버에 SSH를 연결합니다.하지만 당신은 쉽게 사용할 수 있습니다.mail명령어도.

이제 컨테이너 내부의 업데이트된 패키지도 확인하려고 합니다.이것은 용기가 작동한 후 "끌기"를 하는 것보다 실제로 더 효과적입니다.이를 실현하기 위한 스크립트는 다음과 같습니다.

#!/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: root@${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

또 다른 접근 방식은 기본 이미지가 매우 빠르게 지연된다고 가정하고(이 경우 가능성이 매우 높음), 정기적으로(예: 매주) 다른 이미지 빌드를 강제로 실행한 후 변경된 경우 다시 구현하는 것입니다.

제가 알기로는 공식 Debian 또는 Java와 같은 인기 있는 기본 이미지는 보안 수정 사항을 충족하기 위해 태그를 업데이트하므로 태그는 불변하지 않습니다(더 강력한 보증을 원한다면 최신 도커 버전에서 사용할 수 있는 참조 [image:@digest]를 사용해야 합니다).그러므로, 만약 당신이 당신의 이미지를 구축한다면.docker build --pull그러면 응용 프로그램이 참조하는 기본 이미지 태그 중 가장 최신의 태그를 얻을 수 있습니다.

가변 태그는 혼동을 일으킬 수 있으므로 응용 프로그램의 버전 번호를 매번 늘리는 것이 가장 좋습니다. 따라서 최소한 사용자의 입장에서는 더 깨끗한 것이 좋습니다.

따라서 이전 답변 중 하나에서 제안한 스크립트가 제대로 작동하는지 확신할 수 없습니다. 애플리케이션의 이미지를 재구성하지 않고 기본 이미지 태그만 업데이트한 다음 컨테이너를 다시 시작하지만 새 컨테이너는 여전히 이전 기본 이미지 해시를 참조합니다.

컨테이너(또는 다른 프로세스)에서 cron 유형의 작업을 실행하는 것은 컨테이너당 하나의 프로세스만 실행하는 것에 반하는 것이기 때문에 옹호하지 않습니다(왜 이것이 더 나은지에 대한 다양한 주장이 있으므로 여기서는 다루지 않겠습니다).

업데이트: Dependabot 사용 - https://dependabot.com/docker/

BLUF: 컨테이너 변경을 모니터링하기 위한 올바른 삽입 지점을 찾는 것은 어려운 일입니다.DockerHub가 이 문제를 해결해준다면 좋을 것입니다. (리포지토리 링크가 언급되었지만 DockerHub에서 설정할 때 참고하십시오. "기본 이미지가 DockerHub에서 업데이트될 때마다 이 리포지토리에서 빌드를 트리거합니다. 비공식 이미지에만 사용할 수 있습니다.")

이 문제를 직접 해결하려고 시도하는 동안 웹 훅에 대한 몇 가지 권장 사항을 보았기 때문에 제가 사용한 몇 가지 솔루션에 대해 자세히 설명하고자 합니다.

  1. microbadger.com 을 사용하여 컨테이너의 변경 내용을 추적하고 해당 알림 웹 훅 기능을 사용하여 작업을 트리거합니다.저는 이것을 zapier.com 에서 설정했습니다(그러나 사용자 지정 가능한 웹 훅 서비스를 사용할 수 있습니다). 제 github 저장소에서 Alpine을 기본 이미지로 사용하는 새 문제를 만들기 위해.

    • 찬성: 당신은 조치를 취하기 전에 github에서 microbager에 의해 보고된 변경사항을 검토할 수 있습니다.
    • 단점: 마이크로오소리는 특정 태그를 추적할 수 없습니다.'최신'만 추적하는 것 같습니다.
  2. 업스트림 컨테이너에 대한 git 커밋에 대한 RSS 피드를 추적합니다.https://github.com/gliderlabs/docker-alpine/commits/rootfs/library-3.8/x86_64 .저는 zapier.com 을 사용하여 이 피드를 모니터링하고 무언가가 커밋될 때마다 Travis-CI에서 제 컨테이너의 자동 빌드를 트리거했습니다.이것은 약간 극단적이지만 수동 개입을 위해 Git 저장소에서 문제를 여는 것과 같은 다른 작업을 수행하도록 트리거를 변경할 수 있습니다.

    • 찬성: 자동화된 파이프라인에 가깝습니다.Travis-CI 빌드는 기본 이미지 저장소에 커밋된 컨테이너에 문제가 있는지 확인합니다.CI 서비스가 추가 조치를 취할지 여부는 사용자에게 달려 있습니다.
    • 반대: 커밋 피드를 추적하는 것은 완벽하지 않습니다.기본 이미지의 빌드에 영향을 미치지 않는 많은 것들이 저장소에 커밋됩니다.커밋 빈도/수 및 API 조절과 관련된 문제는 고려하지 않습니다.

운영 환경에서 무인 업데이트를 원하는지 여부에 대한 전체적인 질문은 하지 않을 것입니다(그렇지 않을 것 같습니다.유용하다고 생각되는 사람이 있을지도 모르니까 참고용으로 남겨두는 겁니다.터미널에서 다음 명령을 사용하여 모든 도커 이미지를 최신 버전으로 업데이트합니다.

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

내 대답의 전제:

  1. 컨테이너는 태그를 사용하여 실행됩니다.
  2. 동일한 태그를 원하는 대로 다른 이미지 UUID를 가리킬 수 있습니다.
  3. 이미지에 수행된 업데이트를 새 이미지 계층에 커밋할 수 있습니다.

접근

  1. 보안 패치 업데이트 스크립트를 사용하여 모든 컨테이너를 처음부터 빌드
  2. 다음을 위한 자동화된 프로세스 구축
    • 보안 패치 스크립트를 명령으로 사용하여 기존 이미지를 새 컨테이너로 실행
    • 다음으로 이미지 변경 커밋
      • 기존 태그 -> 이어서 컨테이너를 하나씩 다시 시작합니다.
      • 새 버전 태그 -> 몇 개의 컨테이너를 새 태그로 교체 -> 검증 -> 모든 컨테이너를 새 태그로 이동

또한 기본 이미지를 업그레이드할 수 있습니다./ 유지관리자가 필요하다고 생각하는 경우 정기적으로 완전히 새로운 기본 이미지가 포함된 컨테이너를 구축할 수 있습니다.

이점

  1. 새 보안 패치 이미지를 생성하는 동안 이전 버전의 이미지를 보존하므로 필요한 경우 이전 실행 중인 이미지로 롤백할 수 있습니다.
  2. 도커 캐시를 보존하므로 네트워크 전송이 줄어듭니다(변경된 계층만 와이어에 연결됨).
  3. Prod로 이동하기 전에 스테이징에서 업그레이드 프로세스를 검증할 수 있습니다.
  4. 이는 제어된 프로세스일 수 있으므로, 필요한 경우에만/중요하다고 판단되는 경우에만 보안 패치를 적용할 수 있습니다.

위의 답변도 정답입니다.

두 가지 접근 방식이 있습니다.

  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's 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's 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's latest updated image is NOT new; Diff ${diffMins} mins"
        echo "Docker images not fetched"
    else
        echo "Docker hub's 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

여기 제 도커 컴포지트 파일이 있습니다.

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

시도해 보셨습니까: https://github.com/v2tec/watchtower .도커 컨테이너에서 실행되는 간단한 도구로 다른 컨테이너의 기본 이미지가 변경되면 끌어다 다시 배치합니다.

간단하고 훌륭한 해결책은 셰퍼드입니다.

언급URL : https://stackoverflow.com/questions/26423515/how-to-automatically-update-your-docker-containers-if-base-images-are-updated

반응형