Arquiteturas escaláveis exigem o isolamento de componentes. No Locaweb Cloud (IaaS via Apache CloudStack), você detém o poder de orquestração de rede e sistema operacional, sem automações de PaaS que alterem configurações sem consentimento.
Você aprenderá a proteger o banco de dados criando uma VPC com duas sub-redes (Tiers): uma pública para a aplicação Spring Boot e outra estritamente privada para o PostgreSQL, inacessível via internet.
Pré-requisitos
Para acompanhar este guia, você deve garantir que seu ambiente atende às seguintes condições:
- Conta ativa no Locaweb Cloud com permissões administrativas para acesso ao painel de controle CloudStack.
- Chave privada SSH (.key ou .pem) gerada no painel e salva localmente em sua máquina de trabalho com as permissões corretas.
- [Importante!] Aplique chmod 400 sua_chave.key para que apenas o seu usuário possa lê-la — caso contrário o cliente SSH recusa a conexão por segurança.
- Planejamento de rede: Planeje a janela de manutenção reservando o bloco de IP correto. Parâmetros sugeridos:
- Rede Virtual (VPC): 192.168.0.0/16
- Subrede Pública (Web): 192.168.1.0/24
- Subrede Privada (Database): 192.168.2.0/24
- Dados de acesso e repositório Git devidamente estruturados para o deploy.
- Um domínio próprio apontando para o IP público da VPC, necessário para a emissão de certificado HTTPS gratuito com Let’s Encrypt.
Configuração de infraestrutura (painel CloudStack)
A topologia de rede é o alicerce da segurança. O isolamento será garantido através de Network ACLs (Listas de Controle de Acesso) processadas diretamente no Roteador Virtual do Locaweb Cloud.
Passo 1: Criação da VPC e das Tiers
- No painel do Locaweb Cloud, navegue até o menu Rede e clique em VPC.
- Clique em Adicionar VPC.
- Preencha os campos essenciais:
- Nome: VPC-Producao-App
- CIDR da VPC: 10.0.0.0/16
- Oferta de VPC: selecione a oferta adequada ao throughput desejado.
- Após a VPC ser provisionada, clique sobre o nome dela e acesse a aba Redes.
- Clique em Adicionar novo tier na rede e crie a primeira sub-rede (Tier Web):
- Nome: Tier-Publica-Web
- Gateway/CIDR da tier: 10.0.1.1/24
- ACL: selecione default_allow temporariamente (será substituída no Passo 2).
- Repita a operação para criar a segunda sub-rede (Tier DB):
- Nome: Tier-Privada-DB
- Gateway/CIDR da tier: 10.0.2.1/24
- ACL: selecione default_deny temporariamente (será substituída no Passo 2).
Ao final deste passo, você terá duas Tiers criadas dentro da mesma VPC: uma destinada à aplicação Web (com acesso externo) e outra ao banco de dados (totalmente isolada).
Passo 2: Configuração das Network ACLs
A ACL garante proteção no nível da sub-rede, independentemente do firewall (iptables/ufw) configurado dentro do sistema operacional. É aqui que o isolamento do banco de dados é efetivamente aplicado.
- Ainda nos detalhes da sua VPC, acesse a aba Listas de ACL de rede.
- Clique em Adicionar lista de ACL de rede e crie a lista ACL-Tier-Web. Em seguida, abra a lista e adicione as seguintes regras (botão Adicionar ACL):
| Regra | Direção | CIDR | Protocolo | Porta | Ação | Finalidade |
| 10 | Entrada (Ingress) | 0.0.0.0/0 | TCP | 8080 | Permitir | Acesso à API Spring Boot |
| 20 | Entrada (Ingress) | 0.0.0.0/0 | TCP | 22 | Permitir | Acesso SSH administrativo |
| 30 | Entrada (Ingress) | 0.0.0.0/0 | TCP | 80 | Permitir | HTTP (validação Let’s Encrypt) |
| 40 | Entrada (Ingress) | 0.0.0.0/0 | TCP | 443 | Permitir | HTTPS seguro |
| 100 | Saída (Egress) | 0.0.0.0/0 | ALL | — | Permitir | Tráfego de saída geral da sub-rede |
- Crie a lista ACL-Tier-DB. Abra a lista e adicione as seguintes regras estritas — observe que nenhuma origem pública externa é permitida:
| Regra | Direção | CIDR | Protocolo | Porta | Ação | Finalidade |
| 10 | Entrada (Ingress) | 10.0.1.0/24 | TCP | 5432 | Permitir | PostgreSQL, apenas a partir da Tier Web |
| 20 | Entrada (Ingress) | 10.0.1.0/24 | TCP | 22 | Permitir | SSH vindo da VM Web (Bastion Host) |
| 100 | Saída (Egress) | 0.0.0.0/0 | ALL | — | Permitir | Permite baixar atualizações de segurança |
O ponto crítico aqui: a porta 5432 (PostgreSQL) só aceita conexões originadas do bloco 10.0.1.0/24 (a Tier Web). Qualquer pacote vindo da internet pública é descartado pelo Roteador Virtual antes mesmo de chegar à VM do banco.
- Vá até a aba Redes da sua VPC, selecione a Tier-Publica-Web, clique em Substituir lista de ACL e selecione ACL-Tier-Web. Faça o mesmo para a Tier-Privada-DB, associando-a à ACL-Tier-DB.
Passo 3: Provisionamento das VMs
- No menu Computação > VMs, clique em Adicionar VM.
- Crie a VM Web (VM-SpringBoot):
- Template: Ubuntu 22.04 LTS.
- Rede: na etapa de Redes, selecione a Tier-Publica-Web dentro da VPC-Producao-App.
- Chave SSH: selecione sua chave configurada.
- Crie a VM Banco de Dados (VM-Postgres):
- Template: Ubuntu 22.04 LTS.
- Rede: na etapa de Redes, selecione a Tier-Privada-DB.
- Chave SSH: selecione a mesma chave.
Passo 4: Configuração de Acesso Externo (Port Forwarding + Firewall)
- Vá em Rede > VPC > VPC-Producao-App > IPs Públicos. Clique em Obter um novo IP.
- No IP recém-adquirido, acesse a aba Encaminhamento de porta (Port Forwarding). Crie as regras direcionando o tráfego exclusivamente para a VM-SpringBoot:
| Porta Pública | Porta Privada | Protocolo | VM de Destino | Finalidade |
| 22 | 22 | TCP | VM-SpringBoot | Conexão SSH |
| 8080 | 8080 | TCP | VM-SpringBoot | API do ecossistema Spring Boot |
| 80 | 80 | TCP | VM-SpringBoot | Validação HTTP Let’s Encrypt |
| 443 | 443 | TCP | VM-SpringBoot | Acesso público HTTPS |
- Na aba Firewall deste mesmo IP Público, adicione as regras liberando o tráfego de entrada para as portas 22, 80, 443 and 8080, garantindo a perfeita correspondência campo a campo com o Port Forwarding.
3. Configuração de Sistema (Terminal)
Neste ponto, a infraestrutura da Locaweb Cloud garante o isolamento. Vamos agora operar os sistemas operacionais.
Passo 1: Acesso às VMs
Como a VM-Postgres não possui IP público e sua ACL bloqueia o tráfego externo direto, acessaremos o banco usando a VM Web como ponto de salto (Bastion Host).
Abra o terminal na sua máquina local e conecte-se à VM Web usando o IP público associado:
Bash
# Conecta na VM Pública (Web) usando o IP público da VPC ssh -i sua_chave.key ubuntu@<IP_PUBLICO_LOCAWEB>
A forma mais segura de alcançar a VM de banco é usar o salto direto (flag -J) a partir da sua máquina local, mantendo a chave privada apenas no seu computador de trabalho. Descubra antes o IP privado da VM-Postgres no painel (aba NICs da VM, normalmente algo como 10.0.2.x):
Bash
# Usa a VM Web como ponto de salto (ProxyJump) para alcançar a VM de banco ssh -i sua_chave.key -J ubuntu@<IP_PUBLICO_LOCAWEB> ubuntu@10.0.2.5
Passo 2: Instalação e Configuração do Banco de Dados (VM Privada)
Já conectado na VM-Postgres, atualize os repositórios e instale o PostgreSQL:
Bash
# Atualiza a lista de pacotes e instala o servidor PostgreSQL sudo apt update && sudo apt install postgresql postgresql-contrib -y # Habilita o serviço para iniciar junto com o boot e o starta imediatamente sudo systemctl enable --now postgresql
Bash
# Valida a versão ativa para conferência técnica do diretório psql --version
Por padrão de segurança, o PostgreSQL escuta apenas no localhost. Vamos alterar isso para aceitar conexões vindas da rede interna privada da Tier:
Bash
# Abre o arquivo de configuração principal do PostgreSQL 14 sudo nano /etc/postgresql/14/main/postgresql.conf
Encontre a linha #listen_addresses = ‘localhost’ e altere para permitir a escuta de todas as interfaces (o isolamento de portas e blocos já é feito de forma invisível pela ACL da nossa VPC):
Ini, TOML
listen_addresses = '*'
Agora, restrinja no nível da aplicação quais hosts podem se autenticar. Edite o arquivo de autenticação para aceitar conexões apenas da sub-rede pública 10.0.1.0/24 (Tier Web):
Bash
# Abre il file di configurazione pg_hba.conf sudo nano /etc/postgresql/14/main/pg_hba.conf
Adicione a seguinte linha ao final do arquivo, liberando autenticação criptografada (scram-sha-256) somente para a sub-rede da aplicação:
Plaintext
# TYPE DATABASE USER ADDRESS METHOD host all all 10.0.1.0/24 scram-sha-256
Acesse o prompt para criar o usuário e o banco de dados dedicados à aplicação. Substitua as credenciais fictícias por valores próprios e fortes:
Bash
# Acessa o prompt administrativo do psql sudo -u postgres psql
SQL
-- Cria o banco de dados da aplicação CREATE DATABASE app_db; -- Cria o usuário com credenciais fortes e criptografadas CREATE USER spring_user WITH ENCRYPTED PASSWORD 'TROQUE_POR_UMA_SENHA_FORTE'; -- Concede os privilégios necessários para a manipulação das tabelas GRANT ALL PRIVILEGES ON DATABASE app_db TO spring_user; -- Encerra o prompt administrativo do psql \q
Reinicie o serviço para aplicar as configurações e valide o status:
Bash
# Aplica as novas diretrizes do sistema do banco de dados sudo systemctl restart postgresql # Garanta que o serviço está rodando perfeitamente (active/running) sudo systemctl status postgresql
Encerre a sessão na VM de banco e retorne ao terminal da VM Web:
Bash
exit
Passo 3: Preparação da VM Web (Spring Boot)
Já conectado na VM-SpringBoot, instale o Java Runtime Environment necessário para executar o arquivo app.jar. O Spring Boot 3.x exige Java 17 ou superior:
Bash
# Sincroniza a lista de pacotes e instala o OpenJDK 17 headless sudo apt update sudo apt install openjdk-17-jre-headless -y
Confirme o sucesso do provisionamento:
Bash
# Exibe a versão ativa do Java no ambiente de execução java -version
4. Banco de Dados: String de Conexão da Aplicação
Ao empacotar sua aplicação Spring Boot, o seu arquivo application.properties (ou application.yml) deve apontar obrigatoriamente para o IP privado da sub-rede do banco de dados. A comunicação acontece inteiramente dentro do backbone de alta performance da nossa nuvem.
Properties
# Conexão isolada via rede interna da VPC (Tier Web -> Tier DB) # Substitua 10.0.2.5 pelo IP privato real da sua VM-Postgres spring.datasource.url=jdbc:postgresql://10.0.2.5:5432/app_db spring.datasource.username=spring_user spring.datasource.password=TROQUE_POR_UMA_SENHA_FORTE spring.datasource.driver-class-name=org.postgresql.Driver # Estratégia de geração de schema do Hibernate spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect # Porta de exposição da aplicação no ecossistema server.port=8080
5. Deploy da Aplicação (Dois Métodos)
A seguir, apresentamos dois caminhos para colocar seu projeto rodando. O primeiro foca em um modelo manual via gerenciamento de serviços do sistema operacional, ideal para validações rápidas. O segundo adota automações via Docker e GitHub Actions, garantindo agilidade no seu time-to-market.
Método 1: Deploy manual com systemd
Transfira o arquivo app.jar compilado localmente para a sua VM Web. Como apenas a camada Web possui IP público, o comando o alcança de forma direta:
Bash
# Transfere o artefato para o diretório home do usuário ubuntu scp -i sua_chave.key app.jar ubuntu@<IP_PUBLICO_LOCAWEB>:/home/ubuntu/app.jar
Crie o arquivo de definição da unidade:
Bash
# Cria o arquivo de serviço para gerenciar a aplicação em segundo plano sudo nano /etc/systemd/system/springboot.service
Cole a estrutura abaixo, validando os caminhos dos executáveis:
Ini, TOML
[Unit] Description=Aplicacao Spring Boot Locaweb Cloud After=network.target [Service] User=ubuntu WorkingDirectory=/home/ubuntu ExecStart=/usr/bin/java -jar /home/ubuntu/app.jar SuccessExitStatus=143 Restart=always RestartSec=10 [Install] WantedBy=multi-user.target
Atualize o daemon, habilite e inicialize a aplicação:
Bash
# Atualiza os registros do systemd para reconhecer o novo serviço sudo systemctl daemon-reload # Habilita a inicialização automática no boot da VM e starta o app sudo systemctl enable --now springboot # Valida se a sua API está rodando sem erros (active/running) sudo systemctl status springboot
Sempre que precisar atualizar o seu sistema manualmente, basta enviar o novo app.jar via SCP e reiniciar o serviço de forma limpa:
Bash
# Reinicia o serviço aplicando as atualizações do binário jar sudo systemctl restart springboot
Método 2: Deploy moderno com Docker e GitHub Actions
Este método automatiza o pipeline de ponta a ponta: empacota a aplicação em um contêiner isolado e realiza a entrega a cada push na sua branch principal, encurtando o seu time-to-market através do modelo self-service.
Instale a Engine do Docker na VM-SpringBoot através do repositório oficial do fabricante, garantindo o rastreio e fixação correta de versões estáveis:
Bash
# Adiciona dependências de segurança e chaves de repositório GPG oficiais sudo apt-get update sudo apt-get install -y ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg # Registra a fonte oficial do Docker na lista do apt corporativo echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # Realiza a instalação limpa da Engine, CLI e componentes do Docker Compose sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # Inicializa o serviço e adiciona seu usuário ao grupo para eliminar o uso de sudo sudo systemctl enable --now docker sudo usermod -aG docker $USER
Crie um arquivo chamado Dockerfile na raiz do seu projeto Java:
Dockerfile
# Imagem base enxuta Alpine com Java 17 runtime FROM eclipse-temurin:17-jre-alpine WORKDIR /app # Copia o artefato compilado para o escopo do contêiner COPY target/app.jar app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "app.jar"]
No seu repositório Git do GitHub, monte a estrutura do workflow automatizado criando o arquivo .github/workflows/deploy.yml:
YAML
name: Deploy Spring Boot na Locaweb Cloud on: push: branches: [ main ] jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout do código uses: actions/checkout@v4 - name: Configurar JDK 17 uses: actions/setup-java@v4 with: distribution: temurin java-version: '17' - name: Compilar a aplicação com Maven run: mvn -B clean package -DskipTests - name: Deploy via SSH na VM Web uses: appleboy/ssh-action@v1.0.3 with: host: ${{ secrets.SSH_HOST }} username: ${{ secrets.SSH_USER }} key: ${{ secrets.SSH_KEY }} script: | cd /home/ubuntu/app git pull origin main docker build -t spring-app . docker stop spring-app || true docker rm spring-app || true docker run -d --name spring-app --restart always -p 8080:8080 spring-app
- SSH_HOST: O IP público da sua VPC no painel Locaweb.
- SSH_USER: O usuário padrão do sistema operacional (ex: ubuntu).
- SSH_KEY: O conteúdo textual completo da sua chave privada SSH.
A partir de agora, cada push na sua branch main dispara de forma automatizada o build e a atualização do contêiner na nuvem, mantendo sua infraestrutura moderna e ágil.
6. HTTPS com Let’s Encrypt (Recomendado para Produção)
Expor a API diretamente através de conexões HTTP transmite dados textuais sensíveis sem proteção. Vamos plugar o Nginx operando como proxy reverso na frente do Spring Boot para gerenciar os certificados TLS de forma simples.
Instale o Nginx e o cliente Certbot:
Bash
# Instala o servidor web e o gerador automático do Let's Encrypt sudo apt update sudo apt install -y nginx certbot python3-certbot-nginx
Configure o bloco do servidor para realizar o roteamento interno:
Bash
# Cria o arquivo de configuração para o roteamento do seu domínio sudo nano /etc/nginx/sites-available/springboot.conf
Nginx
server { listen 80; server_name seu-dominio.com.br; location / { # Encaminha as requisições de rede para a porta local da aplicação proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
Ative a configuração no painel do Nginx, valide a sintaxe do arquivo e recarregue o serviço:
Bash
# Cria o link simbólico para ativar o site no Nginx sudo ln -s /etc/nginx/sites-available/springboot.conf /etc/nginx/sites-enabled/ # Valida se a sintaxe estrutural do arquivo possui alguma inconformidade técnica sudo nginx -t # Recarrega o serviço para aplicar a nova rota ativa sudo systemctl reload nginx
Dispare o comando do Certbot. O assistente automatizado emitirá o certificado digital SSL e reconfigurará o Nginx para forçar o redirecionamento seguro para HTTPS:
Bash
# Executa a validação e gera o certificado digital SSL para a sua URL sudo certbot --nginx -d seu-dominio.com.br
7. Validação
A etapa de validação atesta a integridade e o sucesso da topologia IaaS implementada no ecossistema.
1. Teste interno na VM Web
Conectado via SSH na VM-SpringBoot, realize uma chamada local para o endpoint de saúde da sua aplicação e verifique se o serviço está escutando a porta corretamente:
Bash
# Verifica se o serviço systemd está em execução normal sudo systemctl status springboot # Faz a requisição local de teste curl -I http://localhost:8080/api/health
Resultado esperado: Status HTTP/1.1 200 OK, indicando que a stack Java subiu e responde localmente.
2. Teste externo da aplicação (Máquina de Trabalho)
A partir do terminal do seu computador local, envie uma chamada HTTP apontando para o IP público associado à sua VPC:
Bash
# Requisição externa para validar o Port Forwarding do painel curl -I http://<IP_PUBLICO_LOCAWEB>:8080/api/health
Resultado esperado: Retorno HTTP/1.1 200 OK. A aplicação respondeu externamente, provando que a VM Web processou o pacote e realizou a conexão interna em tempo real com a VM de banco de dados para buscar as tabelas. (Caso já tenha rodado o passo anterior do Nginx, teste apontando para a sua URL segura: curl -I https://seu-dominio.com.br/api/health).
3. Teste de isolamento do banco de dados (Ação Crítica)
Este é o teste definitivo que valida o compliance e a proteção da sua arquitetura de rede. A partir do seu computador local, tente forçar uma conexão direta ao PostgreSQL usando o IP público da nuvem:
Bash
# Tentativa intencional de burlar o isolamento pela internet pública psql -h <IP_PUBLICO_LOCAWEB> -U spring_user -d app_db -p 5432
Resultado esperado: Mensagem de erro de Connection timed out ou Connection refused. Como não há regras de Port Forwarding mapeando a porta 5432 externa e a ACL da nossa sub-rede privada rejeita pacotes fora do bloco 10.0.1.0/24, o Roteador Virtual barra o tráfego imediatamente.
8. Solução de problemas (Troubleshooting)
- Permissão SSH negada no terminal (Permission denied (publickey))
- Sintoma: Ao tentar disparar o comando de acesso, o console recusa o parâmetro e exibe a mensagem de chave inválida.
- Causa: A sua chave privada .key ou .pem está com permissões de leitura abertas demais no sistema de arquivos local, fazendo com que o cliente SSH recuse a credencial por segurança.
- Solução: Ajuste os privilégios do arquivo local restringindo o acesso apenas ao seu usuário administrador da máquina e repita a conexão:
Bash
chmod 400 sua_chave.key ssh -i sua_chave.key ubuntu@<IP_PUBLICO_LOCAWEB>
Aplicação inacessível externamente (Connection timed out)
-
- Sintoma: O comando curl externo na porta 8080 retorna estouro de tempo de resposta, mas o teste interno local dentro do servidor responde com sucesso.
- Causa: Há uma quebra de consistência ou ausência de regras na infraestrutura: falta configurar o Port Forwarding, liberar a porta no Firewall do IP público ou cadastrar a entrada correspondente na lista da ACL-Tier-Web.
- Solução: Acesse o painel de controle do Locaweb Cloud e certifique-se de que as três camadas possuem correspondência exata: a aba Port Forwarding deve mapear a porta 8080, a aba Firewall deve conter a liberação de tráfego de entrada e a regra da sua Network ACL deve permitir pacotes TCP na porta 8080.
Aplicação falha ao conectar ao banco (Connection refused na porta 5432)
-
- Sintoma: Os logs do Spring Boot (sudo journalctl -u springboot -f) indicam falhas de conexão de banco de dados (Connection refused).
- Causa: O PostgreSQL na VM privada está escutando apenas localmente, as regras do arquivo pg_hba.conf não liberam o IP da sub-rede pública ou a regra de entrada da ACL-Tier-DB está bloqueando a porta 5432.
- Solução: Na VM-Postgres, valide se a linha listen_addresses = ‘*’ está ativa no arquivo postgresql.conf e se a linha host all all 10.0.1.0/24 scram-sha-256 foi adicionada ao arquivo pg_hba.conf. Reinicie o serviço (sudo systemctl restart postgresql). No painel da nuvem, confirme se a lista ACL-Tier-DB possui a regra de entrada TCP habilitada para a porta 5432 vinda da origem 10.0.1.0/24.
- Snapshots Recorrentes: Ative a rotina de Snapshots automatizados no volume de disco da sua VM-Postgres para garantir pontos de restauração rápidos e cópias de segurança sem esforço (Armazenamento > Discos > Snapshots Recorrentes).
- Balanceador de Carga: Conforme sua aplicação crescer em volume de acessos, provisione novas máquinas virtuais idênticas à VM-SpringBoot na sub-rede pública e conecte-as ao Load Balancer do Roteador Virtual para distribuir as requisições sem gargalos.
- Monitoramento Ativo: Configure as métricas de telemetria no painel da sua conta para acompanhar o uso de memória RAM, CPU e throughput de rede das instâncias, antecipando gargalos antes que eles impactem seus usuários.
[Conheça!] Quer automatizar disparos de confirmação de cadastro, relatórios de uploads ou faturas transacionais diretamente do seu app Django? Conheça o SMTP Locaweb, nossa plataforma de alta reputação e entregabilidade de mensagens desenvolvida para fazer o seu sistema se comunicar com velocidade e segurança!