Tutorial

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

Node.jsDockerQuickstart

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:

  • mkdir node_project

Navegue até este diretório:

  • cd node_project

Esse é o diretório raiz do projeto.

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

  • 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:

  • 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:

  • 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:

  • mkdir views

Abra o index.html:

  • 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:

  • 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:

  • 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:

  • 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:

  • 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:

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

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

Verifique suas imagens:

  • 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:

  • 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:

  • 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:

  • 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:

  • 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:

  • 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:

  • docker stop e50ad27074a7

Liste todas as suas imagens com o sinalizador -a:

  • 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:

  • 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:

  • docker pull your_dockerhub_username/nodejs-image-demo

Liste as suas imagens novamente:

  • 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:

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

Liste seus contêineres em execução:

  • 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.

0 Comments

Creative Commons License