Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Romildo Junior
Romildo Junior

Posted on • Edited on

     

Dockerizando um projeto Node.js

Um dos princípios para ter um projeto bem estruturado é tornar a configuração inicial tão simples quanto possível. Com menos impedimento para de fato "rodar" o projeto, é possível inserir mais desenvolvedores no fluxo de trabalho de forma acelerada.

Um dos grandes gargalos, sem dúvidas, é montar a infraestrutura necessária, otimizada para o ambiente de desenvolvimento. As práticas e conceitos do mundo DevOps entram para auxiliar e, nesse artigo, vamos abordar docker e conteinerização de um backend feito com Nodejs e mongodb. Além disso, no fim vamos ver uma dica para visualizar melhor os dados.

Primeiro, vamos criar uma aplicação com node. Você pode utilizar algum projeto que já esteja configurado (e, caso o faça, pule pro próximo tópico). Verifique que ele possui um script "start" que possa ser utilizado.

Iniciando o projeto

Utilizando o yarn:

$yarn inityarn init v1.22.4question name(example_docker): question version(1.0.0): question description: A simple backendquestion entry point(index.js): question repository url: question author: jrmmendes <jrmmendes@outlook.com>question license(MIT): question private: success Saved package.jsonDonein22.54s.
Enter fullscreen modeExit fullscreen mode

Instalando pacotes necessários

Vamos instalar oexpress.js (para construir a aplicação) e odotenv (para carregar variáveis de ambiente mais facilmente):

$yarn add express dotenv
Enter fullscreen modeExit fullscreen mode

Numa aplicação real, outros pacotes são de fato importantes, sobre tudo para questões ligadas à segurança de dados. Esse exemplo é apenas ilustrativo.

Além disso, para conexão com o banco de dados, vamos instalar omongoose:

$yarn add mongoose
Enter fullscreen modeExit fullscreen mode

Escrevendo os arquivos da aplicação

Vamos criar oindex.js com o seguinte conteúdo:

constexpress=require('express');constdotenv=require('dotenv');constmongoose=require('mongoose');// Definição da aplicaçãoconstapp=express();dotenv.config({path:'.env'});app.use(express.json());// Configuração do acesso ao banco de dadosmongoose.connect(process.env.MONGO_URI,{useCreateIndex:true,useNewUrlParser:true,useUnifiedTopology:true,});mongoose.connection.once('open',()=>{console.log('Conectado ao banco de dados');});mongoose.connection.on('error',(e)=>{console.log('Error ao tentar conectar-se ao banco de dados');console.error(e);});// Rotas de testeapp.route('/ping').all((req,res)=>{res.status(200).json({data:'PONG!'});});// Inicialização do servidorapp.listen(process.env.PORT||3000,()=>{console.log('Servidor Iniciado');});
Enter fullscreen modeExit fullscreen mode

Vamos também criar o arquivo.env, com as variáveis de ambientePORT eMONGO_URI:

MONGO_URI="mongodb://root:toor@mongo:27017/development-db?authSource=admin"
Enter fullscreen modeExit fullscreen mode

Por fim, vamos adicionar ao arquivopackage.json um scriptstart, para iniciar o projeto. Ele deve estar assim:

{"name":"example_docker","version":"1.0.0","description":"A simple backend","main":"index.js","author":"jrmmendes <jrmmendes@outlook.com>","license":"MIT","dependencies":{"dotenv":"^8.2.0","express":"^4.17.1"}}
Enter fullscreen modeExit fullscreen mode

De modo que vamos editá-lo, adicionando uma chave "scripts":

{"name":"example_docker","version":"1.0.0","description":"A simple backend","scripts":{"start":"node index.js"},"main":"index.js","author":"jrmmendes <jrmmendes@outlook.com>","license":"MIT","dependencies":{"dotenv":"^8.2.0","express":"^4.17.1","mongoose":"^5.9.7"}}
Enter fullscreen modeExit fullscreen mode

Essa é a estrutura que o projeto deve ter no fim:

example_docker├── index.js├── node_modules├── package.json└── yarn.lock
Enter fullscreen modeExit fullscreen mode

Docker

O ponto de partida será criar um arquivo chamadoDockerfile. É nele onde vamos especificar como ocorre o setup da aplicação.

Caso não esteja familiarizado com os conceitos do Docker, imagine que é uma forma de documentar os passos iniciais para instalar dependências, similar a uma script, mas que é executado de forma mais segura e independente do ambiente do desenvolvedor (desde que seja Linux, nesse caso).

Após isso, iremos configurar os outros serviços relacionados à nossa aplicação (como o banco de dados) e a interação entre eles com o Docker Compose. Aqui já podemos notar um benefício bem clássico dessa abordagem: não será necessário instalar nenhum SGBD no sistema operacional, removendo uma possível fonte de problemas de compatibilidade/configuração.

Definição da Aplicação

Vamos criar o arquivoDockerfile. Ele terá a seguinte estrutura:

# Imagem baseFROM node:12.16# Configuração do usuário/permissõesUSER nodeWORKDIR /home/node/# Instalação das dependênciasCOPY package.json .COPY yarn.lock .RUNyarninstall# Copia dos arquivos do projetoCOPY . .# ExecuçãoCMD ["yarn", "start"]
Enter fullscreen modeExit fullscreen mode

Vamos estudar mais a fundo cada parte.

Base

FROM node:12.16
Enter fullscreen modeExit fullscreen mode

No mundo do Docker, existe oDockerHub, que funciona de maneira análoga ao Github, nos fornecendo um lugar para enviar e utilizar partes reutilizáveis. Nesse caso, vamos tirar proveito da existência de imagens já configuradas do node, em específico das versões12.16.x, nos livrando da necessidade de instalar o próprio node e suas ferramentas, como o yarn.

Configuração do usuário/permissões

USER nodeWORKDIR /home/node/
Enter fullscreen modeExit fullscreen mode

Nessa parte, estamos definindo qual usuário será utilizado dentro do contêiner da aplicação. Essa parte é importante para evitar que todos os comandos sejam executados como superusuário (o que, dentre outros impactos, causa um problema de permissões em alguns arquivos, sendo no mínimo inconveniente).

Também alteramos a pasta onde estaremos copiando e executando instruçõesRUN,COPY,ADD,CMD eENTRYPOINT.

Instalação das dependências

COPY package.json .COPY yarn.lock .RUNyarninstall
Enter fullscreen modeExit fullscreen mode

Aqui instalamos os pacotes que a aplicação necessita. É possível substituir essa fase por algo mais complexo como ummultistage build, mas isso é algo que não vamos ver nesse artigo.

Copia dos arquivos do projeto

COPY . .
Enter fullscreen modeExit fullscreen mode

Nessa fase os arquivos que escrevemos (.env,index.js) são copiados para dentro do contêiner. Apenas para ficar claro, estamos copiando da mesma pasta em que o arquivo Dockerfile se encontra para a que definimos com o comandoWORKDIR (/home/node). Vale também lembrar que a segunda se refere ao contêiner, não ao nosso sistema de arquivos normal.

Execução

CMD ["yarn", "start"]
Enter fullscreen modeExit fullscreen mode

Aqui, iniciamos o projeto. Indicamos qual comando deve ser executado após o setup da aplicação.

Serviços e integração

Para definir os outros serviços e conectar todos os contêineres, além de facilitar a execução do projeto, vamos criar o arquivodocker-compose.yml, com o seguinte conteúdo:

version: '3'services:  api:    build:       dockerfile: ./Dockerfile      context: .    volumes:      - .:/home/node      - /home/node/node_modules    ports:      - 3000:3000    command: yarn start    depends_on:       - mongo  mongo-express:    image: mongo-express    ports:      - 8081:8081    environment:      ME_CONFIG_BASICAUTH_USERNAME: mendes      ME_CONFIG_BASICAUTH_PASSWORD: dotmendes      ME_CONFIG_MONGODB_PORT: 27017      ME_CONFIG_MONGODB_ADMINUSERNAME: root      ME_CONFIG_MONGODB_ADMINPASSWORD: toor    depends_on:      - mongo  mongo:    image: mongo    command: [--auth]    environment:      MONGO_INITDB_ROOT_USERNAME: root      MONGO_INITDB_ROOT_PASSWORD: toor    ports:      - 27017:27017    volumes:      - ./volumes/db:/data/db
Enter fullscreen modeExit fullscreen mode

Explicando de maneira rápida, estamos definindo três serviços: api, mongo e mongo-express. O primeiro é construído a partir do Dockerfile que definimos anteriormente; o seguinte, é criado diretamente da imagem do mongo no Dockerhub (similar ao que fizemos com a imagem do node, contudo não modificamos nada).

O terceiro serviço é uma interface que nos permite visualizar o banco de dados e manusear documentos e coleções.

Existe, por fim, a criação de alguns volumes, que serão utilizados para sincronizar modificações entre os arquivos e o que está dentro do contêiner. Isso é especialmente útil durante o desenvolvimento, para que possamos adicionar novas funcionalidades e testá-las sem que precise ser realizado outro processo de build da aplicação.

Conclusão

Após criar todos os arquivos, podemos instalar e executar a aplicação com um simples comando:

$docker-compose up
Enter fullscreen modeExit fullscreen mode

De modo que teremos como acessar a aplicação emhttp://localhost:3000/ping e a interface do mongo-express emhttp://localhost:8081.

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

I'm a Brazilian back-end developer, with some front-end and devops powers. I do not play soccer well :')
  • Location
    Recife, Brazil
  • Education
    Electronic Engineering (incomplete) @ UFPE
  • Work
    Javascript / Typescript Developer
  • Joined

More fromRomildo Junior

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp