Uma aplicação de estudo construída com foco em aprender os fundamentos de Clean Architecture, DDD, Docker, Nginx (reverse proxy), SSL/HTTPS com Let's Encrypt e práticas modernas com Node.js + TypeScript.
src/
├── application/ # Casos de uso e DTOs
│ ├── dtos/ # Objetos de Transferência de Dados (entrada/saída)
│ └── use-cases/ # Implementações dos casos de uso
│
├── common/ # Código utilitário e erros genéricos
│ └── errors/ # Erros de aplicação personalizados
│
├── contracts/ # Interfaces e contratos para abstrações
│
├── domain/ # Camada de domínio (entidades e interfaces)
│ ├── entities/ # Entidades do domínio (ex: Task)
│ ├── repositories/ # Contratos dos repositórios
│ └── usecases/ # Interfaces dos casos de uso
│
├── infrastructure/ # Detalhes de implementação externa
│ ├── database/mongo/ # Implementação de repositórios com MongoDB
│ └── http/ # Camada de entrega (Express, middlewares, presenters)
│
└── main/ # Entry point e injeção de dependência
├── factory/ # Montagem de casos de uso com dependências
└── express-server.ts # Inicialização do servidor ExpressEsta API RESTful permite criar, listar, buscar e deletar tarefas. Todas as rotas estão sob o prefixo /v1/tasks.
-
GET
/v1/healthVerifica se a API está online.Resposta:
{ "status": "ok" }
-
POST
/v1/tasksCria uma nova tarefa.Body:
{ "title": "Minha nova tarefa", "completed": false }Resposta (201):
{ "message": "Task created successfully", "task": { "title": "Minha nova tarefa", "completed": false } }
-
GET
/v1/tasksRetorna todas as tarefas cadastradas.Resposta (200):
[ { "id": "uuid-da-tarefa", "title": "Minha nova tarefa", "completed": false } // ... ]
-
GET
/v1/tasks/:idRetorna uma tarefa específica pelo ID.Resposta (200):
{ "id": "uuid-da-tarefa", "title": "Minha nova tarefa", "completed": false }Erro (404):
{ "error": "Task with id \"...\" not found" }
-
DELETE
/v1/tasks/:idRemove uma tarefa pelo ID.Resposta (200):
{ "message": "Task deleted successfully" }Erro (404):
{ "error": "Task not found" }
- 400 Bad Request: Dados inválidos (ex: título muito curto)
- 404 Not Found: Tarefa não encontrada
# Criar tarefa
curl -X POST https://seudominio.com/v1/tasks -H "Content-Type: application/json" -d '{"title":"Estudar Clean Architecture"}'
# Listar tarefas
curl https://seudominio.com/v1/tasks
# Buscar tarefa por ID
curl https://seudominio.com/v1/tasks/<id>
# Deletar tarefa por ID
curl -X DELETE https://seudominio.com/v1/tasks/<id>Todas as respostas são em JSON. Para dúvidas ou sugestões, consulte o código ou entre em contato!
# Build da aplicação
docker-compose build
# Subir os containers
docker-compose upA aplicação estará disponível em: http://localhost
Para testar a saúde da API:
curl http://localhost/v1/health
- AWS EC2: Crie uma instância
Ubuntu 24.04 LTS(t2.micro para free tier). - Oracle Cloud: Crie uma VM
VM.Standard.E2.1.Micro(free tier) com Ubuntu 24.04 LTS.
- Porta 22 (SSH): Libere apenas para o seu IP.
- Portas 80 e 443: Libere para 0.0.0.0/0 (acesso público).
- No Ubuntu: Não obrigatório para teste | Cuidado bloquear o acesso a maquina pela porta 22
sudo ufw allow 22 sudo ufw allow 80 sudo ufw allow 443 sudo ufw enable
sudo apt update
sudo apt upgrade -y
sudo apt install docker.io -y
sudo apt install docker-compose -y
sudo usermod -aG docker $USER
newgrp dockerNo seu computador local:
scp -i "sua-chave.key" -r docker-compose.yml Dockerfile package.json package-lock.json tsconfig.json nginx src ubuntu@<ip-da-vm>:/home/ubuntu/todoapp/- Adquira um domínio (Hostinger, GoDaddy, etc).
- Configure o DNS:
Tipo: A Nome: @ Valor: IP_PUBLICO_DA_VM TTL: 3600 Tipo: CNAME Nome: www Valor: seudominio.com TTL: 3600 - Aguarde a propagação DNS (pode levar até 24h).
-
Crie a pasta de validação no host:
sudo mkdir -p /var/www/certbot sudo chown 1000:1000 /var/www/certbot
-
Ajuste temporário no nginx.conf:
- Remova ou comente o bloco HTTPS (porta 443)
- Remova o redirecionamento de HTTP para HTTPS
- Deixe apenas o bloco:
server { listen 80; server_name seudominio.com www.seudominio.com; location /.well-known/acme-challenge/ { root /var/www/certbot; try_files $uri =404; } location / { return 200 'ok'; add_header Content-Type text/plain; } }
-
Reinicie o nginx:
docker-compose down docker-compose up -d
-
Teste o acesso externo: | Não obrigatório
curl http://seudominio.com/.well-known/acme-challenge/teste.txt
-
Emita o certificado:
docker-compose run --rm certbot certonly --webroot \ --webroot-path=/var/www/certbot \ --email seu-email@exemplo.com \ --agree-tos --no-eff-email \ -d seudominio.com -d www.seudominio.com
-
Volte o nginx.conf para a configuração com HTTPS e redirecionamento:
- Reative o bloco HTTPS (porta 443)
- Reative o redirecionamento HTTP → HTTPS
-
Reinicie o nginx novamente:
docker-compose down docker-compose up -d
-
Acesse sua aplicação em: https://seudominio.com
Crie um script de renovação:
cat > renew-ssl.sh << 'EOF'
#!/bin/bash
cd /home/ubuntu/todoapp
docker-compose run --rm certbot renew --quiet
if [ $? -eq 0 ]; then
docker-compose exec nginx nginx -s reload
fi
EOF
chmod +x renew-ssl.shAdicione ao cron:
sudo crontab -e
# Adicione:
0 2 * * * /home/ubuntu/todoapp/renew-ssl.sh >> /var/log/ssl-renewal.log 2>&1- TLS 1.2/1.3: Protocolos modernos de criptografia
- HSTS: Força conexões HTTPS no navegador
- HTTP/2: Protocolo mais eficiente
- Certificado válido por 90 dias com renovação automática
- Redirecionamento automático HTTP → HTTPS
- Nginx é usado para rotear as requisições externas para o container da API.
- Ele recebe requisições HTTP/HTTPS e as repassa para o serviço
apina porta 3000. - Atua como terminador SSL, descriptografando HTTPS antes de enviar para a API.
É um servidor que intercepta requisições feitas ao backend e as encaminha internamente. Ele resolve problemas como:
- Balanceamento de carga
- Encapsulamento do backend
- Cache, compressão e HTTPS
- Terminação SSL/TLS
O projeto implementa diversas práticas recomendadas de segurança no proxy reverso Nginx, visando proteger a aplicação contra ataques comuns e garantir maior robustez em ambientes de produção ou estudo que é o caso desta aplicação.
-
Limitação de requisições por IP: Utiliza o módulo
limit_reqpara restringir cada IP a no máximo 10 requisições por minuto, mitigando ataques de força bruta e DoS leves.limit_req_zone $binary_remote_addr zone=one:10m rate=10r/m; limit_req zone=one burst=5 nodelay;
-
Cabeçalhos de segurança HTTP: Adiciona cabeçalhos para proteção contra XSS, clickjacking e outros ataques.
add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; add_header X-XSS-Protection "1; mode=block"; add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; img-src 'self' data:;"; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
-
Limite de tamanho de upload: Restringe o tamanho máximo do corpo da requisição para evitar abusos e ataques de upload.
client_max_body_size 10m;
-
Timeouts de conexão: Define timeouts para evitar conexões lentas ou maliciosas.
client_body_timeout 12s; client_header_timeout 12s; keepalive_timeout 15s; send_timeout 10s;
-
Proteção contra buffer overflow: Ajusta buffers para evitar ataques de cabeçalho muito grande.
client_header_buffer_size 1k; large_client_header_buffers 4 4k;
-
Bloqueio de user agents maliciosos: Bloqueia requisições de ferramentas conhecidas por automação de ataques.
if ($http_user_agent ~* (sqlmap|wpscan|nikto|wget) ) { return 403; }
-
Configurações SSL/TLS modernas: Implementa protocolos e cifras seguras para HTTPS.
ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off;
- ✅ Clean Architecture
- ✅ Domain-Driven Design (DDD)
- ✅ Inversão de Dependência
- ✅ Express com Adapter Controller
- ✅ MongoDB com repositórios desacoplados
- ✅ DTOs e Presenters
- ✅ Docker e Docker Compose
- ✅ Nginx como proxy reverso com práticas de segurança
- ✅ SSL/TLS com Let's Encrypt
- ✅ Renovação automática de certificados
- ✅ AWS EC2
- ✅ Oracle Cloud
- ✅ Firewall (UFW)
- ✅ DNS e domínios personalizados
Esta aplicação é apenas para fins de estudo e aprendizado. Não deve ser usada em produção sem antes aplicar medidas de segurança e validação adequadas.
Se você quiser trocar ideias, colaborar ou apenas bater um papo sobre arquitetura de software, Docker, Clean Architecture ou qualquer outra coisa nerd — me chama no LinkedIn:
Feito com 💙 por um estudante de Engenharia de Software.