Como usar o Docker em uma aplicação fullstack (React+Node)

Docker é uma plataforma que permite que você empacote, distribua e execute aplicativos em contêineres sem instalar as dependências diretamente no seu computador, tornando a implantação e o gerenciamento de aplicativos mais simples.
Em outras palavras, o Docker é uma ferramenta que ajuda a empacotar um aplicativo com todas as suas dependências em um contêiner, de modo que ele possa ser executado em qualquer lugar, independentemente do ambiente em que está sendo executado.

Para que serve o Docker?
Ao passar um tempo estudando desenvolvimento Web, eventualmente iremos nos deparar com essa tecnologia chamada Docker, mas para que realmente serve isso? Simplificando bastante, o Docker é uma ferramenta que permite que o projeto seja iniciado de maneira mais fácil, sendo possível criar banco de dados, rodar o backend e rodar o frontend em um único comando, sem ter que instalar nada a não ser o próprio Docker.
Mas por que isso é importante? Bem, a principal dificuldade que o Docker resolve é a de garantir que um aplicativo funcionará da mesma forma em diferentes ambientes. Isso porque, com o Docker, você pode empacotar todas as dependências do aplicativo em um contêiner, incluindo o sistema operacional, bibliotecas e outras ferramentas. Dessa forma, é possível garantir que o aplicativo funcione da mesma forma em diferentes máquinas e sistemas operacionais.
Onde o Docker é usado?
Empresas como a Uber, PayPal, Netflix e Spotify estão entre as grandes empresas que utilizam o Docker em seus aplicativos. Isso porque o Docker torna a implantação e o gerenciamento de aplicativos mais fácil e eficiente, permitindo que as empresas possam se concentrar no desenvolvimento de novos recursos e melhorias em vez de lidar com problemas de compatibilidade e ambiente.
Além disso, o Docker também é uma ferramenta muito popular entre desenvolvedores independentes e equipes de desenvolvimento de software, pois permite que eles compartilhem facilmente aplicativos e serviços com outras pessoas e equipes, sem se preocupar com as diferenças de ambiente.
Em resumo, o Docker é uma plataforma poderosa e cada vez mais popular no mercado de tecnologia, que resolve uma das principais dificuldades do desenvolvimento de software: garantir a compatibilidade e a consistência dos aplicativos em diferentes cenários. Com o Docker, os desenvolvedores podem se concentrar em criar e aprimorar seus aplicativos, sem se preocupar com problemas de implantação e gerenciamento.
Como usar Docker em fullstack ( React + Nodejs)
Inicialmente criaremos uma aplicação simples em React e uma simples em uma API em Nodejs que nos dará um “Hello World!” como resposta.
Para começar, é necessário ter o Node.js instalado na sua máquina. Você pode baixar e instalar a versão mais recente do Node.js no site oficial.
Agora crie uma pasta para o projeto:
mkdir full-stack-docker
Crie uma pasta chamada backend para o projeto e acesse-a pelo terminal. Em seguida, inicialize um projeto Node.js com o comando:
npm init
npm install express
Crie um arquivo index.js e cole esse código.

Este código cria um servidor web utilizando o Express e define uma rota /home que retorna um objeto JSON com a mensagem "Hello World!".
Podemos testar a rota rotando o backend e tentando acessá-lo na extensão do VS Code chamada Thunder Client.
Por fim criamos uma Dockerfile dentro da pasta:
touch Dockerfile

FROM
O comando FROM define a “imagem base” que será usada como ponto de partida para a construção da “imagem docker”. Neste caso, a imagem base é o Node.js na versão 19.0.1.
EXPOSE
O comando EXPOSE define a porta que será exposta pela imagem. Neste caso, a porta 3001 será exposta. Isso significa que a imagem estará pronta para receber conexões na porta 3001.
WORKDIR
O comando WORKDIR define o diretório de trabalho da imagem, ou seja, o diretório onde os comandos subsequentes serão executados. Neste caso, o diretório de trabalho é /backend.
COPY
O comando COPY copia os arquivos package.json e package-lock.json da máquina local para o diretório /backend na imagem. Esses arquivos contêm as informações necessárias para instalar as dependências da aplicação.
RUN
O comando RUN executa o comando npm install no diretório /backend. Isso instala as dependências necessárias para a aplicação funcionar.
COPY
O comando COPY copia todo o conteúdo da máquina local para o diretório /backend na imagem.
CMD
Por fim, o comando CMD define o comando que será executado quando a imagem for iniciada. Neste caso, o comando npm start será executado, o que iniciará a aplicação.
Agora vamos para o frontend, para começar crie uma aplicação em React em um diretório chamado frontend:
npx create-react-app frontend
cd frontend
Substitua o App.js por isso:

Este é um componente de função React que utiliza o hook useState para definir o estado inicial de message como uma string vazia. O hook useEffect é usado para executar uma chamada de API fetch para "http://localhost:3001/home" e atualizar o estado message com a mensagem retornada pelo servidor. O array vazio [] como segundo parâmetro de useEffect garante que a chamada da API seja feita apenas uma vez quando o componente é montado. O restante do código renderiza os componentes.
Por fim fazemos a Dockerfile do Front End.
touch Dockerfile

Nesse Dockerfile começamos definindo a mesma imagem base de antes , depois definimos o diretório de trabalho na imagem e copiamos todo o conteúdo do diretório atual para o diretório de trabalho na imagem. Em seguida, instalamos as dependências da aplicação usando o gerenciador de pacotes npm e definimos o comando padrão que será executado quando o contêiner for iniciado.
Com isso podemos fazer o docker-compose.yml, arquivo que será responsável por resumir o jeito que subimos o servidor, permitindo que usemos somente um comando.
Para isso vá paro o diretório /full-stack-docker e crie o arquivo docker-compose.yml:
touch docker-compose.yml

É um arquivo Docker Compose para um aplicativo web. O arquivo é escrito em formato YAML e contém três seções principais: version, services e networks.
A seção version indica a versão do Docker Compose que será usada para construir e executar o ambiente. No caso deste arquivo, a versão é a 3.9.
A seção services descreve os contêineres que serão criados. Neste exemplo, há dois serviços: frontend e backend. Cada serviço possui seu próprio nome de contêiner, definido pela opção container_name, e é construído a partir de um Dockerfile específico, indicado pela opção build.
Além disso, cada serviço expõe uma porta, definida pela opção ports. A opção working_dir define o diretório de trabalho dentro do contêiner. A opção depends_on indica que o serviço frontend depende do serviço backend. A opção restart define a política de reinicialização do contêiner em caso de falha. A opção networks define a rede em que o contêiner está conectado.
A seção volumes define volumes de dados que podem ser compartilhados entre os contêineres.
A seção networks define as redes que serão criadas para conectar os contêineres. Neste caso, há apenas uma rede, chamada web-net.
Agora que entendemos todos os arquivos podemos rodar a aplicação toda rodando o comando:
docker-compose up -d
Após aplicarmos esse projeto seremos capazes de entender o base do Docker e como ele pode ser útil.

Conclusão
Docker é uma ferramenta essencial para qualquer desenvolvedor Full Stack Web. O Docker permite empacotar, distribuir e executar aplicativos em contêineres, tornando a implantação e o gerenciamento de aplicativos mais fácil e eficiente. Com o Docker, é possível garantir a compatibilidade e a consistência dos aplicativos em diferentes ambientes, o que é uma das principais dificuldades do desenvolvimento de software.
Ao criar um projeto Fullstack Web usando React e Node.js, pude ver a importância do Docker em primeira mão. Com o Docker, pude facilmente empacotar minha aplicação Node.js em um contêiner, permitindo que ela pudesse ser executada em qualquer ambiente sem problemas de compatibilidade.
A construção da imagem Docker foi fácil e rápida, graças às diversas funcionalidades da plataforma, como o Dockerfile, que permitiu especificar todas as dependências do meu projeto. Isso me permitiu criar imagens consistentes e confiáveis que podem ser facilmente compartilhadas com outros desenvolvedores.
Em conclusão, usar o Docker é uma excelente maneira de garantir a consistência e a compatibilidade do seu aplicativo em diferentes ambientes. É uma ferramenta essencial para qualquer desenvolvedor Full Stack Web que deseja criar aplicativos mais eficientes e facilmente compartilháveis.
A Revelo Content Network acolhe todas as raças, etnias, nacionalidades, credos, gêneros, orientações, pontos de vista e ideologias, desde que promovam diversidade, equidade, inclusão e crescimento na carreira dos profissionais de tecnologia.