Table of Contents
Introducción
En este tutorial, se explicará la manera de crear una imagen de una aplicación para un sitio web estático que utiliza el marco Express y Bootstrap. Luego, creará un contenedor usando esa imagen, la enviará a Docker Hub y la usará para crear otro contenedor, con lo cual se demostrará la forma de recrear y escalar su aplicación.
Para acceder a una versión más detallada de este tutorial, con explicaciones más exhaustivas de cada paso, consulte Cómo crear una aplicación de Node.js con Docker.
Requisitos previos
Para este tutorial, necesitará lo siguiente:
- Un usuario
sudoen su servidor o en su entorno local.
- Docker.
- Node.js y
npm.
- Una cuenta de Docker Hub.
Paso 1: instalación de las dependencias de su aplicación
Primero, cree un directorio para su proyecto en el directorio principal de su usuario no root.
mkdir <^>node_project<^>
Navegue a este directorio:
cd <^>node_project<^>
Este será el directorio root del proyecto.
A continuación, cree un package.json con las dependencias de su proyecto:
nano package.json
Añada la siguiente información sobre el proyecto al archivo; asegúrese de sustituir la información del autor por su nombre y sus datos de contacto:
[label ~/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 las depdendencias de su proyecto:
npm install
Paso 2: creación de los archivos de la aplicación
Crearemos una página web que ofrece información a los usuarios sobre los tiburones.
Abra app.js en el directorio principal del proyecto para definir las rutas de este:
nano app.js
Añada el siguiente contenido al archivo para crear la aplicación de Express y los objetos de Router, definir el directorio base, el puerto y el host como variables, establezca las rutas y montar el middleware router junto con los activos estáticos de la aplicación:
[label ~/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!')
})
A continuación, añadamos algunos contenidos estáticos a la aplicación. Cree el directorio views:
mkdir views
Abra index.html:
nano views/index.html
Añada el siguiente código al archivo, que importará Bootstrap y creará un componente jumbotron con un enlace a la página de información más detallada sharks.html:
[label ~/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>
A continuación, abra un archivo llamado sharks.html:
nano views/sharks.html
Añada el siguiente código, que importa Bootstrap y la hoja de estilo personalizado, y ofrece a los usuarios información detallada sobre ciertos tiburones:
[label ~/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://www.progressiverobot.com/images/how-to-build-a-node-js-application-with-docker-quickstart-es-section-1.png" 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://www.progressiverobot.com/images/how-to-build-a-node-js-application-with-docker-quickstart-es-section-1.png" alt="Sammy the Shark">
</p>
</div>
</div>
</div>
</body>
</html>
Por último, cree la hoja de estilo CSS personalizado a la que se vinculó en index.html y sharks.html creando, primero, una carpeta css en el directorio views:
mkdir views/css
Abra la hoja de estilo y añada el siguiente código, que establecerá el color y la fuente deseados para nuestras páginas:
[label ~/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 la aplicación:
npm start
Visite en su navegador http://<^>your_server_ip<^>:8080 o localhost:8080 si trabaja a nivel local. Visualizará la siguiente página de destino:
Haga clic en el botón Get Shark Info. Visualizará la siguiente página de información:
Ahora, tiene una aplicación lista y en funcionamiento. Cuando esté listo, salga del servidor al pulsar CTRL+C.
Paso 3: escribir el Dockerfile
En el directorio root de su proyecto, cree el Dockerfile:
nano Dockerfile
Añada el siguiente código al archivo:
[label ~/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" ]
Este Dockerfile usa una imagen alpine base y garantiza que los archivos de la aplicación pertenezcan al usuario node no root proporcionado por defecto por la imagen Docker Node.
A continuación, añada sus módulos de nodo local, sus registros npm, su Dockerfile y .dockerignore a su archivo .dockerignore:
[label ~/node_project/.dockerignore]
node_modules
npm-debug.log
Dockerfile
.dockerignore
Compile la imagen de la aplicación usando el comando docker build:
docker build -t <^>your_dockerhub_username<^>/<^>nodejs-image-demo<^> .
El . especifica que el contexto de compilación es el directorio actual.
Verifique sus imágenes:
docker images
Verá lo siguiente:
[secondary_label 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
Ejecute el siguiente comando para crear un contenedor usando esta imagen:
docker run --name <^>nodejs-image-demo<^> -p <^>80<^>:8080 -d <^>your_dockerhub_username<^>/<^>nodejs-image-demo<^>
Inspeccione la lista de sus contenedores en ejecución con docker ps:
docker ps
Verá lo siguiente:
[secondary_label 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
Con el contenedor en ejecución, podrá visitar su aplicación dirigiéndose a la dirección http://<^>your_server_ip<^> o a localhost en su navegador. Visualizará la página de inicio de su aplicación una vez más:
Ahora que creó una imagen para su aplicación, puede insertarla en Docker Hub para su uso futuro.
Paso 4: utilizar un repositorio para trabajar con imágenes
El primer paso para forzar la imagen es iniciar sesión en su cuenta de Docker Hub:
docker login -u <^>your_dockerhub_username<^> -p <^>your_dockerhub_password<^>
Iniciar sesión de esta manera creará un archivo ~/.docker/config.json en el directorio principal de su usuario con sus credenciales de Docker Hub.
Fuerce su imagen usando su propio nombre de usuario en lugar de <^>your_dockerhub_username<^>:
docker push <^>your_dockerhub_username<^>/<^>nodejs-image-demo<^>
Si lo desea, puede probar la utilidad del registro de la imagen destruyendo el contenedor y la imagen de su aplicación actual, y volviendo a compilarlos.
Primero, enumere sus contenedores en ejecución:
docker ps
Verá la salida siguiente:
[secondary_label 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
Mediante CONTAINER ID, enumerada en su salida, detenga la ejecución del contenedor de la aplicación. Asegúrese de sustituir la ID resaltada debajo por su propia CONTAINER ID:
docker stop <^>e50ad27074a7<^>
Enumere todas sus imágenes con la marca -a:
docker images -a
Visualizará el siguiente resultado con el nombre de su imagen, <^>your_dockerhub_username<^>/<^>nodejs-image-demo<^>, junto con la imagen node y las demás imágenes de su compilación:
[secondary_label 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
Elimine el contenedor detenido y todas las imágenes, incluso las no utilizadas o pendientes, con el siguiente comando:
docker system prune -a
Con todas sus imágenes y contenedores eliminados, ahora, puede extraer la imagen de la aplicación de Docker Hub:
docker pull <^>your_dockerhub_username<^>/<^>nodejs-image-demo<^>
Enumere sus imágenes una vez más:
docker images
Visualizará la imagen de su aplicación:
[secondary_label Output]
REPOSITORY TAG IMAGE ID CREATED SIZE
<^>your_dockerhub_username<^>/<^>nodejs-image-demo<^> latest 1c723fb2ef12 11 minutes ago 895MB
Ahora, puede volver a compilar su contenedor usando el comando que se indica en el Paso 3:
docker run --name <^>nodejs-image-demo<^> -p <^>80<^>:8080 -d <^>your_dockerhub_username<^>/<^>nodejs-image-demo<^>
Enumere sus contenedores en ejecución:
docker ps
[secondary_label 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 http://<^>your_server_ip<^> o localhost una vez más para ver su aplicación en ejecución.
Tutoriales relacionados
A continuación, se ofrecen los enlaces a más guías detalladas relacionadas con este tutorial:
También puede consultar la serie más extensa Transición de contenedores a Kubernetes con Node.js, de cuya adaptación derivó este tutorial.
A su vez, consulte nuestra biblioteca completa de recursos de Docker para obtener más información sobre Docker.