| Plataforma | Tipo | Free Tier | Complexidade | Melhor para |
|---|---|---|---|---|
| Render | PaaS | Sim (dorme após 15min) | Baixa | Projetos pessoais, portfólio |
| Railway | PaaS | Sim ($5/mês de crédito) | Baixa | Projetos pequenos/médios |
| Fly.io | PaaS | Sim (3 VMs pequenas) | Média | Apps globalmente distribuídos |
| AWS Elastic Beanstalk | PaaS sobre IaaS | 12 meses free | Média | Apps corporativos na AWS |
| AWS EC2 | IaaS | 12 meses free (t2.micro) | Alta | Controle total do servidor |
| GCP Cloud Run | Serverless Container | Sim (generoso) | Média | Apps com tráfego variável |
| Heroku | PaaS | Não (pago) | Baixa | Projetos que pagam pelo conforto |
Render é a plataforma mais simples para começar. Suporta deploy direto do GitHub.
- Conta no render.com
- Repositório no GitHub com a aplicação Spring Boot
Dockerfilena raiz do projeto (ou Render detecta automaticamente projetos Maven)
1. Criar o serviço no Render
Dashboard → New + → Web Service → Connect GitHub → Selecionar repositório
2. Configurar o serviço
Name: minha-app
Region: Oregon (US West) ou Frankfurt (Europa)
Branch: main
Runtime: Docker (se tiver Dockerfile) ou Java
Build Command: ./mvnw package -DskipTests
Start Command: java -jar target/minha-app.jar
Instance Type: Free (0.1 CPU, 512 MB RAM)
3. Configurar variáveis de ambiente
No painel do Render, vá em Environment:
SPRING_DATASOURCE_URL=jdbc:postgresql://dpg-xxx.oregon-postgres.render.com/minhadb
SPRING_DATASOURCE_USERNAME=appuser
SPRING_DATASOURCE_PASSWORD=senhaGeradaPeloRender
SPRING_JPA_HIBERNATE_DDL_AUTO=validate
JWT_SECRET=minha-chave-jwt-super-secreta-longa
SPRING_PROFILES_ACTIVE=prod
4. Adicionar banco PostgreSQL no Render
Dashboard → New + → PostgreSQL
Name: minha-app-db
Region: mesma do serviço
Plan: Free (1GB storage, expira em 90 dias no free tier)
Após criar, copie a "Internal Database URL" e use como SPRING_DATASOURCE_URL.
5. application.properties para produção
# src/main/resources/application-prod.yml
spring:
datasource:
url: ${SPRING_DATASOURCE_URL}
username: ${SPRING_DATASOURCE_USERNAME}
password: ${SPRING_DATASOURCE_PASSWORD}
jpa:
hibernate:
ddl-auto: ${SPRING_JPA_HIBERNATE_DDL_AUTO:validate}
show-sql: false
server:
port: ${PORT:8080}
logging:
level:
root: INFO
com.minhaempresa: INFOObservação importante sobre o free tier: a instância "dorme" após 15 minutos sem requisições. A primeira requisição após o sono pode levar 30-60 segundos para responder (cold start da JVM).
Elastic Beanstalk (EB) gerencia automaticamente EC2, Load Balancer, Auto Scaling e deployment, mas você tem mais controle que no Render.
# Instalar AWS CLI
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip && sudo ./aws/install
# Configurar credenciais
aws configure
# AWS Access Key ID: AKIA...
# AWS Secret Access Key: xxx...
# Default region: us-east-1
# Default output format: json
# Instalar EB CLI
pip install awsebcli1. Inicializar o projeto EB
# Na raiz do projeto
eb init
# Responder as perguntas:
# Region: us-east-1
# Application name: minha-app
# Platform: Java 21 running on 64bit Amazon Linux 2023
# SSH: sim (para debug)2. Criar o ambiente de produção
eb create minha-app-prod \
--instance-type t3.micro \
--platform "java-21" \
--region us-east-13. Configurar variáveis de ambiente no EB
eb setenv \
SPRING_DATASOURCE_URL=jdbc:postgresql://xxx.rds.amazonaws.com:5432/minhadb \
SPRING_DATASOURCE_USERNAME=appuser \
SPRING_DATASOURCE_PASSWORD=senhaSegura \
SPRING_PROFILES_ACTIVE=prod \
JWT_SECRET=minha-chave-jwt4. Fazer o deploy
# Empacotar o JAR
./mvnw package -DskipTests
# Deploy do JAR para o EB
eb deploy
# Ver logs
eb logs
# Abrir a aplicação no navegador
eb open
# Status do ambiente
eb status5. Arquivo .elasticbeanstalk/config.yml gerado automaticamente
branch-defaults:
main:
environment: minha-app-prod
group_suffix: null
global:
application_name: minha-app
branch: null
default_ec2_keyname: minha-chave
default_platform: java-21
default_region: us-east-1
repository: null
sc: git6. Arquivo Procfile para o EB saber como iniciar
# Procfile (na raiz do projeto)
web: java -Xms256m -Xmx512m -jar target/minha-app.jar
Boas práticas para gerenciar configurações sensíveis:
Nunca commite valores sensíveis. Use variáveis de ambiente ou serviços de secrets.
// Spring lê variáveis de ambiente automaticamente
// DATABASE_URL → spring.datasource.url (se configurado assim)
// Ou use ${VAR_NAME} no application.yml:
// application.yml
spring:
datasource:
url: ${DATABASE_URL}
username: ${DATABASE_USERNAME}
password: ${DATABASE_PASSWORD}# Verificar variáveis disponíveis em produção (AWS EB)
eb ssh
env | grep SPRING
# Render: visível no painel em Environment
# Railway: visível em VariablesHierarquia de configuração do Spring Boot (maior prioridade primeiro):
- Argumentos da linha de comando (
--server.port=8081) - Variáveis de ambiente do SO (
SERVER_PORT=8081) application-{profile}.yml(ex:application-prod.yml)application.yml- Valores padrão do código (
@Value("${port:8080}"))
GraalVM AOT (Ahead-of-Time) compilation transforma seu JAR em um binário nativo para o SO alvo. O resultado é uma aplicação que:
- Inicia em ~50ms (vs ~3-5s com JVM)
- Usa ~50-100MB de RAM (vs ~200-400MB com JVM)
- Não precisa de JVM instalada no servidor
- Ideal para containers, serverless (Lambda) e microsserviços
<!-- pom.xml: adicionar plugin nativo -->
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
</plugin># Build nativo (requer GraalVM instalado ou Docker)
./mvnw native:compile -Pnative -DskipTests
# Build nativo via Docker (não precisa GraalVM local)
./mvnw spring-boot:build-image -Pnative -DskipTests
# Executar o binário nativo
./target/minha-app| Métrica | JVM (JRE) | Native Image |
|---|---|---|
| Startup | ~3-5s | ~50ms |
| RAM idle | ~200MB | ~50MB |
| Tamanho imagem Docker | ~300MB | ~80MB |
| Throughput máximo | Alto (JIT) | Ligeiramente menor |
| Tempo de build | ~30s | ~5-15min |
| Debug | Fácil | Mais difícil |
Quando usar native:
- Serverless (AWS Lambda, Cloud Run)
- Muitos microsserviços (custo de infra)
- Requisitos de startup rápido
Quando ficar com JVM:
- Aplicações de longa duração e alto throughput
- Debugging e profiling frequentes
- Bibliotecas com reflection extensiva
- Vá em
Settings > Custom Domainsdo seu serviço - Adicione seu domínio (ex:
api.minhaapp.com) - Render fornece o CNAME para configurar no seu DNS
- No seu provedor DNS (Cloudflare, Namecheap, etc.), adicione:
Tipo: CNAME Nome: api Valor: minha-app.onrender.com - SSL/HTTPS é automático (Render usa Let's Encrypt)
# 1. Solicitar certificado SSL no AWS Certificate Manager
aws acm request-certificate \
--domain-name api.minhaapp.com \
--validation-method DNS \
--region us-east-1
# 2. Validar o domínio via DNS (adicionar registro CNAME fornecido pela AWS)
# 3. Adicionar o certificado ao Load Balancer do Elastic Beanstalk
# Painel EB → Configuration → Load Balancer → Listeners → Add (HTTPS:443)
# 4. Criar registro DNS no Route 53 apontando para o EB
aws route53 change-resource-record-sets \
--hosted-zone-id Z1234567890 \
--change-batch file://dns-change.jsonDashboard → Events → Clique no deploy anterior → "Rollback to this deploy"
# Listar versões da aplicação
eb appversion
# Fazer rollback para versão específica
eb deploy --version "versão-anterior"
# Ou pelo console AWS:
# Elastic Beanstalk → Application versions → Selecionar versão → Deploy# Ver histórico de rollouts
kubectl rollout history deployment/minha-app
# Rollback para a versão anterior
kubectl rollout undo deployment/minha-app
# Rollback para uma revisão específica
kubectl rollout undo deployment/minha-app --to-revision=2
# Verificar status após rollback
kubectl rollout status deployment/minha-appMantém duas versões em produção ao mesmo tempo (blue = atual, green = nova), e troca o tráfego instantaneamente:
# Kubernetes: dois deployments, um service que aponta para o ativo
apiVersion: v1
kind: Service
metadata:
name: minha-app-service
spec:
selector:
app: minha-app
version: blue # Mude para "green" para fazer o swap
ports:
- port: 80
targetPort: 8080Para rollback: mude version: green para version: blue no Service — instantâneo, sem downtime.