Desplegando una aplicación Node.js en un Droplet de DigitalOcean con Docker

     

    Introducción

    JavaScript ha recorrido un largo camino a lo largo de los años, y ahora estamos en un punto en el que puede escribir e implementar una aplicación web con mucha facilidad. Los marcos como Express , Sails y Meteor solo lo han hecho más fácil.

    Seguir la mayoría de los tutoriales en Internet significa que estará trabajando en su máquina local con un proyecto local. Pero, ¿y si quisiéramos compartir el proyecto con el mundo o con nuestros amigos? Hoy veremos cómo implementar una aplicación Node.js en un Droplet de DigitalOcean , para que cualquier persona en Internet pueda interactuar con ella.

    Prerrequisitos

    Estibador

    Usaremos Docker para contener nuestra aplicación en una unidad pequeña y fácilmente implementable. Esta unidad se puede implementar en cualquier lugar donde esté instalado Docker.

    Cree una cuenta con Docker Hub y descargue la edición community / desktop. ¡Usaremos esta cuenta más tarde!

    DigitalOcean

    DigitalOcean es un servicio de alojamiento de pago: usaremos su servicio de $ 5 al mes y podemos desactivarlo tan pronto como terminemos para minimizar los costos, pero necesitará un método de pago para dárselo a DigitalOcean antes de usarlo. .

    Aplicación de node

    Para esto, vamos a crear una aplicación Express simple que sirva como punto final de estado para que podamos acceder y averiguar si nuestra aplicación se está ejecutando. En la línea de comando, creemos un directorio:

    Te puede interesar:Leer y escribir YAML en un archivo en Node.js / JavaScript
    $ mkdir digital-ocean
    

    Y luego muévase al directorio e inicialice nuestra aplicación:

    $ cd digital-ocean
    $ npm init
    

    Siéntase libre de presionar ENTERpara omitir / establecer las respuestas predeterminadas para todas las siguientes preguntas, o agregar nombres / descripciones de paquetes si lo desea.

    Para los propósitos de este tutorial, asumiremos que el «punto de entrada» se deja como index.js. Deberías terminar con algo parecido a esto:

    package name: (digital-ocean)
    version: (1.0.0)
    description:
    entry point: (index.js)
    test command:
    git repository:
    keywords:
    author:
    license: (ISC)
    
    {
      "name": "digital-ocean",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo "Error: no test specified" && exit 1"
      },
      "author": "",
      "license": "ISC"
    }
    
    
    Is this OK? (yes)
    

    Si busca en el directorio ahora ( lsen la línea de comando), verá un package.jsonarchivo solitario . Contiene la configuración de nuestra aplicación. Saltemos allí y agreguemos una línea al bloque «scripts»:

    {
      "name": "digital-ocean",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "start": "node index.js",
        "test": "echo "Error: no test specified" && exit 1"
      },
      "author": "",
      "license": "ISC"
    }
    

    Esto nos permite iniciar nuestra aplicación ejecutando npm start. Los scripts son muy útiles para configurar tareas que realizará con frecuencia con una aplicación, como pruebas o varios procesos de compilación.

    A continuación, queremos instalar Express:

    $ npm install express
    

    Y finalmente, escribamos el código que servirá a nuestro /statuspunto final. En el mismo directorio que nuestro package.jsonarchivo, cree un archivo llamado index.js:

    Te puede interesar:Usar fetch para enviar solicitudes HTTP en JavaScript
    const express = require('express')
    const app = express()
    const port = 3000
    
    app.get('/status', (req, res) => res.send({status: "I'm alive!"}))
    
    app.listen(port, () => console.log(`Example app listening on port ${port}!`))
    

    Finalmente, probemos nuestra aplicación ejecutando:

    $ npm start
    

    Al abrir un navegador web y navegar a http://localhost:3000/status, debería ser recibido con algo como esto:

    {"status":"I'm alive!"}
    

    Ahora tenemos una aplicación Express en funcionamiento, que ahora podemos empaquetar e implementar usando Docker y un servidor Droplet.

    Dockerizar una aplicación Node.js

    Ahora tenemos una aplicación que funciona, pero queremos poder implementarla. Podríamos crear un servidor y luego configurarlo para que tenga exactamente la misma configuración que nuestra máquina actual, pero eso puede ser complicado. En su lugar, empaquetémoslo usando Docker.

    Cómo funciona Docker

    Docker nos permite definir un conjunto de instrucciones que crean lo que se llaman capas . Si quieres imaginar cómo se ve una capa, imagina tu sistema de archivos congelado en un momento en el tiempo. Cada nueva capa es una modificación o adición a ese sistema de archivos, que luego se congela nuevamente.

    Estas composiciones de capas una encima de la otra forman lo que se conoce como una imagen , que es esencialmente un sistema de archivos en una caja, listo para funcionar.

    Esta imagen se puede utilizar para crear contenedores , que son versiones vivas de ese sistema de archivos, listas para ejecutar una tarea que definamos para él.

    Te puede interesar:Introducción a las transmisiones de Node.js

    Otro aspecto útil de esto es que podemos usar imágenes prefabricadas como la primera capa en nuestras propias imágenes, lo que nos da un impulso al evitar configuraciones estándar.

    Crear una imagen de Docker

    Lo primero que queremos hacer es crear un Dockerfile. Este archivo es un conjunto de instrucciones que Docker debe interpretar para comprender exactamente cómo empaquetar su aplicación como una imagen.

    En la carpeta de su proyecto, cree un archivo llamado Dockerfiley luego ingrese estos comandos:

    FROM node:13-alpine
    
    WORKDIR /usr/src/app
    
    COPY package*.json ./
    
    RUN npm install
    
    COPY . .
    
    EXPOSE 3000
    CMD [ "npm", "start" ]
    

    Hay algunos componentes aquí, veamos esta línea por línea:

    • FROM node:10: Le dice a Docker que use otra imagen como capa base en nuestro Dockerfile; en este caso, obtenemos una imagen con Node.js instalado, versión 10.
    • WORKDIR /usr/src/app: Le dice a Docker la carpeta en la que debe realizar los siguientes comandos.
    • COPY package*.json ./: Le dice a Docker que copie solo package.jsony package-lock.jsonen la imagen de Docker. Hacemos esto porque Docker puede almacenar en caché composiciones de capas, lo que significa que si nada cambia en nuestro package.json, podemos simplemente extraer una composición de capas que ya hemos construido antes.
    • RUN npm install: Hace lo que dice en la lata y ejecuta el npm installcomando para crear una nueva capa de la imagen con todos nuestros módulos instalados. Nuevamente, si nada ha cambiado en nuestro package.json, esto sacará una versión prediseñada.
    • COPY . .: Copia el resto de la aplicación en el sistema de archivos. Como es probable que la aplicación cambie con más frecuencia (es decir, cada vez que realice un cambio de código), tiene sentido hacer de esta una de las últimas capas para fines de almacenamiento en caché.
    • EXPOSE 3000: Le dice a Docker que abra el puerto 3000 en el contenedor cuando se está ejecutando.
    • CMD [ "npm", "start" ]: Se ejecuta npm starten la instanciación del contenedor y ejecuta nuestra aplicación dentro de él.

    Ejecutando nuestra compilación de Docker

    Ahora que tenemos nuestras instrucciones escritas, ¡construyamos nuestra imagen! En el mismo directorio que su Dockerfile, ejecute:

    $ docker build . -t digital-ocean-app
    

    Esto crea una imagen y luego le da un nombre o ‘etiqueta’ específico; en este caso, es digital-ocean-app. Para probar que nuestra aplicación funciona, ejecutémosla localmente con:

    $ docker run -p 3000:3000 digital-ocean-app
    

    Esto ejecutará nuestra imagen de Docker como un contenedor y ejecutará la CMDparte de nuestro Dockerfile.

    Te puede interesar:Uso de espías para realizar pruebas en JavaScript con Sinon.js

    La -p 3000:3000sección hace lo que se conoce como mapeo de puertos. El número antes de los dos puntos es el puerto en nuestra máquina local que queremos mapear, y el número después es el puerto dentro del contenedor al que queremos que se dirija.

    Esto significa que el puerto 3000de nuestra máquina ahora se conectará al puerto 3000del contenedor Docker en el que se ejecuta nuestra aplicación.

    Para probar esto, abra su navegador y navegue de regreso http://localhost:3000/statusy debería ver su punto final de estado.

    Publicar la imagen en Docker Hub

    Ahora que tenemos nuestra imagen de Docker empaquetada, necesitamos almacenarla en algún lugar desde donde podamos extraerla. Deberá volver a iniciar sesión en Docker Hub y luego hacer clic en ‘Crear repositorio’. Al igual que los repositorios de Git nos permiten almacenar nuestros proyectos de Git controlados por versiones, los repositorios de Docker nos permiten almacenar nuestras imágenes de Docker.

    Deberá completar el nombre del repositorio, así como una descripción opcional y si es o no un repositorio público o privado (si necesita o no iniciar sesión como usuario autorizado de Docker, básicamente).

    Por ahora, déjelo en público, ya que nos facilitará la vida cuando intentemos implementar en DigitalOcean. Finalmente, desplácese hasta la parte inferior y presione ‘Crear’.

    De vuelta en la línea de comando, necesitamos etiquetar nuestra imagen antes de presionarla:

    Te puede interesar:Uso de stubs para pruebas en JavaScript con Sinon.js
    $ docker tag digital-ocean-app <USER_NAME>/digital-ocean-app
    

    Necesitaremos reemplazar la <USER_NAME>sección con nuestro nombre de usuario de Docker Hub. Opcionalmente, si queremos especificar que estamos impulsando una versión específica de nuestra imagen, podemos hacer:

    $ docker tag digital-ocean-app <USER_NAME>/digital-ocean-app:<VERSION>
    

    El <VERSION>se llama el ‘código de imagen’ – podríamos poner un número allí ( 1.0, 1.1, etc.) para representar los comunicados, o incluso describir un entorno ( dev, staging, prod). Tiendo a usar el hash de confirmación de Git para saber exactamente qué estoy ejecutando y puedo compararlo con mi historial de confirmación.

    De forma predeterminada, cada vez que empuja, su repositorio creará automáticamente una imagen con la etiqueta :latest, por lo que siempre sabemos cuál es la etiqueta de la imagen empujada más recientemente.

    Para poder enviar a nuestro repositorio, necesitaremos iniciar sesión:

    $ docker login
    

    Ingrese sus credenciales de Docker Hub.

    Una vez que haya iniciado sesión correctamente, podrá enviar su imagen con:

    $ docker push <USER_NAME>/digital-ocean-app:<OPTIONAL_VERSION>
    

    DigitalOcean

    Finalmente, podemos implementar nuestra aplicación acoplada en DigitalOcean. Primero, vamos a crear una cuenta:

    Te puede interesar:Uso de Mocks para pruebas en JavaScript con Sinon.js

    Tendrá que proporcionar algunos datos personales, incluidos los detalles de pago, así como configurar un proyecto inicial. Siéntase libre de simplemente darle un nombre, pero si planea hacer algo extenso, seleccione algunas de las opciones para optimizar su configuración.

    Una vez que haya terminado, será redirigido a la página raíz de su proyecto. En el lado izquierdo hay una barra de herramientas con varias opciones. Siéntase libre de explorar: DigitalOcean es bueno para informarle si algo que está a punto de hacer le costará.

    Crear una clave SSH

    Antes de hacer algo, necesitaremos crear una clave SSH y cargar la parte pública en DigitalOcean. Las claves SSH vienen en dos partes, una clave pública y una clave privada.

    Se utiliza una clave privada para autenticar a un usuario en un sistema. El sistema hace esto realizando una función usando la clave pública para verificar que la clave privada es la que se usa para generar la clave pública. Si es así, ambos proceden del mismo lugar, por lo que se puede confiar en el usuario.

    DigitalOcean querrá una clave pública que pueda colocar en cualquier Droplets que iniciemos, para que podamos acceder a ellos con una clave que sabemos que solo nosotros tenemos.

    Creemos un par de claves SSH ahora:

    $ ssh-keygen -t rsa -b 4096
    

    Este comando debería funcionar en Windows, Linux y MacOS.

    Te puede interesar:Usando Sequelize ORM con Node.js y Express

    Esto le pedirá un archivo donde desea guardar la clave que puede llamar algo como – digital-ocean-key.

    También le pedirá una frase de contraseña; no dude en establecer una si lo desea o puede dejarla vacía. Si lo creó en la misma carpeta en la que hemos estado trabajando, verá dos archivos, uno llamado digital-ocean-keyy otro llamado digital-ocean-key.pub, que son respectivamente sus claves pública y privada.

    Agregar la clave SSH a su cuenta de DigitalOcean

    En su cuenta de DigitalOcean, en la parte inferior izquierda, hay un enlace para ‘Seguridad’. Siga este enlace y la página siguiente tendrá una opción para agregar una clave SSH:

    Haga clic en ‘Agregar una clave SSH’ y se le presentará un cuadro de diálogo para ingresar su clave. Simplemente copie el contenido de su digital-ocean-key.puben el cuadro de texto grande (puede imprimir el contenido en el terminal con cat digital-ocean-key.pub).

    En el cuadro más pequeño que se encuentra debajo, asigne un nombre a esa clave.

    Configuración de una gota de DigitalOcean

    Una vez que haya agregado su clave SSH. haga clic en el enlace ‘Droplets’ a la izquierda, y luego en la página siguiente haga clic en ‘Crear Droplet’.

    En DigitalOcean, un Droplet es un servidor virtual privado que se puede configurar y usar fácilmente para ejecutar sus aplicaciones.

    Te puede interesar:Implementación de aplicaciones Node.js en AWS EC2 con Docker

    En esta página, se le presentarán varias opciones para configurar su DigitalOcean Droplet, incluida la distribución, el plan, el tamaño / costo por mes, la región y la autenticación.

    En lugar de seleccionar una distribución y configurarla nosotros mismos, vamos a conseguir que DigitalOcean cree un Droplet que ya tiene Docker ejecutándose por nosotros.

    Haga clic en ‘Marketplace’ encima de las diversas distribuciones de Linux; aquí es donde puede encontrar varias configuraciones existentes; estos son Droplets que, cuando se inician, comenzarán con el software descrito ya instalado.

    Esto es un ahorro de tiempo real y significa que podemos iniciar varias instancias con la misma configuración exacta si quisiéramos, en lugar de tener que configurarlas todas individualmente.

    Debería haber una opción para un Docker Droplet. De lo contrario, haga clic en ‘Ver todas las aplicaciones de Marketplace’ y podrá encontrar una configuración de Docker adecuada allí:

    En «Plan», queremos seleccionar «Estándar». Seleccionemos la opción de $ 5 al mes, con fines de demostración.

    Siéntase libre de elegir la región que sea adecuada para usted; generalmente, será más fácil acceder a la más cercana, pero no debería tener un impacto masivo.

    Te puede interesar:Uso de simulacros para pruebas en JavaScript con Jest

    En Autenticación, seleccione ‘Clave SSH’ y seleccione las claves que le gustaría usar (como la que creó en el último paso). También puede nombrar su Droplet si lo desea. Cuando haya terminado, haga clic en ‘Crear gota’ en la parte inferior.

    Espere un minuto a que se inicie Droplet. Aparecerá debajo del panel ‘Gotitas’ con un punto verde al lado cuando esté listo. En este punto, estamos listos para conectarnos.

    Ejecución de imágenes de Docker en gotitas de OD

    Haga clic en el Droplet iniciado y verá los detalles al respecto. Por el momento, estamos interesados ​​en la dirección IP: esta es la dirección en la que se encuentra el Droplet en Internet.

    Para acceder a él, necesitaremos conectarnos a él usando nuestra clave privada creada previamente. Desde la misma carpeta que esa clave privada, ejecute:

    $ ssh -i digital-ocean-key [email protected]<IP_ADDRESS>
    

    Las -i digital-ocean-keyespecifica que está utilizando una clave SSH, y donde se encuentra dicha clave. Los [email protected]<IP_ADDRESS>Especifica el usuario y la dirección que está intentando conectarse a – en este caso, el usuario que estamos tratando de conectar con es root, y la dirección IP serían la dirección de la digitalocean droplet.

    Una vez que esté conectado a la instancia, es solo cuestión de ejecutar su imagen de Docker. Si lo dejó en un repositorio público, puede ejecutarlo fácilmente con el mismo nombre que utilizó para enviarlo:

    $ docker run -p 3000:3000 <DOCKER_USER_NAME>/digital-ocean-app:<OPTIONAL_TAG>
    

    Si lo coloca en un repositorio privado, deberá iniciar sesión docker loginnuevamente antes de ejecutar su docker runcomando.

    Te puede interesar:Clasificación de burbujas y clasificación de coctelera en JavaScript

    Una vez que su contenedor Docker se esté ejecutando, abra una pestaña en su navegador y navegue hasta <IP_ADDRESS>:3000/statusdónde <IP_ADDRESS>está la dirección IP del DigitalOcean Droplet en el que está ejecutando el contenedor.

    Se le debe presentar su punto final de estado creado anteriormente: ¡felicitaciones! ¡Ahora tiene una aplicación Node.js ejecutándose en DigitalOcean!

    Conclusión

    Hay algunas direcciones a las que puede ir desde aquí. Primero, probablemente querrá construir su aplicación para que haga cosas más útiles.

    Es posible que desee considerar comprar un dominio para alojar su aplicación y apuntarlo a su DigitalOcean Droplet para que sea más fácil de acceder.

    También recomendaría explorar algunas de las demás capacidades de DigitalOcean: podría usar algunas de sus herramientas de red para proteger su Droplet restringiendo el acceso al puerto SSH (22), explorar algunas de las otras imágenes que tiene Docker o ¡incluso mire la creación de bases de datos para su aplicación!

     

    Rate this post

    Etiquetas: