DEV Community

Cover image for Utilizando Docker em App WEB Spring Boot
Fernando Raposo da Camara Silva
Fernando Raposo da Camara Silva

Posted on Edited on

Utilizando Docker em App WEB Spring Boot

Certo, muito se fala hoje em dia em Docker... A minha experiência recente é de puro fascínio, como demorei tanto para utilizá-lo? Realmente não sei...
Neste artigo tentarei sintetizar meus entendimentos de Docker e como utilizá-lo para "rodar" um sisteminha Web bem básico. Assim divido tudo em partes:

  1. Conceito do Docker e o que ele tenta resolver;
  2. Um pequeno sistema WEB utilizando Spring Boot;
  3. Juntando tudo: o sistema WEB rodando dentro do Docker;

O que é o Docker?

Analise estes cenários:

  • Lembra aquela vez em que você queria usar um aplicativo no seu computador e instalando dependências necessárias para tal acabou por "quebrar" outros aplicativos no computador?
  • Ou quando para evitar esse tipo de coisa descrita acima você tentou levantar um outro Sistema Operacional virtualizado rodando por cima do seu S.O e no final tudo isso rodando junto ficou tão lento e ocupou tanto espaço que você desistiu!
  • Lembra aquele sistema que você desenvolveu, roda legal na sua máquina mas quando você coloca em produção você passa a noite inteira para fazer funcionar?

Para facilitar a resolução dos três cenários acima a resposta é Docker, Docker e Docker! Vamos primeiro tentar entender a diferença entre um sistema rodando no Docker e rodando numa virtualização de sistema operacional olhando a figura abaixo:
image

Para entender Docker precisamos entender o conceito de Containers. Pelo próprio site do Docker, um container é: "Uma peça padrão de software que empacota código e suas dependências de forma que as aplicações rodem rapidamente e de forma confiável de um ambiente computacional para o outro." Neste site há uma comparação legal, que compara o Docker a um condomínio de apartamentos e um sistema virtualizado a uma casa alugada.
Enquanto que em um condomínio os recursos (a piscina, a academia, garagem, água...) são compartilhados entre os vizinhos. Em uma casa alugada nada é compartilhado, ou seja tudo é exclusivo, e sabemos que essa exclusividade tem um custo.
Resumindo: Containers são menores que imagens virtuais, podem ser mais facilmente construídos (e destruídos) e eles compartilham recursos com o S.O em que estão rodando. Em contrapartida, sistemas virtualizados não compartilham nada um com o outro e também não compartilham recursos no S.O em que estão rodando.

OBS: Informações sobre como instalar o Docker podem ser encontradas no site oficial.

1. Docker

1.1. Dockerfile

O Docker entende uma receitinha de bolo que explica como construir o Container, essa receita é um arquivo sem terminação chamado Dockerfile. Se você vai usar um Linux bem pequeno chamado alpine para rodar o seu programa, você tem que dizer isso no Dockerfile. Se vai precisar instalar uma ferramenta/ dependência que o seu sistema precisa dizer isso também no Dockerfile.

1.2 Docker Image

O Dockerfile é só a receita do Container. É necessário construí-lo fisicamente em uma imagem (na verdade aquele Linux chamado Alpine que é pequeno e que você pode usar também é uma imagem), ou seja, imagens específicas são compostas de outras mais genéricas.

1.3 Container

Depois que temos o Dockerfile e a imagem construída, colocamos o Container baseado naquela imagem para rodar. Se fizermos a analogia com JAVA, imagine o Dockerfile como se fosse o arquivo *.java, a imagem como se fosse o *.class ou o *. jar gerado e o Container como o aquivo jar rodando. E como sabemos, para rodar um jar muitas vezes precisamos passar parâmetros, com os Containers não é diferente, por exemplo, se queremos acessar uma porta do Container, precisamos passar isso como parâmetro.

2. Sistema WEB com SpringBoot

2.1. http://localhost:8080

Crie uma pasta chamada docker e abra o VSCode nela e pressione CTRL+SHIFT+p



$mkdir docker
/docker$ code .


Enter fullscreen mode Exit fullscreen mode

Escolha Spring Initializr: Create a Maven Project
image
Depois escolha a versão mais recente que houver do SpringBoot, no caso, estou usando 2.5.3
image
Escolha a linguagem JAVA e mantenha as opções que vem sendo apresentadas (com.example) e (demo). No packaging type, escolha Jar e na versão JAVA eu estou trabalhando com a 8.
Por fim escolha apenas a dependência do Spring Web (a última da foto)
image
Após isso o seu VSCode deve estar assim com a classe DemoApplication.java criada:
image
O programa ainda não tem muita função, precisamos de um acesso para este retorne informações quando o sistema receber requisições externas. Vamos criar uma classe chamada Serviço (Servico.java) dentro de uma package chamada service que é bem simples, ela só retorna "Hello World":



package com.example.demo.service;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class Servico {

    @RequestMapping("/hello")
    public String hello() {
        return "Hello World";
    }

}


Enter fullscreen mode Exit fullscreen mode

Volte na classe DemoApplication e no método main clique em Run para executar a aplicação. image
Quando ela acabar de levantar, vá no browser e escreva http://localhost:8080/hello
O resultado será o abaixo, e isto quer dizer que o seu sistema WEB está rodando localmente com acesso ao serviço /hello na porta 8080.
image
Falamos antes de Docker e agora temos uma aplicação WEB rodando. Como criar um Container rodando esta aplicação? É o próximo desafio.

3. Aplicativo Rodando no Container

3.1. Construindo Dockerfile

Temos o nosso aplicativo construído na seção 2, vamos agora pensar em como seria o ambiente para executá-lo. Primeiramente, vamos executá-lo em um Container Linux, então vamos considerar o Alpine, mais informações sobre ele aqui. Lembrem que eu escolhi o Java 8 quando estava criando o aplicativo? Então este é outro ponto a se considerar.
Crie um arquivo Dockerfile (sem extensão) no mesmo diretório criado (docker) e no mesmo local onde o projeto JAVA está criado e irei comentar linha a linha este arquivo Dockerfile.



Linha 1: Diz que precisaremos de uma imagem do Linux Alpine e que deve vir com um jdk versão 8 já instalado (prático, não precisamos instalar JAVA);

Linha 3: Diz qual será o diretório de trabalho no Container, no caso será o /home;

Linha 5: Diz para copiar tudo que estiver neste diretório em que estamos e mandar para o WORKDIR definido (no caso /home);

Linha 7: Como a versão Alpine do Linux é bem básica, precisamos instalar o Maven (lembrem que criamos um Maven Project lá no VSCode), é isto que este comando faz;

Linha 9: Após a linha 3 executar passamos a ter um diretório /demo dentro de /home, setamos então /home/demo como sendo o novo diretório de trabalho;

Linha 11: Rodamos o comando para fazer o MAVEN gerar o Jar do App que desenvolvemos, este jar é criado em uma pasta /home/demo/target

Linha 13: Este comando expõe a porta 8080 (que é a porta que o App Web utiliza para receber requisições

Linha 15: Este comando representa o que deverá ser rodado no prompt deste Container quando ele for iniciado, que são o comando java, com os parâmetros "-jar" e o arquivo jar a ser executado /home/demo/target/demo-0.0.1-SNAPSHOT.jar

3.2. Gerando Imagem

Lembrem que o Dockerfile é como se fosse o arquivo .java, então temos que gerar o .jar dele para podermos rodá-lo. Para fazer isso, utilizamos o comando build e com isso geraremos a imagem com tudo que está descrito no Dockerfile. Assim, na mesma pasta em que estão o Dockerfile e a pasta /demo com o nosso projeto Spring, digite:
docker build . -t java-spring
O que isso vai fazer? Vai ler o Dockerfile que está nesta pasta, vai ler o projeto Spring criado e gerar a imagem que terá o nome de "java-spring". Aguarde a imagem ser criada e depois digite o comando docker image list para constatar que a imagem foi criada.
image
Isso quer dizer que a imagem (o nosso jar) foi criado. Temos que pô-lo para rodar.

3.3. Criando Container

Como foi dito, da mesma forma como temos que passar parâmetros para rodar um arquivo jar, para rodar um Container também temos a mesma lógica. Para executarmos o Container e conseguirmos acessá-lo do browser da mesma forma que acessamos quando rodamos localmente precisaremos fazer um mapeamento de portas. Recorde-se que na Linha 13 foi exposta a porta 8080, precisamos agora mandar informações para esta porta mapeando uma porta no S.O host para a porta do Container. Veja o comando abaixo para gerar o Container
docker run --name java-container -d -p 8080:8080 java-spring
traduzindo os parâmetros para:

  • --name: o nome do Container (java-container);
  • -d: Modo dettached (isso quer dizer que após o container começar a rodar, ele ficará rodando em background e o terminal ficará livre para o usuário);
  • -p: é o mapeamento de portas PORTA_HOST:PORTA_CONTAINER, quer dizer que uma requisição no host para a porta 8080 irá ser enviada para o host na porta 8080.

O parâmetro a seguir é justamente a imagem java-spring que foi criada, seria como se fosse o nome do jar que vamos rodar.

Após solicitar que o Container inicie-se pode ir no Browser e digitar http://localhost:8080/hello, o efeito será o mesmo de quando executávamos o app web no host, justamente a palavra Hello World.

3.4. Comandos Adicionais Docker

Listar Containers rodando

$docker ps

Listar Containers existentes

$docker ps -a

Iniciar um Container

$docker start <nome_container>

Derrubar um Container

$docker stop <nome_container>

Reiniciar um Container (stop seguido de um start)

$docker restart <nome_container>

Listar Imagens Máquina Local

$docker image list

Remover Imagem

$docker rmi <nome_imagem>

Enviar um comando para um Container rodando

$docker exec -it <nome_container> <comando>

Considerações

O Docker é um aliado poderoso, vale a pena aprender e usá-lo. O app e o Dockerfile estão aqui para quem quiser baixar.

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.