Neste artigo, nosso objetivo é abordar essa mentalidade, demonstrando como configurações simples podem resultar em muitos benefícios, como um ambiente confiável sobre ambientes de produção e desenvolvimento.

Até o final deste post, você terá aprendido como:

  • Converta um aplicativo herdado para execução em um contêiner do Docker;
  • Habilitar o cache de dependência nos módulos Node.js.
  • Ative o recarregamento ao vivo usando volumes de docker;
  • Agregue todos os serviços na janela de encaixe-composição.

Exigências

Nas próximas etapas, você clonará um projeto existente para executar todos os exemplos neste artigo. Antes de começar a codificar, verifique se você possui as seguintes ferramentas instaladas em sua máquina:

Introdução

Cada vez mais tecnologias de ponta estão sendo lançadas na Internet. Eles são estáveis ​​e divertidos de desenvolver e liberar, mas não são previsíveis quando se trabalha em ambientes diferentes. Portanto, os desenvolvedores criaram o Docker para ajudar a reduzir as chances de possíveis erros.

O Docker é uma das minhas ferramentas favoritas, que eu trabalho diariamente em aplicativos de desktop, Web e IoT. Ele me deu o poder de não apenas mover aplicativos por diferentes ambientes, mas também de manter o ambiente local o mais limpo possível.

Para os desenvolvedores que trabalham com tecnologias de ponta, estão sempre trabalhando com algo novo. Mas e os nossos aplicativos herdados? Devemos apenas reescrever tudo com novas tecnologias? Eu sei que isso não é tão simples quanto parece. Devemos trabalhar em coisas novas, mas também fazer melhorias nos aplicativos existentes.

Digamos que você decidiu mudar dos servidores Windows para servidores Unix. Como você faria? Você conhece todas as dependências que seu aplicativo precisa para funcionar?

Como deve ser um ambiente de desenvolvimento?

Os desenvolvedores sempre tentaram ser mais produtivos adicionando plugins, clichês e bases de código em seus editores / IDEs / terminais. O melhor ambiente na minha opinião deve ser:

  1. Fácil de executar e testar;
  2. Agnóstico ao meio ambiente;
  3. Rápido para avaliar modificações;
  4. Fácil de replicar em qualquer máquina.

Seguindo esses princípios, configuraremos um aplicativo nas próximas seções deste artigo. Além disso, se você nunca ouviu falar sobre recarga ao vivo (ou recarga quente), é um recurso que procura por alterações no seu código e reinicia o servidor, se necessário. Portanto, você não precisa ir e voltar, reiniciar seu aplicativo ou mesmo reconstruir o sistema.

Começando

Primeiro, você precisa ter uma pasta vazia chamada post-docker-livereload que você usará como um espaço de trabalho. Vou ao Repositório do Github e clone-o na sua pasta post-docker-live-reload.

Em segundo lugar, vamos analisar o que o aplicativo requer. Se você der uma olhada no arquivo README.md, existem algumas instruções que demonstram como executar este aplicativo, conforme mostrado na imagem abaixo:

Screen Shot 2020 06 24 at 18.10.43 1

Requer o Node.js. versão 10 ou superior e o MongoDB. Em vez de instalar o MongoDB em sua máquina de ambiente local, você o instalará usando o Docker. Você também o expõe no localhost: 27017 para que os aplicativos que não estão em execução no Docker possam acessá-lo sem conhecer o endereço IP interno do Docker.

Copie o comando abaixo e cole-o no seu terminal:

docker run --name mongodb -p 27017:27017 -d mongo:4

Usando o comando acima, ele fará o download e executará o MongoDB instância. Observe que, se você já tiver uma instância com esse nome, ocorrerá um erro sobre o nome inválido. Se você vir o erro, execute docker rm mongodb e removerá qualquer instância anterior para que você possa executar o comando docker run novamente.

Cavando no aplicativo

O arquivo README.md diz que você precisa de uma instância do MongoDB em execução antes de iniciar o aplicativo, juntamente com o Node.js. Se você tiver o Node.js instalado, acesse o nodejs-with-mongodb-api-example pasta e execute os seguintes comandos:

npm i npm run build npm start

Depois de executar esses comandos, você pode acessar um navegador em http: // localhost: 3000 e veja o aplicativo em execução, como mostra a imagem abaixo:

01 start

Lembre-se de que o aplicativo já possui um comando para ativar a atualização ao vivo, que é npm run dev:watch. O pipeline deve refletir as seguintes etapas:

  1. Desenvolvedor altera arquivos TypeScript;
  2. Arquivos transcritos transcritos para Javascript;
  3. O servidor percebe alterações no Javascript e reinicia o servidor Node.js.

Portanto, o espelhamento de arquivos nos contêineres do Docker refletirá todas as alterações no contêiner. o npm run build:watch do aplicativo capturará as alterações e gerará arquivos de saída na lib pasta para que o npm run dev:run reiniciará o servidor toda vez que for acionado.

Dockerizing aplicativos

Se o Docker é um mundo completamente novo para você, não tenha medo! Você irá configurá-lo do zero. Você precisará criar alguns arquivos para iniciar:

  1. Dockerfile – um arquivo de recibo que lista como instalar e executar seu aplicativo;
  2. .dockerignore – um arquivo que lista quais arquivos não serão incluídos na instância do contêiner do Docker.

Criando o Dockerfile

O Dockerfile é o conceito chave aqui. Lá você especifica as etapas e dependências para preparar e executar o aplicativo. Enquanto você ler o arquivo README.md, será fácil implementar o arquivo de recebimento.

Vou colocar o arquivo inteiro abaixo e cavar depois. Na tua nodejs-with-mongodb-api-example pasta criar um Dockerfile e cole o código abaixo:

FROM node:14-alpineWORKDIR /srcADD package.json /src RUN npm i --silentADD . /src RUN npm run build CMD npm start

O que está acontecendo lá?

  • Na linha 1 – utiliza como base de imagem o Node.js 14 – versão alpina;
  • Das linhas 2 a 4 – copia e instala dependências do Node.js. do host para o contêiner. Observe que a ordem é importante. Adicionar package.json à pasta src antes de restaurar as dependências armazenará em cache e impedirá a instalação de pacotes toda vez que você precisar criar sua imagem;
  • Das linhas 6 a 7 – Executa comandos para o processo de compilação e, em seguida, para iniciar o programa conforme mencionado no arquivo README.md.

Ignorando arquivos desnecessários com .dockerignore

Além disso, estou trabalhando em um sistema baseado em OSX e o contêiner do Docker será executado em um sistema baseado no Linux Alpine. Quando você executa o npm install ele restaurará dependências para ambientes específicos.

Agora você criará um arquivo para ignorar o código gerado da sua máquina local, como node_modules e lib. Portanto, quando você copia todos os arquivos do diretório atual para o contêiner, ele não obtém versões de pacotes inválidas.

No nodejs-with-mongodb-api-example pasta criar um .dockerignore e cole o código abaixo:

node_modules/lib/

Construindo a imagem da janela de encaixe

Eu prefiro executar este aplicativo a partir do rootFolder. Volte para o post-docker-live-reload pasta e execute os seguintes comandos para preparar uma imagem para uso posterior:

docker build -t app nodejs-with-mongodb-api-example

Observe que o comando acima usa o -t para indicar o nome da imagem e, logo em seguida, a pasta que contém o Dockerfile Arquivo.

Trabalhando com volumes

Antes de executar o aplicativo, vamos fazer alguns hacks para melhorar nossa experiência nos contêineres do Docker.

Os volumes do Docker são um recurso para espelhar arquivos através da máquina local e do ambiente do Docker. Você também pode compartilhar volumes em contêineres e reutilizá-los para armazenar em cache dependências.

Seu objetivo é assistir a quaisquer alterações nos locais .ts arquivos e espelhar essas alterações no contêiner. Mesmo que os arquivos e os node_modules pasta estão no mesmo caminho.

Você se lembra quando eu disse que as dependências em cada sistema operacional seriam diferentes? Para garantir que nosso ambiente local não afete o ambiente do Docker ao espelhar arquivos, isolaremos o contêiner node_modules pasta em um volume distinto.

Consequentemente, ao criar o node_modules pasta no contêiner, ele não criará a pasta no ambiente da máquina local. Execute o comando abaixo no seu terminal para criá-lo:

docker volume create --name nodemodules

Executando e ativando o recarregamento ao vivo

Como você sabe, o npm run dev:watch especificado no arquivo README.md mostra como ativar o recarregamento ao vivo. O problema é que você está codificando em uma máquina local e ela deve refletir diretamente seu contêiner.

Ao executar os seguintes comandos, você vinculará seu ambiente local ao contêiner do Docker para que qualquer alteração no nodejs-with-mongodb-api-example afetará o contêiner src pasta.

docker run     --name app     --link mongodb     -e MONGO_URL=mongodb     -e PORT=4000     -p 4000:4000     -v `pwd`/nodejs-with-mongodb-api-example:/src     -v nodemodules:/src/node_modules     app npm run dev:watch

Vamos nos aprofundar no que está acontecendo lá:

  • --link está dando permissão ao aplicativo para acessar a instância do MongoDB;
  • -e – são as variáveis ​​de ambiente. Conforme mencionado no arquivo README.md você pode especificar a cadeia de conexão do MongoDB à qual deseja se conectar substituindo o MONGO_URL variável. Substitua o PORT variável se você deseja executá-lo em uma porta diferente. Observe que o valor mongodb é o mesmo nome que usamos para criar nossa instância do MongoDB nas seções anteriores. Esse valor também é um alias para o IP da instância interna do MongoDB;
  • -v – mapeia o diretório atual para o contêiner do Docker usando um volume virtual. Usando o pwd comando, você pode obter o caminho absoluto para o diretório de trabalho atual e a pasta que deseja espelhar no contêiner do Docker. Tem o :/src. o src caminho é o WORKDIR instrução definida em Dockerfile portanto, espelhamos a pasta local no src do contêiner do Docker;
  • -v – o segundo volume refletirá o volume individual que criamos no contêiner node_modules pasta;
  • app – o nome da imagem;
  • npm run dev:watch – este último comando substituirá o CMD instruções do Dockerfile.

Após executar o comando abaixo, você pode acionar o navegador após alterar o local Index.ts arquivo para ver os resultados. O vídeo abaixo demonstra essas etapas na prática.

Empacotando

Você sabe que trabalhar com comandos shell funciona. Mas não é tão comum usá-los aqui e não é produtivo para executar todos esses comandos, criar imagens e gerenciar instâncias manualmente. Então componha!

A composição do Docker é uma maneira de simplificar a agregação e vinculação de serviços. Você pode especificar os bancos de dados, logs, aplicativos, volumes, redes e assim por diante.

Primeiro, você precisa remover todas as instâncias ativas para evitar conflitos nas portas expostas. Execute os seguintes comandos no seu terminal para remover volumes, serviços e contêineres:

docker rm app docker volume rm nodemodulesdocker stop $(docker ps -aq)docker rm $(docker ps -aq)

O arquivo docker-compose

Crie um docker-compose.yml arquivo no seu post-docker-livereload pasta usando os dados abaixo:

version: '3'services:    mongodb:        image: mongo:4        ports:            - 27017:27017    app:        build: nodejs-with-mongodb-api-example        command: npm run dev:watch        ports:            - 4000:4000        environment:             MONGO_URL: mongodb            PORT: 4000        volumes:            - ./nodejs-with-mongodb-api-example:/src/            - nodemodules:/src/node_modules        links:            - mongodb        depends_on:             - mongodbvolumes:    nodemodules: {}

O arquivo acima especifica recursos por seções. Observe que você tem links e depends_on seções lá. O campo links é o mesmo sinalizador que você usou no seu comando shell. O Depend_on garantirá que o MongoDB seja uma dependência para a execução do seu aplicativo. Ele executará o MongoDB antes do seu aplicativo como mágica!

Voltando ao seu terminal, para iniciar todos os serviços e criar a imagem do Docker e criar volumes e serviços de link, execute o seguinte comando:

docker-compose up --build

Se você precisar remover todos os serviços criados anteriormente por esse Dockerfile você também pode correr docker-compose down.

Docker é seu amigo!

Está certo, meu amigo. O Docker pode ajudar a evitar muitos erros possíveis antes que eles aconteçam. Você pode usá-lo para aplicativos front-end e back-end. Mesmo para a IoT quando você precisa controlar o hardware, pode especificar políticas para usá-lo.

Como próximas etapas, recomendo que você dê uma olhada em orquestradores de contêineres, como o Kubernetes e o Docker swarm. Eles podem melhorar ainda mais seus aplicativos existentes e ajudá-lo a passar para o próximo nível.

Obrigado pela leitura

Eu realmente aprecio o tempo que passamos juntos. Espero que este conteúdo seja mais do que apenas texto. Espero que ajude a torná-lo um pensador melhor e também um programador melhor. Siga-me Twitter e confira meu blog pessoal onde eu compartilho todo o meu conteúdo valioso.

Até mais! 🍻