How do I deploy updated Docker images to Amazon ECS tasks?
Solution 1:
If your task is running under a service you can force a new deployment. This forces the task definition to be re-evaluated and the new container image to be pulled.
aws ecs update-service --cluster <cluster name> --service <service name> --force-new-deployment
Solution 2:
Every time you start a task (either through the StartTask
and RunTask
API calls or that is started automatically as part of a Service), the ECS Agent will perform a docker pull
of the image
you specify in your task definition. If you use the same image name (including tag) each time you push to your registry, you should be able to have the new image run by running a new task. Note that if Docker cannot reach the registry for any reason (e.g., network issues or authentication issues), the ECS Agent will attempt to use a cached image; if you want to avoid cached images from being used when you update your image, you'll want to push a different tag to your registry each time and update your task definition correspondingly before running the new task.
Update: This behavior can now be tuned through the ECS_IMAGE_PULL_BEHAVIOR
environment variable set on the ECS agent. See the documentation for details. As of the time of writing, the following settings are supported:
The behavior used to customize the pull image process for your container instances. The following describes the optional behaviors:
If
default
is specified, the image is pulled remotely. If the image pull fails, then the container uses the cached image on the instance.If
always
is specified, the image is always pulled remotely. If the image pull fails, then the task fails. This option ensures that the latest version of the image is always pulled. Any cached images are ignored and are subject to the automated image cleanup process.If
once
is specified, the image is pulled remotely only if it has not been pulled by a previous task on the same container instance or if the cached image was removed by the automated image cleanup process. Otherwise, the cached image on the instance is used. This ensures that no unnecessary image pulls are attempted.If
prefer-cached
is specified, the image is pulled remotely if there is no cached image. Otherwise, the cached image on the instance is used. Automated image cleanup is disabled for the container to ensure that the cached image is not removed.
Solution 3:
Registering a new task definition and updating the service to use the new task definition is the approach recommended by AWS. The easiest way to do this is to:
- Navigate to Task Definitions
- Select the correct task
- Choose create new revision
- If you're already pulling the latest version of the container image with something like the :latest tag, then just click Create. Otherwise, update the version number of the container image and then click Create.
- Expand Actions
- Choose Update Service (twice)
- Then wait for the service to be restarted
This tutorial has more detail and describes how the above steps fit into an end-to-end product development process.
Full disclosure: This tutorial features containers from Bitnami and I work for Bitnami. However the thoughts expressed here are my own and not the opinion of Bitnami.
Solution 4:
There are two ways to do this.
First, use AWS CodeDeploy. You can config Blue/Green deployment sections in ECS service definition. This includes a CodeDeployRoleForECS, another TargetGroup for switch, and a test Listener (optional). AWS ECS will create CodeDeploy application and deployment group and link these CodeDeploy resources with your ECS Cluster/Service and your ELB/TargetGroups for you. Then you can use CodeDeploy to initiate a deployment, in which you need to enter an AppSpec that specifies using what task/container to update what service. Here is where you specify your new task/container. Then, you will see new instances are spin up in the new TargetGroup and the old TargetGroup is disconnected to the ELB, and soon the old instances registered to the old TargetGroup will be terminated.
This sounds very complicated. Actually, since/if you have enabled auto scaling on your ECS service, a simple way to do it is to just force a new deployment using console or cli, like a gentleman here pointed out:
aws ecs update-service --cluster <cluster name> --service <service name> --force-new-deployment
In this way you can still use the "rolling update" deployment type, and ECS will simply spin up new instances and drain the old ones with no downtime of your service if everything is OK. The bad side is you lose fine control on the deployment and you cannot roll back to previous version if there is an error and this will break the ongoing service. But this is a really simple way to go.
BTW, don't forget to set proper numbers for Minimum healthy percent and Maximum percent, like 100 and 200.