amazon web services - AWS Lightsail Automatically Clear Container Images - Stack Overflow

admin2025-04-29  1

I want to automatically delete the existing container images that are not currently in use from the storage. We store the images already elsewhere and aws will reject a container push if too many images build up.

This is currently my .gitlab-ci.yml job that I use to automatically push our image over to aws. What I have works if the first image is the one that is in use, but I would like something more robust for our more complex services with multiple containers in one deployment. Something about this just feels wrong and I feel like I am missing a more obvious way to "delete all the images I am allowed to delete".

deploy:
  stage: Deploy
  only:
    - tags
    - main
  image: registry.gitlab/my-group/my-project:deployment
  services:
    - docker:dind
  needs: ["build_web"]
  before_script:
    - docker login registry.gitlab -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD}
  script:
    - docker buildx build -t ${SERVICE_IMAGE} -f Dockerfile .
    - all_images=$(aws lightsail get-container-images --service-name ${SERVICE_NAME} --query "containerImages[].image" --output text)
    - skip_image=$(echo $all_images | awk '{print $1}')
    - |
      for image in $all_images; do
        if [ "$image" != "$skip_image" ]; then
          echo "Deleting old image: $image";
          aws lightsail delete-container-image --service-name ${SERVICE_NAME} --image "$image";
        fi;
      done
    - aws lightsail push-container-image --service-name ${SERVICE_NAME} --label ${SERVICE_NAME}-${CI_PIPELINE_ID} --image ${SERVICE_IMAGE}
    - |
      aws lightsail create-container-service-deployment \
        --region us-east-2 \
        --service-name ${SERVICE_NAME} \
        --output yaml \
        --containers "{
          \"${SERVICE_NAME}\": {
            \"image\": \":${SERVICE_NAME}.${SERVICE_NAME}-${CI_PIPELINE_ID}.latest\",
            \"environment\": {
              \"PORT\": \"3001\"
            },
            \"ports\": {
              \"3001\": \"HTTP\"
            }
          }
        }" \
        --public-endpoint "{
          \"containerName\": \"${SERVICE_NAME}\",
          \"containerPort\": 3001,
          \"healthCheck\": {
            \"path\": \"/\",
            \"timeoutSeconds\": 2,
            \"intervalSeconds\": 5,
            \"healthyThreshold\": 2,
            \"unhealthyThreshold\": 2,
            \"successCodes\": \"200-499\"
          }
        }"
  after_script:
    - docker push ${SERVICE_IMAGE}
  environment: production

I want to automatically delete the existing container images that are not currently in use from the storage. We store the images already elsewhere and aws will reject a container push if too many images build up.

This is currently my .gitlab-ci.yml job that I use to automatically push our image over to aws. What I have works if the first image is the one that is in use, but I would like something more robust for our more complex services with multiple containers in one deployment. Something about this just feels wrong and I feel like I am missing a more obvious way to "delete all the images I am allowed to delete".

deploy:
  stage: Deploy
  only:
    - tags
    - main
  image: registry.gitlab.com/my-group/my-project:deployment
  services:
    - docker:dind
  needs: ["build_web"]
  before_script:
    - docker login registry.gitlab.com -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD}
  script:
    - docker buildx build -t ${SERVICE_IMAGE} -f Dockerfile .
    - all_images=$(aws lightsail get-container-images --service-name ${SERVICE_NAME} --query "containerImages[].image" --output text)
    - skip_image=$(echo $all_images | awk '{print $1}')
    - |
      for image in $all_images; do
        if [ "$image" != "$skip_image" ]; then
          echo "Deleting old image: $image";
          aws lightsail delete-container-image --service-name ${SERVICE_NAME} --image "$image";
        fi;
      done
    - aws lightsail push-container-image --service-name ${SERVICE_NAME} --label ${SERVICE_NAME}-${CI_PIPELINE_ID} --image ${SERVICE_IMAGE}
    - |
      aws lightsail create-container-service-deployment \
        --region us-east-2 \
        --service-name ${SERVICE_NAME} \
        --output yaml \
        --containers "{
          \"${SERVICE_NAME}\": {
            \"image\": \":${SERVICE_NAME}.${SERVICE_NAME}-${CI_PIPELINE_ID}.latest\",
            \"environment\": {
              \"PORT\": \"3001\"
            },
            \"ports\": {
              \"3001\": \"HTTP\"
            }
          }
        }" \
        --public-endpoint "{
          \"containerName\": \"${SERVICE_NAME}\",
          \"containerPort\": 3001,
          \"healthCheck\": {
            \"path\": \"/\",
            \"timeoutSeconds\": 2,
            \"intervalSeconds\": 5,
            \"healthyThreshold\": 2,
            \"unhealthyThreshold\": 2,
            \"successCodes\": \"200-499\"
          }
        }"
  after_script:
    - docker push ${SERVICE_IMAGE}
  environment: production
Share Improve this question asked Jan 7 at 3:46 Christopher WroggChristopher Wrogg 576 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

After some work I came up with the following:

- |
      ACTIVE_IMAGES=$(aws lightsail get-container-services \
        --service-name ${SERVICE_NAME} \
        --query "containerServices[0].currentDeployment.containers.*.image" \
        --output text)

      EXISTING_IMAGES=$(aws lightsail get-container-images \
        --service-name ${SERVICE_NAME} \
        --query "containerImages[*].image" \
        --output text)

      for IMAGE in ${EXISTING_IMAGES}; do
        if [[ ! "${ACTIVE_IMAGES}" =~ "${IMAGE}" ]]; then
          echo "Deleting unused image: ${IMAGE}"
          aws lightsail delete-container-image \
            --service-name ${SERVICE_NAME} \
            --image "${IMAGE}"
        fi
      done
转载请注明原文地址:http://anycun.com/QandA/1745933263a91314.html