Do localhost:8080 a um endpoint público#

O ponto de partida é comum: um serviço backend HTTP que funciona na sua máquina, por exemplo uma API em Go que escuta na porta 8080. O objetivo é expô-lo na internet com um domínio, várias instâncias e deploys repetíveis a partir de uma branch, uma tag ou um commit.

Qualquer plataforma de deploy pede os mesmos dados: o repositório, a linguagem ou como construir a imagem, se o acesso é público ou privado, um prefixo de rota, a rota do health check, CPU e memória, número mínimo e máximo de instâncias e quando escalar. Neste guia, resolvemos tudo diretamente com serviços da AWS: Amazon ECR para a imagem, Amazon ECS com AWS Fargate para executá-la e um Application Load Balancer (ALB) na frente.

O requisito do código: um health check#

O único requisito do código é um endpoint que responda 200 quando o processo consegue atender requisições. O load balancer o consulta periodicamente e para de enviar tráfego para as instâncias que falham. Este exemplo usa apenas a biblioteca padrão do Go:

go
// main.go (Go 1.22+: padrões com método no ServeMux)
package main

import (
	"log"
	"net/http"
)

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("GET /api/demo/health-check", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("ok")) // 200 por padrão
	})
	mux.HandleFunc("GET /api/demo/hello-world", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("hello world"))
	})
	log.Fatal(http.ListenAndServe(":8080", mux))
}
Serviço mínimo com duas rotas. Os padrões "GET /rota" exigem Go 1.22 ou posterior.

Mantenha o health check barato. Ele pode verificar dependências críticas, mas, se verificar tudo, a queda de um serviço secundário vai tirar todas as suas instâncias de rotação ao mesmo tempo.

Para se aprofundar: O que é um load balancer: o que ele resolve e o que não resolve

Documentação: Go · net/http ↗ · Go · Melhorias de routing no 1.22 ↗

Onde executar na AWS#

OpçãoO que você gerenciaQuando escolher
ECS com Fargate + ALBTask definition, serviço, target group, escalonamentoControle total sem administrar servidores; a opção detalhada neste guia
ECS Express ModeImagem e duas roles do IAM; a AWS cria o serviço, o ALB com TLS e o escalonamentoVocê quer padrões razoáveis e começar rápido
AWS App RunnerImagem ou códigoSó se você já é cliente: a AWS o fechou para novos clientes e recomenda migrar para o ECS Express Mode

O ECS Express Mode cria um serviço do ECS com Fargate com URL própria, load balancer com SSL/TLS, políticas de auto scaling e monitoramento, e todos os recursos ficam na sua conta para você ajustar depois. Se você precisa de cada peça sob seu controle desde o início, siga com a abordagem manual.

Para se aprofundar: Deploy rápido sem montar EC2, VPC nem IAM: guia de PaaS

Documentação: AWS Fargate ↗ · Amazon ECS · Express Mode ↗ · AWS App Runner · Mudança de disponibilidade ↗

Construir a imagem e enviá-la ao ECR#

Um build multi-stage compila em uma imagem com o toolchain e copia apenas o binário para uma imagem final mínima, que além disso roda como usuário sem privilégios:

dockerfile
# Dockerfile
FROM golang:1.25 AS build
WORKDIR /src
COPY go.mod ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /server .

FROM gcr.io/distroless/static-debian13:nonroot
COPY --from=build /server /server
EXPOSE 8080
ENTRYPOINT ["/server"]
A tag nonroot do distroless executa o processo como usuário sem privilégios. Faça o build para a arquitetura declarada na task definition (aqui, ARM64).

Construa a imagem no seu CI para a plataforma correta (linux/arm64 ou linux/amd64) e envie-a para um repositório do Amazon ECR com uma tag imutável, como a versão ou o SHA do commit. Evite fazer deploy da tag latest: você não vai saber qual versão está rodando.

Para se aprofundar: Dockerfile: deploys consistentes em qualquer nuvem

Documentação: Docker · Builds multi-stage ↗ · Docker · Builds multiplataforma ↗ · distroless ↗ · Amazon ECR · Enviar uma imagem ↗

A task definition#

A task definition descreve como executar o container: imagem, CPU e memória, porta e logs. No Fargate, 256 unidades de CPU (0,25 vCPU) aceitam 512 MiB, 1 GB ou 2 GB de memória; 1024 unidades equivalem a 1 vCPU.

json
{
  "family": "demo-api",
  "requiresCompatibilities": ["FARGATE"],
  "networkMode": "awsvpc",
  "cpu": "256",
  "memory": "512",
  "runtimePlatform": { "operatingSystemFamily": "LINUX", "cpuArchitecture": "ARM64" },
  "executionRoleArn": "arn:aws:iam::111122223333:role/ecsTaskExecutionRole",
  "containerDefinitions": [
    {
      "name": "api",
      "image": "111122223333.dkr.ecr.us-east-1.amazonaws.com/demo-api:1.0.0",
      "essential": true,
      "portMappings": [{ "containerPort": 8080, "protocol": "tcp" }],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/demo-api",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "api"
        }
      }
    }
  ]
}
Exemplo ilustrativo. A execution role permite ao ECS baixar a imagem do ECR e gravar logs; se o seu código chama outros serviços da AWS, adicione também uma task role só com essas permissões.

As variáveis de ambiente vão na task definition; os secrets, como referências ao Secrets Manager ou ao Parameter Store, para que não fiquem em texto puro.

Documentação: Amazon ECS · Parâmetros da task definition ↗ · Amazon ECS · Fargate ↗ · Amazon ECS · Logs com awslogs ↗ · Amazon ECS · Execution role ↗ · Amazon ECS · Dados sensíveis ↗

Serviço, ALB e health checks#

Com Fargate, as tasks usam o modo de rede awsvpc, então o target group do ALB precisa ser do tipo ip, não instance. Configure o health check com a rota /api/demo/health-check e o código 200. Por padrão, o ALB marca um target como saudável após 5 verificações bem-sucedidas e como não saudável após 2 falhas.

Coloque o ALB em sub-redes públicas e as tasks em sub-redes privadas. Se o serviço só deve ser acessível por outros serviços internos, use um ALB interno: é o equivalente a escolher acesso privado em uma plataforma de deploy. O prefixo de rota é implementado com regras de listener por path.

bash
aws ecs create-service \
  --cluster demo \
  --service-name demo-api \
  --task-definition demo-api \
  --desired-count 2 \
  --launch-type FARGATE \
  --network-configuration 'awsvpcConfiguration={subnets=[subnet-private-a,subnet-private-b],securityGroups=[sg-api],assignPublicIp=DISABLED}' \
  --load-balancers targetGroupArn=arn:aws:elasticloadbalancing:us-east-1:111122223333:targetgroup/demo-api/0123456789abcdef,containerName=api,containerPort=8080 \
  --health-check-grace-period-seconds 30 \
  --deployment-configuration 'deploymentCircuitBreaker={enable=true,rollback=true}'
Cria o serviço com duas tasks em sub-redes privadas, registradas no target group. Os IDs de sub-rede, security group e target group são de exemplo.

healthCheckGracePeriodSeconds indica por quanto tempo, depois que uma task sobe, o ECS ignora health checks com falha; aumente o valor se o seu serviço demora para iniciar. O deployment circuit breaker detecta deploys que não chegam a um estado estável e, com rollback ativado, volta para a última versão concluída.

Documentação: Amazon ECS · ALB e target type ip ↗ · ELB · Health checks ↗ · Amazon ECS · Parâmetros de serviço ↗ · AWS CLI · ecs create-service ↗ · Amazon ECS · Circuit breaker ↗ · Amazon VPC · Sub-redes ↗

Escalonamento e custo#

  • Target tracking: defina um valor-alvo, por exemplo 60 % de CPU média do serviço, e o Application Auto Scaling adiciona ou remove tasks entre o seu mínimo e o seu máximo.
  • Fargate Spot: executa tasks tolerantes a interrupções com desconto; a AWS pode recuperá-las com um aviso de dois minutos. Combine com capacidade Fargate normal para manter um mínimo estável.
  • Mantenha pelo menos duas tasks em zonas de disponibilidade diferentes para que uma falha de zona não deixe você sem serviço.

Documentação: Amazon ECS · Target tracking ↗ · Amazon ECS · Fargate Spot ↗

Verificar e diagnosticar#

Quando o serviço estiver estável, chame os mesmos endpoints que você usava localmente, agora pelo domínio do ALB. Se os targets não ficarem healthy, verifique nesta ordem: se o container escuta na porta declarada, se a rota do health check está exata, se o security group das tasks aceita tráfego do ALB nessa porta, se o grace period dá tempo para a inicialização e se os logs no CloudWatch não mostram erros de configuração.

Fontes e escopo

Documentação consultada em 25 de setembro de 2026. Os exemplos e critérios de decisão são propostas editoriais; adapte-os ao contrato da sua aplicação e valide-os no seu ambiente de testes autorizado.

Do design à decisão

Compare opções de nuvem

Confira preços, limites, condições e fontes de cada opção.

Abrir comparador