Tutorial

Cómo crear una aplicación de Node.js con Docker [Quickstart]

Published on March 5, 2020
Español
Cómo crear una aplicación de Node.js con Docker [Quickstart]

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 sudo en 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.

  1. mkdir node_project

Navegue a este directorio:

  1. cd node_project

Este será el directorio root del proyecto.

A continuación, cree un package.json con las dependencias de su proyecto:

  1. 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:

~/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:

  1. 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:

  1. 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:

~/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:

  1. mkdir views

Abra index.html:

  1. 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:

~/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:

  1. 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:

~/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 ú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:

  1. 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:

~/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:

  1. 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:

Página de inicio de la aplicación

Haga clic en el botón Get Shark Info. Visualizará la siguiente página de información:

Página de información de tiburones

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:

  1. nano Dockerfile

Añada el siguiente código al archivo:

~/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:

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

Compile la imagen de la aplicación usando el comando docker build:

  1. 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:

  1. docker images

Verá lo siguiente:

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:

  1. 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:

  1. docker ps

Verá lo siguiente:

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:

Página de destino de la aplicación

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:

  1. 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:

  1. 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:

  1. docker ps

Verá la salida siguiente:

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:

  1. docker stop e50ad27074a7

Enumere todas sus imágenes con la marca -a:

  1. 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:

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:

  1. docker system prune -a

Con todas sus imágenes y contenedores eliminados, ahora, puede extraer la imagen de la aplicación de Docker Hub:

  1. docker pull your_dockerhub_username/nodejs-image-demo

Enumere sus imágenes una vez más:

  1. docker images

Visualizará la imagen de su aplicación:

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:

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

Enumere sus contenedores en ejecución:

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

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors

Still looking for an answer?

Ask a questionSearch for more help

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!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Featured on Community

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more