O AWS Elastic Beanstalk disponibiliza uma plataforma gerida para implementar aplicações web sem gerir a infraestrutura subjacente. Trata do aprovisionamento de capacidade, balanceamento de carga, auto-scaling e monitorização da saúde da aplicação. Este guia aborda a implementação de aplicações em contentores no Elastic Beanstalk na perspetiva de um programador sénior.
Porquê o Elastic Beanstalk
O Elastic Beanstalk oferece várias vantagens:
- Infraestrutura Gerida: A AWS trata dos servidores, balanceadores de carga e escalabilidade
- Suporte para Docker: Implemente contentores sem a complexidade do Kubernetes
- Reversões Fáceis: Reversão com um clique para versões anteriores
- Monitorização Integrada: Métricas do CloudWatch prontas a usar
- Custo-Eficiente: Pague apenas pelos recursos AWS subjacentes
Configuração Inicial
Criar Aplicação Elastic Beanstalk
- Aceda à AWS Management Console
- Procure por «Elastic Beanstalk» em Find Services
- Clique em «Create Application»
- Introduza o nome da aplicação (por exemplo, «my-docker-app»)
- Selecione «Docker» como plataforma
- Escolha «Docker running on 64bit Amazon Linux 2»
- Clique em «Create Application»
Aguarde pela criação do ambiente (um visto verde indica sucesso).
Configurar o Tipo de Instância
A instância t2.micro predefinida muitas vezes expira durante os builds. Atualize para t2.small:
- Na barra lateral esquerda, clique em «Configuration»
- Encontre «Capacity» e clique em «Edit»
- Altere «Instance Type» de t2.micro para t2.small
- Clique em «Apply»
Nota: a t2.small está fora do free tier, mas evita falhas de build.
Configuração do Docker
Implementação de Contentor Único
Crie Dockerfile na raiz do seu projeto:
# Fase de build
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
# Fase de produção
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Multi-Contentor com Docker Compose
Crie docker-compose.yml para o Elastic Beanstalk:
version: '3.8'
services:
nginx:
build:
context: ./nginx
dockerfile: Dockerfile
ports:
- "80:80"
depends_on:
- api
- frontend
api:
build:
context: ./api
dockerfile: Dockerfile
environment:
- NODE_ENV=production
- DATABASE_URL=${DATABASE_URL}
- REDIS_HOST=redis
depends_on:
- redis
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
environment:
- API_URL=http://api:5000
redis:
image: redis:alpine
worker:
build:
context: ./worker
dockerfile: Dockerfile
environment:
- REDIS_HOST=redis
Crie nginx/default.conf:
upstream frontend {
server frontend:3000;
}
upstream api {
server api:5000;
}
server {
listen 80;
location / {
proxy_pass http://frontend;
}
location /sockjs-node {
proxy_pass http://frontend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location /api {
rewrite /api/(.*) /$1 break;
proxy_pass http://api;
}
}
CI/CD com Travis CI
Configuração de Utilizador IAM
Crie credenciais de implementação:
- Procure por «IAM» na AWS Console
- Clique em «Users» → «Add User»
- Introduza o nome de utilizador: «eb-deploy-user»
- Selecione «Programmatic Access»
- Clique em «Attach Existing Policies Directly»
- Procure e selecione «AWSElasticBeanstalkFullAccess»
- Conclua a criação e guarde o Access Key ID e o Secret
Configuração do Travis
Adicione as credenciais AWS ao Travis:
- Aceda ao seu Travis Dashboard
- Clique no repositório → «More Options» → «Settings»
- Adicione variáveis de ambiente:
- AWSACCESSKEY: A sua access key do IAM - AWSSECRETKEY: A sua secret key do IAM
Crie .travis.yml:
language: generic
services:
- docker
before_install:
- docker build -t my-app-test -f Dockerfile.dev .
script:
- docker run -e CI=true my-app-test npm test -- --coverage
deploy:
provider: elasticbeanstalk
region: us-east-1
app: my-docker-app
env: my-docker-app-env
bucket_name: elasticbeanstalk-us-east-1-123456789012
bucket_path: my-docker-app
on:
branch: main
access_key_id: $AWS_ACCESS_KEY
secret_access_key: $AWS_SECRET_KEY
Encontre o nome do seu bucket:
- Aceda ao S3 na AWS Console
- Procure o bucket que começa por «elasticbeanstalk-» e corresponde à sua região
- Copie o nome completo do bucket
Configuração de Base de Dados com RDS
Criar Instância RDS
- Procure por «RDS» na AWS Console
- Clique em «Create Database»
- Selecione «PostgreSQL» (ou MySQL)
- Escolha o template «Free tier» para testes
- Configure:
- DB instance identifier: my-app-db - Master username: admin - Master password: (palavra-passe segura) 6. Em «Connectivity»: - Escolha a sua VPC - Crie um novo security group: my-app-db-sg 7. Clique em «Create Database»
Configurar Security Groups
Permita que o Elastic Beanstalk aceda ao RDS:
- Aceda a EC2 → Security Groups
- Encontre o security group do seu RDS
- Edite as regras de entrada
- Adicione a regra:
- Type: PostgreSQL (port 5432) - Source: Security group do seu ambiente EB 5. Guarde as regras
Definir Variáveis de Ambiente
- Aceda a Elastic Beanstalk → Configuration
- Encontre «Software» e clique em «Edit»
- Em «Environment properties», adicione:
- DATABASEURL: postgres://admin:password@hostname:5432/myapp - RAILSENV: production - SECRETKEYBASE: (gerar com rails secret) 4. Clique em «Apply»
Redis com ElastiCache
Criar Cluster Redis
- Procure por «ElastiCache» na AWS Console
- Clique em «Create» em Redis
- Configure:
- Name: my-app-redis - Node type: cache.t3.micro - Number of replicas: 0 (para desenvolvimento) 4. Selecione a sua VPC e o subnet group 5. Crie um novo security group 6. Clique em «Create»
Configurar Segurança
- Edite o security group do ElastiCache
- Adicione regra de entrada:
- Type: Custom TCP (port 6379) - Source: Security group do ambiente EB 3. Adicione a variável de ambiente no EB: - REDIS_HOST: (endpoint do ElastiCache sem a porta)
Health Checks e Monitorização
Configurar Health Check
Crie .ebextensions/healthcheck.config:
option_settings:
aws:elasticbeanstalk:application:
Application Healthcheck URL: /health
aws:elasticbeanstalk:environment:process:default:
HealthCheckPath: /health
HealthCheckInterval: 30
HealthCheckTimeout: 5
HealthyThresholdCount: 3
UnhealthyThresholdCount: 5
Implemente o endpoint de saúde na sua aplicação:
// Exemplo de Express.js
app.get('/health', (req, res) => {
// Verificar a ligação à base de dados
db.query('SELECT 1')
.then(() => {
res.status(200).json({ status: 'healthy' });
})
.catch(() => {
res.status(503).json({ status: 'unhealthy' });
});
});
Alarmes do CloudWatch
Crie .ebextensions/cloudwatch.config:
Resources:
CPUAlarmHigh:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmDescription: "CPU > 80% for 5 minutes"
MetricName: CPUUtilization
Namespace: AWS/EC2
Statistic: Average
Period: 300
EvaluationPeriods: 1
Threshold: 80
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref NotificationTopic
NotificationTopic:
Type: AWS::SNS::Topic
Properties:
Subscription:
- Endpoint: [email protected]
Protocol: email
Configuração de Auto Scaling
Crie .ebextensions/autoscaling.config:
option_settings:
aws:autoscaling:asg:
MinSize: 2
MaxSize: 10
aws:autoscaling:trigger:
MeasureName: CPUUtilization
Statistic: Average
Unit: Percent
LowerThreshold: 30
UpperThreshold: 70
LowerBreachScaleIncrement: -1
UpperBreachScaleIncrement: 1
aws:elasticbeanstalk:environment:
LoadBalancerType: application
Configuração de HTTPS
Pedir Certificado SSL
- Aceda ao AWS Certificate Manager (ACM)
- Clique em «Request Certificate»
- Introduza o domínio: *.example.com
- Valide via DNS ou email
- Aguarde que o certificado seja emitido
Configurar HTTPS
Crie .ebextensions/https.config:
option_settings:
aws:elb:listener:443:
ListenerProtocol: HTTPS
InstanceProtocol: HTTP
InstancePort: 80
SSLCertificateId: arn:aws:acm:region:account:certificate/id
aws:elb:listener:80:
ListenerEnabled: false
Boas Práticas de Implementação
Implementações Blue-Green
Para implementações sem downtime:
- Crie um novo ambiente (clone do existente)
- Implemente a nova versão no novo ambiente
- Teste exaustivamente
- Troque os URLs dos ambientes na consola do EB
- Termine o ambiente antigo após verificação
Rolling Updates
Configure em .ebextensions/deployment.config:
option_settings:
aws:elasticbeanstalk:command:
DeploymentPolicy: Rolling
BatchSizeType: Percentage
BatchSize: 25
Resolução de Problemas
Ver Logs
# A utilizar o EB CLI
eb logs
# Ou na AWS Console:
# Elastic Beanstalk → Logs → Request Logs
Problemas Comuns
Build timeout: Aumente o tamanho da instância para t2.small ou superior
O contentor não arranca: Verifique os logs do Docker:
eb ssh
docker logs $(docker ps -q)
Ligação à base de dados recusada: Verifique se as regras do security group permitem tráfego do EB para o RDS
502 Bad Gateway: A aplicação falhou ou não está a escutar na porta correta
Principais Conclusões
- Use Docker: Coloque em contentores para implementações consistentes
- Separe responsabilidades: Base de dados e cache em serviços geridos
- Os security groups são importantes: Configure cuidadosamente para a comunicação entre serviços
- Variáveis de ambiente: Nunca codifique credenciais diretamente
- Monitorize ativamente: Configure alarmes do CloudWatch desde o primeiro dia
- Planeie a escalabilidade: Configure o auto-scaling antes de precisar dele
O Elastic Beanstalk oferece um excelente equilíbrio entre abstração de infraestrutura e controlo, tornando-o ideal para equipas que pretendem implementações geridas sem toda a complexidade do Kubernetes.