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:
- Fácil de executar e testar;
- Agnóstico ao meio ambiente;
- Rápido para avaliar modificações;
- 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:
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:
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:
- Desenvolvedor altera arquivos TypeScript;
- Arquivos transcritos transcritos para Javascript;
- 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:
Dockerfile
– um arquivo de recibo que lista como instalar e executar seu aplicativo;.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
afetará o contêiner nodejs-with-mongodb-api-example
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 oMONGO_URL
variável. Substitua oPORT
variável se você deseja executá-lo em uma porta diferente. Observe que o valormongodb
é 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 opwd
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
. osrc
caminho é oWORKDIR
instrução definida emDockerfile
portanto, espelhamos a pasta local no src do contêiner do Docker; -v
– o segundo volume refletirá o volume individual que criamos no contêinernode_modules
pasta;app
– o nome da imagem;-
npm run dev:watch
– este último comando substituirá oCMD
instruções doDockerfile
.
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! 🍻