No mundo atual, a infraestrutura em nuvem se tornou essencial para o desenvolvimento e implantação de aplicações web. A Virtual Private Server (VPS), ou Servidor Virtual Privado, é uma solução popular que oferece controle, escalabilidade e desempenho para hospedar aplicativos online. Neste artigo, apresentaremos um guia completo sobre como preparar uma VPS para hospedar uma aplicação Spring, permitindo que você execute e disponibilize sua aplicação com facilidade e segurança.
O processo será detalhado, desde a escolha do provedor de nuvem até a configuração do servidor web Nginx para servir a aplicação na web. Utilizaremos como exemplo a plataforma DigitalOcean, no entanto, os procedimentos podem ser adaptados para outras provedoras de nuvem que ofereçam serviços de VPS. Vamos começar preparando a VPS com todos os requisitos necessários para hospedar a sua aplicação Spring.
Preparando a nossa VPS
Primeiramente vamos preparar a VPS para que a mesma esteja com todo o ambiente necessário para executar e disponibilizar a nossa aplicação Spring.
Existem diversos provedores de nuvem que disponibilizam um serviço de VPS, nesse artigo vamos utilizar a DigitalOcean, porém, todo o passo a passo de configuração aqui demonstrado pode ser aplicado para outros provedores de nuvem. Pois essencialmente uma VPS nada mais é do que uma máquina virtual.
Curso Spring Framework - Fundamentos
Conhecer o cursoCriando um projeto
Agora vamos criar um Droplet, nome dado pela DigitalOcean ao seu produto de VPS. Para isso acesse a sua conta na DigitalOcean e selecione a opção de criar um novo Droplet.
Na tela de criação de um Droplet, vamos precisar passar algumas configurações. A primeira é que precisamos informar qual a região do Datacenter que irá conter o nosso Droplet.
O ideal é escolher a região geograficamente mais próxima aos usuários que irão utilizar a aplicação.
Logo em seguida precisamos escolher qual a imagem do sistema operacional que vamos utilizar em nosso Droplet.
Para esse artigo vamos utilizar uma máquina Ubuntu 22.04.
Também precisamos informar qual será a configuração de hardware do nosso Droplet. Esse é um ponto muito importante, pois, dependendo das configurações de hardware, seremos cobrados um valor diferente.
Para esse exemplo vamos utilizar uma máquina com uma CPU AMD, com 1 GB de memória e 25 GB de armazenamento em disco. Para essa configuração seremos cobrados o valor de sete dólares por mês. Lembrado que a DigitalOcean só cobra pelo tempo utilizando, ou seja, caso a máquina fique disponível por um único dia, só seremos cobrados o equivalente há um dia de uso e não por um mês completo.
Agora precisamos informar o método de autenticação que iremos utilizar, para facilitar, vamos utilizar uma autenticação com senha.
Por fim, recomendo também alterar o hostname do Droplet para facilitar a identificação da VPS.
Agora, basta clicar no botão “Create Droplet” para que o Droplet seja criado e disponibilizado.
Conectando ao Droplet via SSH
Agora que o nosso Droplet está criado, vamos precisar entrar no terminal desse Droplet para podermos executar comandos na nossa VPS. Para isso iremos utilizar o SSH (Secure Shell).
Primeiramente, precisamos do endereço IP que foi gerando para o nosso Droplet, para obter essa informação vá até a página de listagem dos Droplets, página essa para qual formos redirecionados após a criação do Droplet e copie o endereço IP disponibilizado.
Agora que temos o endereço IP do nosso Droplet vamos nos conectar a nossa VPS com o seguinte comando:
ssh root@165.232.148.181
Lembre-se de substituir o endereço IP do comando acima para o endereço IP da sua VPS.
Ao executar o comando acima pela primeira vez será exibida a seguinte mensagem:
The authenticity of host '165.232.148.181 (165.232.148.181)' can't be established.
ED25519 key fingerprint is SHA256:stYZPeU0IekNoljTjsAs8uHQiZFlSrnBhCvYDPisuwY.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?
Basta digitar “yes” e depois dar um enter e logo em seguida digitar a senha que você configurou para o usuário root na criação do seu Droplet e dar um enter novamente.
Curso Spring Framework - Tópicos Avançados
Conhecer o cursoConfigurando um Firewall
Como boa prática de segurança, vamos habilitar um firewall em nosso servidor para garantir que apenas certos serviços possam receber conexões externas.
Para isso vamos utilizar o UFW (Uncomplicated Firewall), que é um serviço de firewall que já vem disponibilizado no Linux Ubuntu.
Primeiramente vamos configurar o UFW para permitir conexões via SSH, para isso execute o seguinte comando:
ufw allow OpenSSH
E por fim vamos habilitar o nosso firewall com o comando:
ufw enable
Como o firewall está bloqueando atualmente todas as conexões, exceto o SSH, se você instalar e configurar serviços adicionais, precisará ajustar as configurações do firewall para permitir o tráfego.
Instalando o Java Runtime Enviroment
Para podermos executar a nossa aplicação, vamos precisar instalar o JRE (Java Runtime Enviroment), para isso executamos o seguinte comando:
apt install openjdk-17-jre-headless
Para verificarmos se a instalação foi bem sucedida, basta executar o comando java --version
e a saída desse comando será algo semelhante ao conteúdo abaixo:
openjdk 17.0.7 2023-04-18
OpenJDK Runtime Environment (build 17.0.7+7-Ubuntu-0ubuntu122.04.2)
OpenJDK 64-Bit Server VM (build 17.0.7+7-Ubuntu-0ubuntu122.04.2, mixed mode, sharing)
Instalando o Nginx
A fim de disponibilizarmos a nossa aplicação na web, vamos precisar de um servidor HTTP, para esse artigo nós vamos utilizar o Nginx.
A instalação do Nginx pode ser feita com o seguinte comando:
apt install nginx
Para verificarmos se a instalação do Nginx foi bem sucedida podemos verificar o status do serviço do Nginx com o seguinte comando:
systemctl status nginx
A saída gerado pelo comando acima será algo semelhante ao conteúdo abaixo:
nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2023-07-31 07:27:49 UTC; 17s ago
Docs: man:nginx(8)
Process: 10076 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exit>
Process: 10077 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, statu>
Main PID: 10166 (nginx)
Tasks: 2 (limit: 1116)
Memory: 5.1M
CPU: 27ms
CGroup: /system.slice/nginx.service
├─10166 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"
└─10169 "nginx: worker process" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ">
Agora que temos o Nginx instalado, também precisamos habilitar o Nginx em nosso firewall, para isso execute o seguinte comando:
ufw allow 'Nginx Full'
Para verificarmos que de fato o Nginx foi habilitado em nosso firewall, basta acessar o código IP da nossa VPS no navegador que iremos visualizar a página de boas-vindas do Nginx.
Ao instalar o Nginx é criada uma pasta chamada www
dentro do diretorio /var
, essa pasta é onde comumente colocamos as nossas aplicações, então vamos criar uma nova pasta dentro de www
que irá conter os arquivos da aplicação que iremos realizar o deploy. Então, execute o seguinte comando:
mkdir /var/www/spring
Curso Nginx - Fundamentos
Conhecer o cursoPreparando o projeto localmente
Agora nós já temos a configuração necessário em nosso servidor para que ele seja capaz de executar a nossa aplicação Spring. O que vamos precisar fazer é então preparar a aplicação localmente e então enviar essa aplicação para a VPS.
Eu já deixei pronta uma aplicação Spring Boot que iremos utilizar para exemplificar o processo de deploy, essa aplicação é bem simples, consiste basicamente em uma página de “Hello World” na rota principal da aplicação.
Executando a aplicação
Para testarmos a aplicação localmente vamos precisar clonar o repositório, entrar na pasta do projeto e então executar a aplicação. Para isso execute os seguintes comando no terminal.
git clone https://github.com/CleysonPH/spring-deploy-vps-example.git
cd spring-deploy-vps-example
mvn spring-boot:run
Após executar os comandos acima, acesse o link http://localhost:8080/ e você verá a seguinte página:
Gerando o arquivo JAR
As aplicações desenvolvidas com Spring Boot podem ser empacotadas em um arquivo .jar
, esse arquivo é o build final de nossa aplicação, arquivo esse que precisamentos enviar para o nosso servidor.
Para gerar o arquivo JAR executamos o seguinte comando:
mvn clean package
Após a execução do comando acima, você verá que foi gerado um arquivo chamado vps-deploy-0.0.1-SNAPSHOT.jar
localizado na pasta target
.
Curso Linux - Fundamentos para desenvolvedores
Conhecer o cursoRealizando o deploy do projeto
Agora que já conseguimos realizar o build da nossa aplicação e também já preparamos a nossa VPS para conseguir executar e disponibilizar a aplicação. Vamos de fato realizar o deploy do nosso projeto.
Enviando o arquivo JAR para o servidor
Para enviarmos o arquivo para JAR para dentro do nosso servidor vamos utilizar o SCP (Secure copy)
Para isso execute o seguinte comando:
scp target/vps-deploy-0.0.1-SNAPSHOT.jar root@165.232.148.181:/var/www/spring
Aqui está uma explicação detalhada do comando:
-
scp
: É o comando que invoca a funcionalidade de cópia segura. -
target/vps-deploy-0.0.1-SNAPSHOT.jar
: É o caminho do arquivo que você deseja copiar. Neste caso, o arquivo é chamado “vps-deploy-0.0.1-SNAPSHOT.jar” e está localizado dentro da pasta “target”. -
root@165.232.148.181
: É o endereço IP ou nome de domínio do servidor remoto para o qual você deseja copiar o arquivo. O usuário “root” é usado para autenticação no servidor remoto. -
:/var/www/spring
: É o caminho do diretório de destino no servidor remoto onde o arquivo será copiado. Neste caso, o arquivo será copiado para o diretório “/var/www/spring” no servidor remoto.
Em resumo, o comando copiará o arquivo “vps-deploy-0.0.1-SNAPSHOT.jar” da pasta local “target” para o diretório “/var/www/spring” no servidor remoto com o endereço IP “165.232.148.181”, usando o usuário “root” para autenticação.
Executando o arquivo JAR no servidor
No servidor de produção nós podemos simplesmente executar o comando java -jar /var/www/vps-deploy-0.0.1-SNAPSHOT.jar
para rodar a aplicação, porém, isso fará com que o terminal fique travado e assim que sairmos do terminal a aplicação também irá parar de executar. Então precisamos executar a aplicação de alguma maneira que o terminal não fique travado e que a mesma seja executada novamente caso a máquina, seja reiniciada.
Uma maneira de fazer isso é através da configuração de um serviço. Para isso precisamos de criar um arquivo de configuração que irá informar como esse serviço deve ser executado. Então devemos nos conectar novamente ao terminal do servidor através do SSH e então executar o seguinte comando:
nano /etc/system/system/spring.service
Com o comando acima vamos abrir o editor de texto nano em novo um arquivo chamado spring.service
no diretório /etc/system/systemd
, esse arquivo será o arquivo de configuração do nosso serviço.
Nesse arquivo vamos colocar o seguinte conteúdo:
[Unit]
Description=Aplicação Spring de teste para deploy na DigitalOcean
[Service]
WorkingDirectory=/var/www/spring
ExecStart=java -jar vps-deploy-0.0.1-SNAPSHOT.jar
User=root
Restar=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
Aqui vai uma explicação detalhada do código de configuração que estamos utilizando:
-
[Unit]
: Esta seção contém metadados sobre o serviço. Neste caso, apenas a descrição do serviço está presente. -
[Service]
: Esta seção contém informações sobre o serviço em si e como ele deve ser executado.-
WorkingDirectory=/var/www/spring
: Define o diretório de trabalho para o serviço. O serviço será iniciado a partir deste diretório. -
ExecStart=java -jar vps-deploy-0.0.1-SNAPSHOT.jar
: Especifica o comando que será executado para iniciar o serviço. Neste caso, ele inicia a aplicação Spring executando o arquivo JAR “vps-deploy-0.0.1-SNAPSHOT.jar” usando o comando “java -jar”. -
User=root
: Define o usuário sob o qual o serviço será executado. Neste caso, o serviço será executado com privilégios de superusuário (root). -
Restart=on-failure
: Indica que o serviço será reiniciado automaticamente se ele falhar inesperadamente (por exemplo, devido a uma exceção não tratada). -
RestartSec=10
: Especifica o intervalo de tempo (em segundos) após o qual o serviço será reiniciado, se necessário. Neste caso, após uma falha, o serviço será reiniciado após 10 segundos.
-
-
[Install]
: Esta seção especifica como o serviço deve ser instalado e configurado como parte do sistema.-
WantedBy=multi-user.target
: Indica que o serviço deve ser iniciado automaticamente quando o sistema estiver no modo multiusuário. Isso geralmente significa que o serviço será iniciado durante a inicialização do sistema.
-
Para salvar o conteúdo do arquivo e então sair do editor nano utilize os atalhos CTRL+o e depois CTRL+x.
Agora precisamos iniciar o serviço que foi configurado e também habilitar o serviço para que o mesmo sempre execute mesmo que o sistema seja reinicializado. Para isso execute os comandos:
systemctl start spring.service
systemctl enable spring.service
Para vermos os status do nosso serviço podemos executar o comando systemctl status spring.service
e então veremos uma saída similar a seguinte:
spring.service - Aplicação Spring de teste para deploy na DigitalOcean
Loaded: loaded (/etc/systemd/system/spring.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2023-08-01 12:51:53 UTC; 4min 39s ago
Main PID: 28525 (java)
Tasks: 29 (limit: 1116)
Memory: 128.8M
CPU: 8.334s
CGroup: /system.slice/spring.service
└─28525 java -jar vps-deploy-0.0.1-SNAPSHOT.jar
Configurando o Nginx
Agora, a nossa aplicação já sendo executada em nosso servidor, porém ainda não temos acesso a mesmo pela web. Isso porque nós temos um firewall configurado que impede que conexões sejam feitas em nosso servidor e no momentos temos apenas o Nginx sendo habilitado para receber conexões.
Então precisamos configurar o Nginx para servir a nossa aplicação para o mundo externo. Para isso execute o seguinte comando:
nano /etc/nginx/sites-available/default
Com o comando acima vamos editar o arquivo de configuração padrão do Nginx e nesse arquivo vamos editar a seção location /
, e colocar as configurações necessárias para o Nginx servir a aplicação para a web. Abaixo vou deixar a configuração completa do arquivo:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
server_name _;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:8080;
proxy_redirect off;
try_files $uri $uri/ =404;
}
}
Aqui está uma explicação das principais partes do código:
-
server
: Indica o início da configuração de um bloco de servidor. Isso permite definir as configurações específicas para esse servidor virtual. -
listen 80 default_server;
elisten [::]:80 default_server;
: Configura o servidor para escutar conexões HTTP na porta 80. A opçãodefault_server
significa que este servidor será usado como servidor padrão para qualquer solicitação que não corresponda a nenhum outro servidor virtual. -
root /var/www/html;
: Define o diretório raiz para o servidor. Todos os arquivos do site estão localizados em “/var/www/html” neste caso. -
server_name _;
: Especifica o nome do servidor virtual. Neste caso, o caractere sublinhado (_) é usado como um curinga, indicando que esse servidor virtual será o padrão usado para qualquer solicitação que não corresponda a um servidor virtual específico. -
location / { ... }
: Define as configurações para a localização do servidor que corresponde ao caminho “/”. Isso é a configuração padrão para todas as solicitações não tratadas por outras localizações. - Nas configurações
location / { ... }
, temos várias diretivas de proxy para passar as solicitações para o aplicativo ou serviço em execução na porta 8080 em localhost (127.0.0.1).-
proxy_set_header
: Define os cabeçalhos que serão enviados para o servidor backend (127.0.0.1:8080). -
proxy_pass http://127.0.0.1:8080;
: Define o endereço do servidor backend (aplicativo ou serviço) onde as solicitações serão encaminhadas. -
proxy_redirect off;
: Desativa a substituição automática de cabeçalhos “Location” nos cabeçalhos da resposta do servidor backend. -
try_files $uri $uri/ =404;
: Tenta servir o arquivo solicitado diretamente, ou se não existir, repassa para o servidor backend (127.0.0.1:8080).
-
Essa configuração é comum para atuar como um proxy reverso para aplicativos da web ou servidores de aplicativos que estão sendo executados na porta 8080 do localhost. O Nginx recebe as solicitações na porta 80, encaminha-as para o servidor de backend na porta 8080 e retorna as respostas para o cliente que fez a solicitação.
Agora podemos acessar a aplicação pela web, basta acessar o endereço IP da sua VPS pelo navegador, no meu caso a acessar o endereço http://165.232.148.181/ veremos a seguinte página.
Conclusão
Neste artigo, exploramos o passo a passo de como preparar uma Virtual Private Server (VPS) para hospedar e disponibilizar uma aplicação Spring. Aprendemos a configurar uma VPS na plataforma DigitalOcean e como instalar o Java Runtime Environment (JRE) e o servidor web Nginx, elementos essenciais para executar e servir a aplicação.
Além disso, mostramos como realizar o deploy da aplicação, desde a geração do arquivo JAR localmente até a transferência e execução do mesmo na VPS. Ao configurar um serviço através do systemd, garantimos que a aplicação seja executada de forma contínua mesmo após reinicializações.
Com a VPS devidamente preparada e o Nginx configurado como proxy reverso, sua aplicação Spring está pronta para ser acessada pela web. É importante destacar que a segurança também foi considerada, visto que habilitamos um firewall para permitir apenas as conexões necessárias.
Seguindo esse guia, você estará pronto para hospedar suas aplicações web com eficiência, escalabilidade e segurança em uma VPS. Experimente e explore todas as possibilidades que essa poderosa ferramenta oferece para o desenvolvimento e disponibilização de suas aplicações online.