Introducción

La plataforma Docker permite a los desarrolladores empaquetar y ejecutar aplicaciones como contenedores. Un contenedor es un proceso aislado que se ejecuta en un sistema operativo compartido, ofreciendo una alternativa más ligera para máquinas virtuales. Si bien los contenedores no son nuevos, ofrecen beneficios, como aislamiento de procesos y estandarización de entornos, que están creciendo en importancia a medida que más desarrolladores utilizan arquitecturas de aplicaciones distribuidas.

Cuando se construye y escala una aplicación con Docker, el punto de partida suele ser la creación de una imagen para su aplicación, que, luego, puede ejecutar en un contenedor. La imagen incluye el código, las bibliotecas, los archivos de configuración, las variables del entorno y el tiempo de ejecución de su aplicación. Usar una imagen asegura que el entorno de su contenedor esté estandarizado y que solo contenga lo necesario para crear y ejecutar su aplicación.

En este tutorial, creará la imagen de una aplicación para un sitio web estático que utiliza el marco de trabajo Express y Bootstrap. Luego, creará un contenedor usando esa imagen y la insertará en Docker Hub para su uso futuro. Por último, extraerá la imagen almacenada de su repositorio de Docker Hub y creará otro contenedor para demostrar cómo puede recrear y escalar su aplicación.

Requisitos previos

Para seguir este tutorial, necesitará lo siguiente:

Paso 1: instalación de las dependencias de su aplicación

Para crear su imagen, primero, deberá crear los archivos de su aplicación, que, luego, puede copiar a su contenedor. Estos archivos incluirán el contenido estático, el código y las dependencias de su aplicación.

Primero, cree un directorio para su proyecto en el directorio principal de su usuario no root. Llamaremos al nuestro node_project, pero no es necesario que usted utilice la misma denominación:

  • mkdir node_project

Navegue a este directorio:

  • cd node_project

Este será el directorio root del proyecto.

A continuación, cree un archivo package.json con las dependencias de su proyecto y otra información de identificación. Abra el archivo con nano o su editor favorito:

  • nano package.json

Añada la siguiente información sobre el proyecto, incluido su nombre, autor, licencia, punto de entrada y dependencias. Asegúrese de sustituir la información de autor con su propio nombre y sus detalles 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",
  "keywords": [
    "nodejs",
    "bootstrap",
    "express"
  ],
  "dependencies": {
    "express": "^4.16.4"
  }
}

Este archivo incluye el nombre, el autor y la licencia del proyecto con los que se comparte. Npm recomienda que el nombre de su proyecto sea corto y descriptivo, así como evitar duplicaciones en el registro de npm. Hemos incluido la licencia MIT en el campo de licencia, lo que permite el uso y la distribución gratuitos del código de la aplicación.

Además, el archivo especifica lo siguiente:

  • "main": el punto de entrada de la aplicación, app.js. Creará este archivo a continuación.
  • "dependencies": las dependencias del proyecto; en este caso, Express 4.16.4 o superior.

Aunque este archivo no enumera un repositorio, puede añadir uno al seguir estas pautas sobre la adición de un repositorio a su archivo package.json. Es una buena adición si va a crear versiones de su aplicación.

Guarde y cierre el archivo cuando haya terminado de realizar cambios.

Para instalar las dependencias de su proyecto, ejecute el siguiente comando:

  • npm install

Esto instalará los paquetes que haya incluido en su archivo package.json en el directorio de su proyecto.

Ahora, podemos proceder a crear los archivos de la aplicación.

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. Nuestra aplicación tendrá un punto de entrada principal, app.js y un directorio views que incluirá los activos estáticos del proyecto. La página de inicio, index.html, ofrecerá a los usuarios algunos datos preliminares y un enlace a una página con información más detallada sobre tiburones, sharks.html. En el directorio views, crearemos tanto la página de inicio como la página sharks.html.

Primero, abra el archivo app.js en el directorio principal del proyecto para definir las rutas del proyecto:

  • nano app.js

La primera parte del archivo creará la aplicación Express y los objetos Router, y definirá el directorio base y el puerto como constantes:

~/node_project/app.js
const express = require('express');
const app = express();
const router = express.Router();

const path = __dirname + '/views/';
const port = 8080;

La función require carga el módulo express, que, luego, usaremos para crear los objetos app y router. El objeto router realizará la función de enrutamiento de la aplicación, y, al definir las rutas de método HTTP, las añadiremos a este objeto para definir cómo se deben manejar las solicitudes.

Esta sección del archivo también establece dos constantes: path y port:

  • path: define el directorio base, que será el subdirectorio de views dentro del directorio actual del proyecto.
  • port: le indica a la aplicación que escuche el puerto 8080 y se conecte a él.

A continuación, establezca las rutas de la aplicación usando el objeto router:

~/node_project/app.js
...

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');
});

La función router.use carga una función de middleware que registrará las solicitudes del router y las transmitirá a las rutas de la aplicación. Estas se definen en las funciones siguientes, que especifican que una solicitud GET a la URL del proyecto base debe devolver la página index.html, mientras que una solicitud GET a la ruta /sharks debe devolver sharks.html.

Por último, monte el middleware router y los activos estáticos de la aplicación e indíquele a esta que escuche por el puerto 8080:

~/node_project/app.js
...

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

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

El archivo app.js terminado tendrá este aspecto:

~/node_project/app.js
const express = require('express');
const app = express();
const router = express.Router();

const path = __dirname + '/views/';
const port = 8080;

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(port, function () {
  console.log('Example app listening on port 8080!')
})

Guarde y cierre el archivo cuando haya terminado.

A continuación, añadamos algunos contenidos estáticos a la aplicación. Comience por crear el directorio views:

  • mkdir views

Abra el archivo de la página de destino, 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:

~/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://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <link href="css/styles.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Merriweather:400,700" rel="stylesheet" type="text/css">
</head>

<body>
    <nav class="navbar navbar-dark bg-dark navbar-static-top navbar-expand-md">
        <div class="container">
            <button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span>
            </button> <a class="navbar-brand" href="#">Everything Sharks</a>
            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                <ul class="nav navbar-nav mr-auto">
                    <li class="active nav-item"><a href="/" class="nav-link">Home</a>
                    </li>
                    <li class="nav-item"><a href="/sharks" class="nav-link">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-lg-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-lg-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>

Aquí, la barra de navegación de nivel superior permite a los usuarios alternar entre las páginas Home y Sharks. En el subcomponente navbar-nav, estamos usando la clase active de Bootstrap para indicar la página actual al usuario. También especificamos las rutas a nuestras páginas estáticas, que coinciden con las rutas que definimos en app.js:

~/node_project/views/index.html
...
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
   <ul class="nav navbar-nav mr-auto">
      <li class="active nav-item"><a href="/" class="nav-link">Home</a>
      </li>
      <li class="nav-item"><a href="/sharks" class="nav-link">Sharks</a>
      </li>
   </ul>
</div>
...

Además, creamos un enlace a nuestra página de información de tiburones en el botón de jumbotron:

~/node_project/views/index.html
...
<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>
...

También hay un enlace a una hoja de estilo personalizado en el encabezado:

~/node_project/views/index.html
...
<link href="css/styles.css" rel="stylesheet">
...

Crearemos esta hoja de estilo al final de este paso.

Guarde y cierre el archivo cuando haya terminado.

Con la página de destino de la aplicación establecida, podemos crear nuestra página de información de tiburones, sharks.html, que ofrecerá más información a los usuarios interesados en los tiburones.

Abra el archivo:

  • 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://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <link href="css/styles.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Merriweather:400,700" rel="stylesheet" type="text/css">
</head>
<nav class="navbar navbar-dark bg-dark navbar-static-top navbar-expand-md">
    <div class="container">
        <button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span>
        </button> <a class="navbar-brand" href="/">Everything Sharks</a>
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav mr-auto">
                <li class="nav-item"><a href="/" class="nav-link">Home</a>
                </li>
                <li class="active nav-item"><a href="/sharks" class="nav-link">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-lg-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-lg-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>

</html>

Tenga en cuenta que, en este archivo, volvemos a usar la clase active para indicar la página actual.

Guarde y cierre el archivo cuando haya terminado.

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:

  • nano views/css/styles.css

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;
}

Además de establecer fuentes y color, este archivo también limita el tamaño de las imágenes al especificar un ancho máximo, max-width, del 80%. Esto impedirá que ocupen más espacio del que quisiéramos en la página.

Guarde y cierre el archivo cuando haya terminado.

Con los archivos de la aplicación establecidos y las dependencias del proyecto instaladas, está listo para iniciar la aplicación.

Si siguió el tutorial de configuración inicial del servidor que se indica en los requisitos previos, tendrá un firewall activo que solo permite tráfico SSH. Para permitir el tráfico al puerto 8080 ejecute lo siguiente:

  • sudo ufw allow 8080

Para iniciar la aplicación, asegúrese de estar en el directorio root de su proyecto:

  • cd ~/node_project

Inicie la aplicación con node app.js:

  • node app.js

Ingrese la dirección http://your_server_ip:8080 en su navegador. Visualizará la siguiente página de destino:

Página de destino 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. Ahora, podemos pasar a crear el Dockerfile que nos permitirá recrear y escalar esta aplicación como deseemos.

Paso 3: escribir el Dockerfile

Su Dockerfile especifica qué se incluirá en el contenedor de su aplicación cuando se ejecute. Usar Dockerfile le permite definir el entorno de su contenedor y evitar discrepancias con las dependencias o versiones de tiempo de ejecución.

Siguiendo estas pautas sobre la creación de contenedores optimizados, haremos que nuestra imagen sea tan eficiente como sea posible al minimizar el número de capas de imagen y restringir la función de la imagen a un único propósito: recrear los archivos y el contenido estático de nuestra aplicación.

En el directorio root de su proyecto, cree el Dockerfile:

  • nano Dockerfile

Las imágenes de Docker se crean usando una sucesión de imágenes en capas que se acumulan unas sobre otras. El primer paso será añadir la imagen base para nuestra aplicación, que formará el punto de partida de la creación de la aplicación.

Procederemos a utilizar la imagen node:10-alpine, dado que, al momento de redactar este artículo, es la versión LTS de Node.js recomendada. La imagen alpine se deriva del proyecto Alpine Linux, y nos ayudará a mantener el tamaño de las imágenes bajo. Para obtener más información sobre si la imagen alpine es la opción correcta para su proyecto, consulte la discusión completa en la sección de Variantes de imagen de la página de la imagen Node de Docker Hub.

Añada la siguiente instrucción FROM para configurar la imagen base de la aplicación:

~/node_project/Dockerfile
FROM node:10-alpine

Esta imagen incluye Node.js y npm. Cada Dockerfile debe comenzar con una instrucción FROM.

De forma predeterminada, la imagen Node de Docker incluye un usuario node no root que puede usar para evitar ejecutar el contenedor de su aplicación como root. Evitar ejecutar contenedores como root y restringir las capacidades del contenedorsolo a las necesarias para la ejecución de sus procesos es una práctica de seguridad recomendada. Por lo tanto, utilizaremos el directorio principal del usuario node como directorio de trabajo de nuestra aplicación, y procederemos a configurarlo como nuestro usuario dentro del contenedor. Para obtener más información sobre las mejores prácticas al trabajar con la imagen Node de Docker, consulte esta guía de prácticas recomendadas.

Para ajustar los permisos en el código de nuestra aplicación en el contenedor, cree el subdirectorio node_modules en /home/node y el directorio app. Crear estos directorios garantizará que tengan los permisos deseados, lo que será importante al crear módulos de nodo locales en el contenedor con npm install. Además de crear estos directorios, estableceremos la propiedad sobre ellos a nuestro usuario node:

~/node_project/Dockerfile
...
RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app

Para obtener más información sobre la utilidad de consolidar instrucciones RUN, consulte esta discusión sobre cómo gestionar capas de contenedores.

A continuación, establezca el directorio de trabajo de la aplicación en /home/node/app:

~/node_project/Dockerfile
...
WORKDIR /home/node/app

Si no hay un WORKDIR establecido, Docker creará uno por defecto, por lo que es buena idea configurarlo de manera explícita.

A continuación, copie los archivos package.json y package-lock.json (para npm 5+):

~/node_project/Dockerfile
...
COPY package*.json ./

Añadir esta instrucción COPY antes de ejecutar npm install o copiar el código de la aplicación nos permite aprovechar el mecanismo de almacenamiento en caché de Docker. En cada etapa de la creación, Docker comprobará si tiene una capa en caché para esa instrucción en particular. Si cambiamos package.json, esta capa se reconstruye, pero si no lo hacemos, esta instrucción le permitirá a Docker utilizar la capa de imagen existente y omitir la reinstalación de nuestros módulos de nodo.

Para garantizar que todos los archivos de la aplicación sean propiedad del usuario node no root, incluido el contenido del directorio node_modules, cambie el usuario a node antes de ejecutar npm install:

~/node_project/Dockerfile
...
USER node

Tras copiar las dependencias del proyecto y cambiar nuestro usuario, podemos ejecutar npm install:

~/node_project/Dockerfile
...
RUN npm install

A continuación, copie el código de su aplicación con los permisos apropiados al directorio de la aplicación en el contenedor:

~/node_project/Dockerfile
...
COPY --chown=node:node . .

Esto garantizará que los archivos de la aplicación sean propiedad del usuario node no root.

Por último, exponga el puerto 8080 en el contenedor e inicie la aplicación:

~/node_project/Dockerfile
...
EXPOSE 8080

CMD [ "node", "app.js" ]

EXPOSE no publica el puerto, sino que actúa como una manera de documentar qué puertos del contenedor se publicarán en el tiempo de ejecución. CMD ejecuta el comando para iniciar la aplicación; en este caso, node app.js. Tenga en cuenta que debe haber una sola instrucción CMD en cada Dockerfile. Si incluye más de una, solo la última tendrá efecto.

Se pueden hacer muchas cosas con Dockerfile. Para obtener una lista completa de instrucciones, consulte la documentación de referencia de Dockerfile de Docker.

Así es como se ve el Dockerfile completo:

~/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" ]

Guarde y cierre el archivo cuando haya terminado de editar.

Antes de crear la imagen de la aplicación, añadamos un archivo .dockerignore. Con un funcionamiento similar al de un archivo.gitignore, .dockerignore especifica qué archivos y directorios del directorio de su proyecto no deben copiarse a su contenedor.

Abra el archivo .dockerignore:

  • nano .dockerignore

Dentro del archivo, añada sus módulos de nodo locales, registros de npm, Dockerfile y el archivo .dockerignore:

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

Si está trabajando con Git, también es conveniente que añada su directorio .git y el archivo .gitignore.

Guarde y cierre el archivo cuando haya terminado.

Ahora, está listo para crear la imagen de la aplicación usando el comando docker build. Usar la marca -t con docker build le permitirá etiquetar la imagen con un nombre fácil de recordar. Dado que vamos a insertar la imagen en Docker Hub, incluiremos nuestro nombre de usuario de Docker Hub en la etiqueta. Vamos a etiquetar la imagen como nodejs-image-demo, pero puede utilizar un nombre de su elección. Recuerde reemplazar también your_dockerhub_usernamecon su nombre de usuario de Docker Hub:

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

El . especifica que el contexto de compilación es el directorio actual.

La compilación de la imagen tomará entre uno y dos minutos. Una vez que se haya completado, verifique sus imágenes:

  • docker images

Verá la salida siguiente:

Output
REPOSITORY TAG IMAGE ID CREATED SIZE your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 8 seconds ago 73MB node 10-alpine f09e7c96b6de 3 weeks ago 70.7MB

Ahora, es posible crear un contenedor con esta imagen usandodocker run. Incluiremos tres marcas con este comando:

  • -p: edita el puerto en el contenedor y lo asigna a un puerto en nuestro host. Usaremos el puerto 80 en el host, pero puede modificarlo como considere necesario si tiene otro proceso en ejecución en ese puerto. Para obtener más información sobre cómo funciona, consulte esta discusión en la documentación de Docker sobre enlaces de puerto.
  • -d: ejecuta el contenedor en segundo plano.
  • --name: permite darle al contenedor un nombre fácil de recordar.

Ejecute el siguiente comando para compilar el contenedor:

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

Una vez que su contenedor esté listo y en funcionamiento, puede inspeccionar una lista de sus contenedores en ejecución con docker ps:

  • docker ps

Verá la salida siguiente:

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

Con el contenedor en ejecución, ahora, puede visitar su aplicación ingresando la dirección http://your_server_ip 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

Al insertar la imagen de su aplicación en un registro como Docker Hub, la pone a disposición para su uso posterior a medida que construye y escala sus contenedores. Demostraremos cómo funciona esto al insertar la imagen de la aplicación en un repositorio y, luego, usar la imagen para recrear nuestro contenedor.

El primer paso para insertar la imagen es ingresar a la cuenta de Docker Hub que creó en los requisitos previos:

  • docker login -u your_dockerhub_username

Cuando se le indique, ingrese la contraseña de la cuenta de Docker Hub. 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.

Ahora, puede insertar la imagen de la aplicación en Docker Hub usando la etiqueta que creó anteriormente, your_dockerhub_username/nodejs-image-demo:

  • docker push your_dockerhub_username/nodejs-image-demo

Vamos a probar la utilidad del registro de imágenes al destruir el contenedor y la imagen de nuestra aplicación actual y volver a compilarlos con la imagen en nuestro repositorio.

Primero, enumere sus contenedores en ejecución:

  • docker ps

Verá la salida siguiente:

Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e50ad27074a7 your_dockerhub_username/nodejs-image-demo "node app.js" 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á la siguiente salida 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 73MB <none> <none> 2e3267d9ac02 4 minutes ago 72.9MB <none> <none> 8352b41730b9 4 minutes ago 73MB <none> <none> 5d58b92823cb 4 minutes ago 73MB <none> <none> 3f1e35d7062a 4 minutes ago 73MB <none> <none> 02176311e4d0 4 minutes ago 73MB <none> <none> 8e84b33edcda 4 minutes ago 70.7MB <none> <none> 6a5ed70f86f2 4 minutes ago 70.7MB <none> <none> 776b2637d3c1 4 minutes ago 70.7MB node 10-alpine f09e7c96b6de 3 weeks ago 70.7MB

Elimine el contenedor detenido y todas las imágenes, incluso las no utilizadas o pendientes, con el siguiente comando:

  • docker system prune -a

Escriba y cuando se le indique, en la salida, para confirmar que desea eliminar el contenedor detenido y las imágenes. Tenga en cuenta que esto también eliminará la memoria caché de su compilación.

Ahora, eliminó tanto la imagen de su aplicación como el contenedor que la ejecutaba. Para obtener más información sobre la eliminación de contenedores, imágenes y volúmenes de Docker, consulte la sección Cómo eliminar imágenes, contenedores y volúmenes de Docker.

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:

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

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
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f6bc2f50dff6 your_dockerhub_username/nodejs-image-demo "node app.js" 4 seconds ago Up 3 seconds 0.0.0.0:80->8080/tcp nodejs-image-demo

Visite http://your_server_ip una vez más para ver su aplicación en ejecución.

Conclusión

En este tutorial, creó una aplicación web estática con Express y Bootstrap, así como una imagen de Docker para la aplicación. Utilizó esta imagen para crear un contenedor y la insertó en Docker Hub. Desde allí, pudo destruir su imagen y su contenedor, y recrearlos usando su repositorio de Docker Hub.

Si le interesa aprender más sobre cómo trabajar con herramientas como Docker Compose y Docker Machine para crear configuraciones de múltiples contenedores, puede consultar las siguientes guías:

Para obtener sugerencias generales sobre el trabajo con los datos del contenedor, consulte:

Si le interesan otros temas relacionados con Docker, consulte nuestra biblioteca completa de tutoriales de Docker.

0 Comments

Creative Commons License