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:
Navegue até este diretório:
Esse será o diretório raiz do projeto.
Em seguida, crie um package.json
com as dependências do seu projeto:
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 <[email protected]>",
"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:
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:
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
:
Abra o 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="https://www.digitalocean.com/#">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="http://www.digitalocean.com/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="http://www.digitalocean.com/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
:
Adicione o código a seguir, o qual importará o Bootstrap e a folha de estilos personalizada e fornecerá 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="https://www.digitalocean.com/#">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="http://www.digitalocean.com/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 CSS personalizada que você vinculou ao index.html
e ao sharks.html
, criando primeiro uma pasta css
no diretório views
:
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:
Use seu navegador para ir para o endereço http://your_server_ip:8080
ou localhost:8080
, se estiver trabalhando localmente. Você verá a seguinte página inicial:
Clique no botão Get Shark Info. Você verá a seguinte página de informaçõ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:
Adicione o código a seguir ao arquivo:
~/node_project/Dockerfile
FROM node:10-alpine
RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app
WORKDIR /home/node/app
COPY package*.json ./
USER node
RUN npm install
COPY --chown=node:node . .
EXPOSE 8080
CMD [ "node", "app.js" ]
Esse Dockerfile utiliza uma imagem base alpine, assegurando que o usuário node não raiz detenha a propriedade dos arquivos do aplicativo. Por padrão, a imagem Node do Docker inclui o usuário node não raiz.
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:
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
Usando o docker ps
, verifique a lista dos contêineres em execução:
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 inicial do seu aplicativo novamente:
Agora que você criou uma imagem para seu aplicativo, é possível encaminhá-la para o Docker Hub para uso futuro.
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
Acessar 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, usando seu próprio 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 do seu aplicativo; depois, recompile-os.
Primeiro, liste os contêineres em execução:
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
Usar o CONTAINER ID
listada em sua saída interromperá o contêiner do aplicativo em execução. Certifique-se de substituir o ID destacado abaixo pelo seu próprio CONTAINER ID
:
Liste todas as suas imagens com o sinalizador -a
:
Você verá o seguinte resultado com o nome de sua imagem, your_dockerhub_username/nodejs-image-demo
, junto com a imagem node
e 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
Usando o comando abaixo, remova o contêiner suspenso e todas as imagens, incluindo as imagens não utilizadas ou pendentes:
Com todas as suas imagens e contêineres excluídos, agora você poderá extrair a imagem do aplicativo do Docker Hub:
- docker pull your_dockerhub_username/nodejs-image-demo
Liste as suas imagens novamente:
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, você pode recompilar 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:
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
Acesse novamente o http://your_server_ip
ou o localhost
para visualizar seu aplicativo em execução.
Tutoriais relacionados
Aqui estão os links para os guias mais detalhados relacionados a este tutorial:
Você também pode revisar a série mais extensa do artigo intitulado 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.