Primeiro container Docker em produção no Amazon ECS, passo a passo
No fim deste texto, um container Docker que roda na sua máquina passa a rodar no Amazon ECS: imagem no Amazon ECR, cluster com uma instância EC2, task definition e um service que mantém a task de pé. Você derruba a aplicação de propósito para ver o ECS repor tudo sozinho e publica uma versão nova.
A aplicação é bem simples, um Nginx servindo um HTML. Gravei isto em 2022 e o console da AWS mudou desde então: as telas podem estar diferentes, mas a ordem dos passos e os conceitos valem.
O que o ECS faz por você
O Amazon ECS é o serviço de gerenciamento de containers da AWS, o principal dela com essa finalidade. Rodar o container numa EC2 na mão parece mais prático, até você pensar no que envolve manter isso disponível. O ECS automatiza a atualização (quando você conecta esse processo a ele, ele atualiza os containers) e a disponibilidade (você diz quantas tasks quer rodando e ele faz o máximo para manter essa quantidade, subindo outra EC2 para o cluster se precisar).
São quatro peças. O cluster concentra o poder computacional, as instâncias EC2. A task definition descreve o container e diz qual imagem usar. O service, ligado à task definition, lança a task, que é o container rodando. E a imagem precisa estar num registry: poderia ser o Docker Hub, usei o Amazon ECR, o da própria AWS.
1Rodar o container na sua máquina
Você precisa de Git e VS Code, no Windows ou no Linux (eu estava no Linux). O projeto tem uma pasta meu_html com um hello.htm e um Dockerfile só para o Nginx, o Dockerfile-nginx. Ele pega o que está em meu_html e copia para a pasta que o Nginx serve:
FROM nginx
COPY meu_html /usr/share/nginx/html
Gere a imagem passando o Dockerfile com -f, a tag meu-nginx e o diretório atual como contexto:
docker build -f Dockerfile-nginx -t meu-nginx .
Rode o container em modo detached, com a porta local 8081 apontando para a 80 do container, que é a porta padrão do Nginx, e confira se ele subiu:
docker run -d -p 8081:80 meu-nginx
docker ps

Abra localhost:8081/hello.htm no navegador. Na minha apareceu a mensagem "saí da máquina local e fui para o container". O objetivo agora é tirar esse container da máquina e rodar na AWS, gerenciado pelo ECS.
2Subir a imagem para o Amazon ECR
No ECR, crie um repositório com o nome da imagem, meu-nginx. A tela do repositório tem os push commands, os comandos para subir a imagem. Copiei para um arquivo build.sh (no Windows, pode ser build.bat) e fiz uma adaptação: incluir no build o -f com o Dockerfile do Nginx. Com o ID da sua conta no lugar de <id-da-conta>, o script fica assim:
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <id-da-conta>.dkr.ecr.us-east-1.amazonaws.com
docker build -t meu-nginx -f Dockerfile-nginx .
docker tag meu-nginx:latest <id-da-conta>.dkr.ecr.us-east-1.amazonaws.com/meu-nginx:latest
docker push <id-da-conta>.dkr.ecr.us-east-1.amazonaws.com/meu-nginx:latest
A primeira linha pega o login no ECR pelo AWS CLI. A segunda gera a imagem, a terceira aplica a tag com o endereço do repositório e a quarta dá o push.
Antes de rodar, o AWS CLI precisa de uma credencial IAM. Criei um usuário com acesso programático e anexei a policy AmazonEC2ContainerRegistryFullAccess, suficiente para interagir com o ECR. Confira o CLI e configure a credencial:
aws --version
aws configure
No aws configure entram a access key, a secret key e a região (eu estava na Virgínia, us-east-1). O formato de saída pode ficar em branco.
O build.sh nasce sem permissão de execução. Dê a permissão e rode o script:
chmod +x build.sh
./build.sh

O push terminou rápido, e a imagem apareceu no repositório com 56 MB.
3Criar o cluster com uma instância EC2
Crie um cluster com instâncias EC2:
- Instância: t3.micro. Daria para usar a t2.micro, mas a t3 é mais nova.
- Key pair: pode ser qualquer uma, porque não vamos nos conectar na máquina.
- Security group: crie um liberando a porta 80 (HTTP) para todo mundo, já que a aplicação é acessada por ela.
- Rede: a VPC padrão, qualquer subnet e IP público habilitado (na subnet padrão já vem assim).
- IAM role da instância: é o que dá permissão para o agente do ECS falar com a AWS. Crie uma nova ou use uma existente.
Em ECS Instances você vê a instância se registrar no cluster.
4Criar a task definition
Crie uma task definition para EC2, sem task role, porque o container não precisa falar com nenhum serviço da AWS. Na definição do container:
- Nome do container:
meu-nginx. - Imagem: o endereço da imagem no ECR, o mesmo para onde o push mandou.
- Memória: existe o hard limit e o soft limit. Um é quanto você reserva, o outro é o teto antes de o container ser morto por pedir memória demais. Coloquei só um soft limit de 400 MB.
- Porta: local, eu tinha usado 8081. Aqui ficou a 80 dos dois lados, que é mais fácil de expor.
5Criar o service que lança a task
O service é o responsável por lançar a task:
- Cluster: o que você acabou de criar. Launch type: EC2.
- Service type: réplica. Quem está começando não precisa se preocupar com o modo daemon.
- Número de tasks: 1.
- Minimum healthy percent 0 e maximum percent 100: esses valores dizem quanto do serviço fica disponível durante um deploy. Com 0, o ECS pode derrubar a task antiga antes de lançar a nova. Usei assim porque não há load balancer nem outros elementos envolvidos.
- Task placement, load balancer e auto scaling: não mexi.
A task passa de pendente para running. No detalhe dela aparece o link externo. Chame hello.htm nesse endereço e a aplicação está no ar.

6Derrubar de propósito
Esse modelo serve para produção porque o ECS gerencia a disponibilidade. Faça dois testes:
- Pare a task. A aplicação cai, claro. Em pouco tempo o ECS percebe que não há nenhuma task rodando, quando o requisito era pelo menos uma, e lança outra.
- Termine a instância EC2. O serviço cai de novo. Como há serviços por baixo do ECS cuidando disso, o Auto Scaling entre eles, ele sobe outra instância, ela entra no cluster e o service lança a task de novo. Isso leva uns 3 minutos, porque ele precisa lançar outra EC2. A aplicação volta com outro IP.
7Publicar uma versão nova
Enquanto a instância nova subia, mudei o HTML para "v3" e rodei o build.sh de novo. Como a máquina era nova e baixou a imagem, já apareceu a v3.
Depois fiz a v4 com a instância já de pé. Subi a imagem, e a aplicação continuou na v3: ela só muda quando você faz um novo deployment. No service, use update e marque para forçar um novo deployment.
Com a regra 0 e 100, o ECS tira a task antiga do ar e lança a nova. Foi rápido, e a v4 apareceu.

No fim, delete o cluster. A instância EC2 aparece como terminada.
Checklist
- Container rodando local e conferido no navegador.
- Repositório no Amazon ECR e os push commands num
build.sh, com o-fdo Dockerfile. - AWS CLI com um usuário IAM só com a permissão do ECR, chaves bem guardadas.
- Cluster com EC2, security group liberando a porta 80 e IP público.
- Task definition apontando para a imagem do ECR, com limite de memória e a porta 80 mapeada.
- Service em modo réplica, com 1 task.
- Task parada e EC2 terminada, e o ECS repondo as duas.
- Versão nova com a mesma tag publicada forçando um novo deployment.
- Cluster deletado no fim do teste.
Isto é o básico: uma task, sem load balancer e com deploy manual. Depois que você vê o ECS repor uma máquina sozinho, gerenciar container na mão deixa de fazer sentido.
Formação AWS
Aprenda AWS e IA na prática, com projeto real e acompanhamento. Converse com o time sobre a Formação AWS.
Agende uma conversaPrefere assistir?
A aula completa (39 min) está no canal Domine AWS. O vídeo toca aqui mesmo.