// Tutorial //

Como compilar um aplicativo Node.js com o Docker [Início rápido]

Published on April 2, 2020
Default avatar
By Kathleen Juell
Developer and author at DigitalOcean.
Português
Como compilar um aplicativo Node.js com o Docker [Início rápido]

Introdução

Este tutorial traz um passo a passo para ajudá-lo na criação de uma imagem de aplicativo para um website estático que utilize o framework Express e o Bootstrap. Em seguida, você irá compilar um contêiner usando essa imagem, irá enviá-la para o Docker Hub e a utilizará para compilar outro contêiner, demonstrando como é possível recriar e dimensionar o seu aplicativo.

Para obter uma versão mais detalhada deste tutorial, com explicações mais detalhadas de cada passo, consulte o tutorial Como compilar um aplicativo Node.js com o Docker.

Pré-requisitos

Para seguir este tutorial, você vai precisar do seguinte:

  • Um usuário sudo em seu servidor ou em seu ambiente local.
  • O Docker.
  • Node.js e npm.
  • Uma conta do Docker Hub.

Passo 1 — Instalando as dependências do seu aplicativo

Primeiro, crie um diretório para seu projeto em seu diretório home do usuário não raiz:

  1. mkdir node_project

Navegue até este diretório:

  1. cd node_project

Esse é o diretório raiz do projeto.

Em seguida, crie um package.json com as dependências do seu projeto:

  1. nano package.json

Adicione as seguintes informações sobre o projeto ao arquivo; certifique-se de substituir as informações do autor pelo seu nome e detalhes de contato:

~/node_project/package.json
{
  "name": "nodejs-image-demo",
  "version": "1.0.0",
  "description": "nodejs image demo",
  "author": "Sammy the Shark <sammy@example.com>",
  "license": "MIT",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "nodejs",
    "bootstrap",
    "express"
  ],
  "dependencies": {
    "express": "^4.16.4"
  }
}

Instale as dependências do seu projeto:

  1. npm install

Passo 2 — Criando os arquivos do aplicativo

Criaremos um site que fornece informações aos usuários sobre tubarões.

Abra o app.js no diretório principal do projeto para definir as rotas do projeto:

  1. nano app.js

Adicione o conteúdo a seguir ao arquivo para criar o aplicativo Express e os objetos Router, definir o diretório base, a porta e o host como variáveis, definir as rotas e, em seguida, montar o middleware router junto com os ativos estáticos do aplicativo:

~/node_project/app.js
var express = require("express");
var app = express();
var router = express.Router();

var path = __dirname + '/views/';

// Constants
const PORT = 8080;
const HOST = '0.0.0.0';

router.use(function (req,res,next) {
  console.log("/" + req.method);
  next();
});

router.get("/",function(req,res){
  res.sendFile(path + "index.html");
});

router.get("/sharks",function(req,res){
  res.sendFile(path + "sharks.html");
});

app.use(express.static(path));
app.use("/", router);

app.listen(8080, function () {
  console.log('Example app listening on port 8080!')
})

Em seguida, vamos adicionar conteúdo estático ao aplicativo. Crie o diretório views:

  1. mkdir views

Abra o index.html:

  1. nano views/index.html

Adicione o código a seguir ao arquivo, que importará o Boostrap e criará um componente jumbotron com um link para a página de informações mais detalhadas do sharks.html:

~/node_project/views/index.html
<!DOCTYPE html>
<html lang="en">
   <head>
      <title>About Sharks</title>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
      <link href="css/styles.css" rel="stylesheet">
      <link href='https://fonts.googleapis.com/css?family=Merriweather:400,700' rel='stylesheet' type='text/css'>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
   </head>
   <body>
      <nav class="navbar navbar-inverse navbar-static-top">
         <div class="container">
            <div class="navbar-header">
               <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
               <span class="sr-only">Toggle navigation</span>
               <span class="icon-bar"></span>
               <span class="icon-bar"></span>
               <span class="icon-bar"></span>
               </button>
               <a class="navbar-brand" href="#">Everything Sharks</a>
            </div>
            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
               <ul class="nav navbar-nav mr-auto">
                  <li class="active"><a href="/">Home</a></li>
                  <li><a href="/sharks">Sharks</a></li>
               </ul>
            </div>
         </div>
      </nav>
      <div class="jumbotron">
         <div class="container">
            <h1>Want to Learn About Sharks?</h1>
            <p>Are you ready to learn about sharks?</p>
            <br>
            <p><a class="btn btn-primary btn-lg" href="/sharks" role="button">Get Shark Info</a></p>
         </div>
      </div>
      <div class="container">
         <div class="row">
            <div class="col-md-6">
               <h3>Not all sharks are alike</h3>
               <p>Though some are dangerous, sharks generally do not attack humans. Out of the 500 species known to researchers, only 30 have been known to attack humans.</p>
            </div>
            <div class="col-md-6">
               <h3>Sharks are ancient</h3>
               <p>There is evidence to suggest that sharks lived up to 400 million years ago.</p>
            </div>
         </div>
      </div>
   </body>
</html>

Em seguida, abra um arquivo chamado sharks.html:

  1. nano views/sharks.html

Adicione o código a seguir, o qual importa o Bootstrap e a folha de estilos personalizada e fornece informações detalhadas sobre certos tubarões:

~/node_project/views/sharks.html
<!DOCTYPE html>
<html lang="en">
   <head>
      <title>About Sharks</title>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
      <link href="css/styles.css" rel="stylesheet">
      <link href='https://fonts.googleapis.com/css?family=Merriweather:400,700' rel='stylesheet' type='text/css'>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
   </head>
   <nav class="navbar navbar-inverse navbar-static-top">
      <div class="container">
         <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">Everything Sharks</a>
         </div>
         <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav mr-auto">
               <li><a href="/">Home</a></li>
               <li class="active"><a href="/sharks">Sharks</a></li>
            </ul>
         </div>
      </div>
   </nav>
   <div class="jumbotron text-center">
      <h1>Shark Info</h1>
   </div>
   <div class="container">
      <div class="row">
         <div class="col-md-6">
            <p>
            <div class="caption">Some sharks are known to be dangerous to humans, though many more are not. The sawshark, for example, is not considered a threat to humans.</div>
            <img src="https://assets.digitalocean.com/articles/docker_node_image/sawshark.jpg" alt="Sawshark">
            </p>
         </div>
         <div class="col-md-6">
            <p>
            <div class="caption">Other sharks are known to be friendly and welcoming!</div>
            <img src="https://assets.digitalocean.com/articles/docker_node_image/sammy.png" alt="Sammy the Shark">
            </p>
         </div>
      </div>
    </div>
   </body>
</html>

Por fim, crie a folha de estilos personalizada CSS que você vinculou ao index.html e ao sharks.html, criando primeiro uma pasta css no diretório views:

  1. mkdir views/css

Abra a folha de estilos e adicione o código a seguir, o qual definirá a cor e a fonte desejadas para nossas páginas:

~/node_project/views/css/styles.css
.navbar {
        margin-bottom: 0;
}

body {
        background: #020A1B;
        color: #ffffff;
        font-family: 'Merriweather', sans-serif;
}
h1,
h2 {
        font-weight: bold;
}
p {
        font-size: 16px;
        color: #ffffff;
}


.jumbotron {
        background: #0048CD;
        color: white;
        text-align: center;
}
.jumbotron p {
        color: white;
        font-size: 26px;
}

.btn-primary {
        color: #fff;
        text-color: #000000;
        border-color: white;
        margin-bottom: 5px;
}

img, video, audio {
        margin-top: 20px;
        max-width: 80%;
}

div.caption: {
        float: left;
        clear: both;
}

Inicie o aplicativo:

  1. npm start

Use seu navegador para ir para o endereço http://your_server_ip:8080 ou localhost:8080, caso esteja trabalhando localmente. Você verá a seguinte página de destino:

Página de destino do aplicativo

Clique no botão Get Shark Info. Você verá a seguinte página de informações:

Página de informações sobre tubarões

Agora, você tem um aplicativo em funcionamento. Quando estiver pronto, saia do servidor digitando CTRL+C.

Passo 3 — Escrevendo o Dockerfile

No diretório raiz do seu projeto, crie o Dockerfile:

  1. nano Dockerfile

Adicione o código a seguir ao arquivo:

~/node_project/Dockerfile

FROM node:10

RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app

WORKDIR /home/node/app

COPY package*.json ./

RUN npm install

COPY . .

COPY --chown=node:node . .

USER node

EXPOSE 8080

CMD [ "npm", "start" ]

Esse Dockerfile utiliza uma imagem base alpine e garante que os arquivos do aplicativo sejam propriedade do usuário node não raiz que, por padrão, é fornecida pela Imagem Node do Docker.

Em seguida, adicione seus módulos node locais, os registros npm, o Dockerfile e o .dockerignore ao seu arquivo .dockerignore:

~/node_project/.dockerignore
node_modules
npm-debug.log
Dockerfile
.dockerignore

Compile a imagem do aplicativo usando o comando docker build:

  1. docker build -t your_dockerhub_username/nodejs-image-demo .

O . especifica que o contexto de compilação é o diretório atual.

Verifique suas imagens:

  1. docker images

Você verá o seguinte resultado:

Output
REPOSITORY TAG IMAGE ID CREATED SIZE your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 8 seconds ago 895MB node 10 f09e7c96b6de 17 hours ago 893MB

Execute o comando a seguir para compilar um contêiner usando esta imagem:

  1. docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo

Verifique a lista dos contêineres em execução com o docker ps:

  1. docker ps

Você verá o seguinte resultado:

Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e50ad27074a7 your_dockerhub_username/nodejs-image-demo "npm start" 8 seconds ago Up 7 seconds 0.0.0.0:80->8080/tcp nodejs-image-demo

Com seu contêiner em execução, agora você pode acessar o seu aplicativo, utilizando seu navegador para acessar o endereço http://your_server_ip ou o localhost. Você verá a página principal do seu aplicativo novamente:

Página de destino do aplicativo

Agora que você criou uma imagem para seu aplicativo, é possível encaminhá-la para o Docker Hub para uso futuro.

Passo 4 — Utilizando um repositório para trabalhar com imagens

O primeiro passo para enviar a imagem é fazer o login na sua conta do Docker Hub:

  1. docker login -u your_dockerhub_username -p your_dockerhub_password

Acessando dessa maneira criará um arquivo ~/.docker/config.json no diretório home do seu usuário com as suas credenciais do Docker Hub.

Envie sua imagem com o uso do seu nome de usuário no lugar de your_dockerhub_username:

  1. docker push your_dockerhub_username/nodejs-image-demo

Se quiser, teste o utilitário do registro de imagens, destruindo o contâiner e a imagem atuais de seu aplicativo e compilando-as novamente.

Primeiro, liste os contêineres em execução:

  1. docker ps

Você verá o seguinte resultado:

Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e50ad27074a7 your_dockerhub_username/nodejs-image-demo "npm start" 3 minutes ago Up 3 minutes 0.0.0.0:80->8080/tcp nodejs-image-demo

Usando a CONTAINER ID listada em sua saída, interrompa o contêiner do aplicativo em execução. Certifique-se de substituir a ID destacada abaixo pela seu própria CONTAINER ID:

  1. docker stop e50ad27074a7

Liste todas as suas imagens com o sinalizador -a:

  1. docker images -a

Você verá a seguinte saída com o nome da sua imagem, your_dockerhub_username/nodejs-image-demo, junto com a imagem node e as outras imagens da sua compilação:

Output
REPOSITORY TAG IMAGE ID CREATED SIZE your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 7 minutes ago 895MB <none> <none> e039d1b9a6a0 7 minutes ago 895MB <none> <none> dfa98908c5d1 7 minutes ago 895MB <none> <none> b9a714435a86 7 minutes ago 895MB <none> <none> 51de3ed7e944 7 minutes ago 895MB <none> <none> 5228d6c3b480 7 minutes ago 895MB <none> <none> 833b622e5492 8 minutes ago 893MB <none> <none> 5c47cc4725f1 8 minutes ago 893MB <none> <none> 5386324d89fb 8 minutes ago 893MB <none> <none> 631661025e2d 8 minutes ago 893MB node 10 f09e7c96b6de 17 hours ago 893MB

Remova o contêiner interrompido e todas as imagens, incluindo as imagens não utilizadas ou pendentes, com o seguinte comando:

  1. docker system prune -a

Com todas as suas imagens e contêineres excluídos, agora você poderá remover a imagem do aplicativo do Docker Hub:

  1. docker pull your_dockerhub_username/nodejs-image-demo

Liste as suas imagens novamente:

  1. docker images

Você verá a imagem do seu aplicativo:

Output
REPOSITORY TAG IMAGE ID CREATED SIZE your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 11 minutes ago 895MB

Agora, é possível reconstruir seu contêiner usando o comando do Passo 3:

  1. docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo

Liste seus contêineres em execução:

  1. docker ps
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f6bc2f50dff6 your_dockerhub_username/nodejs-image-demo "npm start" 4 seconds ago Up 3 seconds 0.0.0.0:80->8080/tcp nodejs-image-demo

Visite novamente http://your_server_ip ou localhost para visualizar seu aplicativo em execução.

Tutoriais relacionados

Aqui estão os link para os guias mais detalhados relacionados a este tutorial:

Você também pode revisar a série mais extensa do artigo em De contêineres a Kubernetes com o Node.js, a partir da qual este tutorial foi adaptado.

Além disso, consulte nossa biblioteca completa dos Recursos do Docker para obter mais detalhes sobre o Docker.


Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.

Sign up
About the authors
Default avatar
Developer and author at DigitalOcean.

Still looking for an answer?

Was this helpful?
Leave a comment

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!