Encadenamiento de CI / CD y automatización de Docker

Escribí mis primeros sitios a finales de los 90. Luego ponerlos en condiciones de trabajo fue muy simple. Había un servidor Apache en algún alojamiento compartido, podría iniciar sesión en este servidor a través de FTP, escribiendo algo así en la línea del navegador ftp://ftp.example.com. Luego fue necesario ingresar un nombre y contraseña y subir archivos al servidor. Hubo otros momentos, todo era más fácil que ahora. En las últimas dos décadas, todo ha cambiado mucho. Los sitios se han vuelto más complejos, deben ensamblarse antes de ser lanzados a producción. Un único servidor se ha convertido en una pluralidad de servidores que trabajan detrás de equilibradores de carga; el uso de sistemas de control de versiones se ha convertido en algo común.





Para mi proyecto personal, tenía una configuración especial. Y sabía que necesitaba la capacidad de implementar un sitio en producción, realizando solo una acción: escribir código en una sucursal masteren GitHub. Además, sabía que para garantizar el funcionamiento de mi pequeña aplicación web, no quería administrar un gran clúster de Kubernetes, ni utilizar la tecnología Docker Swarm, ni mantener un parque de servidores con pods, agentes y todo tipo de dificultades. Para lograr el objetivo de simplificar el trabajo tanto como sea posible, necesitaba familiarizarme con CI / CD.

Si tiene un proyecto pequeño (en nuestro caso estamos hablando de un proyecto Node.js) y le gustaría aprender cómo automatizar la implementación de este proyecto, mientras se asegura de que lo que está almacenado en el repositorio coincida exactamente lo que funciona en producción, creo que te puede interesar este artículo.

Prerrequisitos


Se espera que el lector de este artículo tenga conocimientos básicos del área de la línea de comandos y escriba scripts de Bash. Además, necesitará las cuentas de Travis CI y Docker Hub .

Metas


No diré que este artículo puede llamarse incondicionalmente un "manual de capacitación". Es más bien un documento en el que hablo sobre lo que aprendí y describo el proceso de prueba y despliegue de código en producción que me conviene, realizado en un solo paso automatizado.

Así es como terminó mi flujo de trabajo.

Excepto el código enviado a cualquier rama del repositorio, masterse realizan las siguientes acciones:

  • Construye el proyecto en Travis CI.
  • Se realizan todas las pruebas unitarias, de integración y de extremo a extremo.

Solo para el código que entra en masterlas siguientes retenciones:

  • Todo lo dicho anteriormente, más ...
  • Cree la imagen de Docker en función del código, la configuración y el entorno actuales.
  • Colocar una imagen en el Docker Hub.
  • Conexión al servidor de producción.
  • Cargar la imagen del Docker Hub al servidor.
  • Detenga el contenedor actual e inicie uno nuevo basado en la nueva imagen.

Si no sabe absolutamente nada sobre Docker, sobre imágenes y contenedores, no se preocupe. Te contaré todo sobre esto.

¿Qué es un CI / CD?


La abreviatura CI / CD significa "integración continua / despliegue continuo" - "integración continua / despliegue continuo".

▍ Integración continua


La integración continua es un proceso durante el cual los desarrolladores se comprometen con el repositorio principal del código fuente del proyecto (generalmente a una rama master). Al mismo tiempo, la calidad del código se garantiza mediante la realización de pruebas automatizadas.

▍ Despliegue continuo


El despliegue continuo es el despliegue automatizado frecuente de código en producción. La segunda parte de la abreviatura CI / CD a veces se describe como "entrega continua" ("entrega continua"). Esto, en general, es lo mismo que "implementación continua", pero "entrega continua" implica la necesidad de una confirmación manual de los cambios antes de comenzar el proceso de implementación del proyecto.

Comienzo de trabajo


La aplicación en la que lo dominé todo se llama TakeNote . Este es el proyecto web en el que estoy trabajando, diseñado para tomar notas. Al principio traté de hacer un proyecto JAMStack , o simplemente una aplicación frontend sin servidor, para aprovechar las capacidades estándar de alojamiento e implementación que ofrece Netlify . A medida que crecía la complejidad de la aplicación, necesitaba crear su parte de servidor, lo que significaba que tendría que formar mi propia estrategia para la integración automatizada y la implementación automatizada del proyecto.

En mi caso, la aplicación es un servidor Express que se ejecuta en el entorno Node.js, que sirve una aplicación React de una sola página y admite una API de servidor segura. Esta arquitectura sigue la estrategia que se encuentra en esta guía de autenticación de pila completa.

Consulté con un amigo que es un experto en automatización y le pregunté qué necesitaba hacer para que funcionara como lo necesitaba. Me dio una idea de cómo debería ser un flujo de trabajo automatizado, descrito en la sección Objetivos de este artículo. El hecho de que me estableciera tales objetivos significaba que necesitaba descubrir cómo usar Docker.

Estibador


Docker es una herramienta que, gracias a la tecnología de contenedorización, facilita la distribución de aplicaciones, así como la implementación y el lanzamiento en el mismo entorno, incluso si la plataforma Docker funciona en entornos diferentes. Para empezar, necesitaba tener las herramientas de línea de comandos de Docker (CLI) a mi disposición. Las instrucciones para instalar Docker no se pueden llamar muy claras y comprensibles, pero puede aprender de él que para dar el primer paso de instalación, debe descargar Docker Desktop (para Mac o Windows).

Docker Hub es casi lo mismo que GitHub para repositorios git, o el registro npmpara paquetes de JavaScript. Este es un repositorio en línea para imágenes Docker. Se conecta a él Docker Desktop.

Entonces, para comenzar con Docker, debe hacer dos cosas:


Después de eso, puede verificar que la CLI de Docker esté funcionando ejecutando el siguiente comando para verificar la versión de Docker:

docker -v

Luego, inicie sesión en Docker Hub ingresando, cuando se le solicite, su nombre de usuario y contraseña:

docker login

Para utilizar Docker, debe comprender los conceptos de imágenes y contenedores.

▍ Imágenes


Una imagen es algo así como un plan que contiene instrucciones para construir un contenedor. Esta es una instantánea inmutable del sistema de archivos y la configuración de la aplicación. Los desarrolladores pueden compartir fácilmente imágenes.

#     
docker images

Este comando mostrará una tabla con el siguiente encabezado:

REPOSITORY     TAG     IMAGE ID     CREATED     SIZE
---

A continuación, consideraremos algunos ejemplos de comandos en el mismo formato: primero viene un comando con un comentario y luego un ejemplo de lo que puede generar.

▍Contenedores


Un contenedor es un paquete ejecutable que contiene todo lo que necesita para ejecutar una aplicación. Una aplicación con este enfoque siempre funcionará igual, independientemente de la infraestructura: en un entorno aislado y en el mismo entorno. El punto es que en diferentes entornos, se lanzan instancias de la misma imagen.

#   
docker ps -a
CONTAINER ID     IMAGE     COMMAND     CREATED     STATUS     PORTS     NAMES
---

▍Etiquetas


Una etiqueta es una indicación de una versión específica de una imagen.

▍ Resumen del comando Docker


Aquí hay una descripción general de algunos comandos Docker de uso común.
Equipo
Contexto
Actuar
Docker Build
Formar
Ensamblar una imagen desde Dockerfile
etiqueta acoplable
Formar
Etiquetado de imagen
imágenes de la ventana acoplable
Formar
Listado de imágenes
Docker Run
Envase
Lanzamiento de contenedor basado en imágenes
empuje de estibador
Formar
Enviar una imagen al registro
estibador
Formar
Descargar imagen del registro
docker ps
Envase
Lista de contenedores
poda del sistema acoplable
Imagen / Contenedor
Eliminar contenedores e imágenes no utilizados

▍ Dockerfile


Sé cómo ejecutar una aplicación de producción localmente. Tengo una configuración de Webpack diseñada para crear una aplicación React lista para usar. A continuación, tengo un comando que inicia un servidor basado en Node.js en el puerto 5000. Se parece a esto:

npm i         #  
npm run build #  React-
npm run start #  Node-

Cabe señalar que no tengo una aplicación de ejemplo para este material. Pero aquí, para los experimentos, cualquier aplicación Node simple es adecuada.

Para usar el contenedor, debe dar instrucciones a Docker. Esto se realiza a través de un archivo llamado Dockerfileubicado en el directorio raíz del proyecto. Este archivo, al principio, parece bastante oscuro.

Pero lo que contiene solo describe, con comandos especiales, algo similar a configurar un entorno de trabajo. Estos son algunos de estos comandos:

  • DESDE : este comando inicia el archivo. Indica la imagen básica en base a la cual se construye el contenedor.
  • COPIAR : copia archivos de una fuente local a un contenedor.
  • WORKDIR : configuración del directorio de trabajo para los siguientes comandos.
  • EJECUTAR : ejecuta comandos.
  • EXPOSE - Configuración del puerto.
  • PUNTO DE ENTRADA : especifica el comando a ejecutar.

Dockerfile podría verse más o menos así:

#   
FROM node:12-alpine

#        app/
COPY . app/

#  app/    
WORKDIR app/

#   ( npm ci  npm i,     )
RUN npm ci --only-production

#   React-  
RUN npm run build

#   
EXPOSE 5000

#  Node-
ENTRYPOINT npm run start

Dependiendo de la imagen base seleccionada, es posible que deba instalar dependencias adicionales. El hecho es que algunas imágenes básicas (como Node Alpine Linux) están diseñadas para hacerlas lo más compactas posible. Como resultado, es posible que no tengan algunos de los programas con los que cuenta.

▍ Construir, etiquetar y lanzar contenedor


El montaje local y el lanzamiento del contenedor es, después de que tenemos Dockerfile, las tareas son bastante simples. Antes de enviar una imagen al Docker Hub, debe probarla localmente.

▍ Asamblea


Primero debe recopilar la imagen especificando un nombre y, opcionalmente, una etiqueta (si no se especifica la etiqueta, el sistema asignará automáticamente una etiqueta a la imagen latest).

#  
docker build -t <image>:<tag> .

Después de ejecutar este comando, puede observar cómo Docker construye la imagen.

Sending build context to Docker daemon   2.88MB
Step 1/9 : FROM node:12-alpine
 ---> ...  ...
Successfully built 123456789123
Successfully tagged <image>:<tag>

El ensamblaje puede demorar un par de minutos; todo depende de cuántas dependencias tenga. Después de completar el ensamblaje, puede ejecutar el comando docker imagesy echar un vistazo a la descripción de su nueva imagen.

REPOSITORY          TAG               IMAGE ID            CREATED              SIZE
<image>             latest            123456789123        About a minute ago   x.xxGB

▍Inicio


La imagen es creada. Y esto significa que, sobre esta base, es posible lanzar un contenedor. Como quiero poder acceder a la aplicación que se ejecuta en el contenedor en la dirección localhost:5000que 5000:5000instalé en el lado izquierdo del par en el siguiente comando 5000. En el lado derecho está el puerto de contenedores.

#      5000    5000
docker run -p 5000:5000 <image>:<tag>

Ahora que el contenedor se creó e inició, puede usar el comando docker pspara ver la información sobre este contenedor (o puede usar el comando docker ps -aque muestra información sobre todos los contenedores, no solo los que funcionan).

CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS                      PORTS                    NAMES
987654321234        <image>             "/bin/sh -c 'npm run…"   6 seconds ago        Up 6 seconds                0.0.0.0:5000->5000/tcp   stoic_darwin

Si va a la dirección ahora localhost:5000, puede ver la página de la aplicación de trabajo, que se ve exactamente igual a la página de la aplicación que trabaja en el entorno de producción.

▍ Asignación y publicación de etiquetas


Para usar una de las imágenes creadas en el servidor de producción, necesitamos poder descargar esta imagen desde Docker Hub. Esto significa que primero debe crear un repositorio para el proyecto en Docker Hub. Después de eso, tendremos a nuestra disposición un lugar donde puede arreglar la imagen. Se debe cambiar el nombre de la imagen para que comience con nuestro nombre de usuario en Docker Hub. Después de esto debería ser el nombre del repositorio. Al final del nombre puede ser cualquier etiqueta. El siguiente es un ejemplo de nombrar imágenes usando este esquema.

Ahora puede recopilar la imagen con un nuevo nombre y ejecutar el comando docker pushpara enviarla al repositorio de Docker Hub.

docker build -t <username>/<repository>:<tag> .
docker tag <username>/<repository>:<tag> <username>/<repository>:latest
docker push <username>/<repository>:<tag>

#     , , :
docker build -t user/app:v1.0.0 .
docker tag user/app:v1.0.0 user/app:latest
docker push user/app:v1.0.0

Si todo va bien, la imagen estará disponible en Docker Hub y se puede descargar fácilmente al servidor o transferirse a otros desarrolladores.

Próximos pasos


Hasta la fecha, nos hemos asegurado de que la aplicación, en forma de contenedor Docker, funcione localmente. Subimos el contenedor al Docker Hub. Todo esto significa que ya hemos progresado muy bien hacia la meta. Ahora necesitamos resolver dos preguntas más:

  • Configuración de una herramienta de CI para probar e implementar código.
  • Configurar el servidor de producción para que pueda cargar y ejecutar nuestro código.

En nuestro caso, Travis CI se utiliza como una solución CI / CD . Como servidor: DitigalOcean .

Cabe señalar que aquí puede usar otra combinación de servicios. Por ejemplo, en lugar de Travis CI, puede usar CircleCI o Github Actions. Y en lugar de DigitalOcean: AWS o Linode.

Decidimos trabajar con Travis CI, y en este servicio ya tengo algo configurado. Por lo tanto, ahora hablaré brevemente sobre cómo prepararlo para el trabajo.

Travis ci


Travis CI es una herramienta para probar e implementar código. No me gustaría entrar en las complejidades de configurar Travis CI, ya que cada proyecto es único, y esto no traerá muchos beneficios. Pero le contaré sobre los conceptos básicos que le permitirán comenzar si decide usar Travis CI. Elijas lo que elijas: Travis CI, CircleCI, Jenkins u otra cosa, se usarán métodos de configuración similares en todas partes.

Para comenzar a trabajar con Travis CI, vaya al sitio web del proyectoy crea una cuenta. Luego integre Travis CI con su cuenta de GitHub. Durante la configuración del sistema, deberá especificar el repositorio con el que desea automatizar y habilitar el acceso al mismo. (Uso GitHub, pero estoy seguro de que Travis CI puede integrarse con BitBucket, GitLab y otros servicios similares).

Cada vez que se toma Travis CI para trabajar, se inicia un servidor que ejecuta los comandos especificados en el archivo de configuración, incluida la implementación de las ramas del repositorio correspondientes.

▍ Ciclo de vida de la tarea


El archivo de configuración de Travis CI, llamado .travis.ymly almacenado en el directorio raíz del proyecto, admite el concepto de eventos del ciclo de vida del trabajo. Estos eventos se enumeran en el orden en que ocurren:

  • apt addons
  • cache components
  • before_install
  • install
  • before_script
  • script
  • before_cache
  • after_success after_failure
  • before_deploy
  • deploy
  • after_deploy
  • after_script

▍Pruebas


En el archivo de configuración, voy a configurar el servidor local Travis CI. Como lenguaje, elegí el Nodo 12 y le dije al sistema que instalara las dependencias necesarias para usar Docker.

Todo lo que aparece en la lista .travis.ymlse ejecutará cuando se ejecuten todas las solicitudes de extracción a todas las ramas del repositorio, a menos que se especifique lo contrario. Esta es una característica útil, ya que significa que podemos probar todo el código que ingresa al repositorio. Esto le permite saber si el código está listo para ser escrito en la sucursal mastery si interrumpirá el proceso de construcción del proyecto. En esta configuración global, instalo todo localmente, inicio el servidor de desarrollo Webpack en segundo plano (esta es una característica de mi flujo de trabajo) y ejecuto las pruebas.

Si desea mostrar iconos con información sobre la cobertura del código en su repositorio, aquí puede encontrar instrucciones breves sobre el uso de Jest, Travis CI y Overol para recopilar y mostrar esta información.

Así que aquí está el contenido del archivo .travis.yml:

#  
language: node_js

#   Node.js
node_js:
  - '12'

services:
  #    Docker
  - docker

install:
  #    
  - npm ci

before_script:
  #      
  - npm run dev &

script:
  #  
  - npm run test

Aquí finalizan las acciones que se realizan para todas las ramas del repositorio y para las solicitudes de extracción.

▍ Despliegue


Basado en el supuesto de que todas las pruebas automatizadas se completaron con éxito, opcionalmente, podemos implementar el código en el servidor de producción. Dado que queremos hacer esto solo para el código de una rama master, le damos al sistema las instrucciones adecuadas en la configuración de implementación. Antes de intentar usar el código en su proyecto, que consideraremos más adelante, me gustaría advertirle que debe tener un script real que se llame para su implementación.

deploy:
  #  Docker-     Docker Hub
  provider: script
  script: bash deploy.sh
  on:
    branch: master

El script de implementación resuelve dos problemas:

  • Cree, etiquete y envíe la imagen al Docker Hub utilizando la herramienta CI (en nuestro caso, es Travis CI).
  • Cargando la imagen en el servidor, deteniendo el contenedor antiguo e iniciando el nuevo (en nuestro caso, el servidor se ejecuta en la plataforma DigitalOcean).

Primero debe configurar el proceso automático de ensamblaje, etiquetado y envío de la imagen al Docker Hub. Todo esto es muy similar a lo que ya hicimos manualmente, excepto que aquí necesitamos una estrategia para asignar etiquetas únicas a las imágenes y automatizar el inicio de sesión. Tuve dificultades con algunos detalles del script de implementación, como una estrategia de etiquetado, iniciar sesión, codificar claves SSH, establecer una conexión SSH. Pero, afortunadamente, mi novio maneja bash muy bien, así como muchas otras cosas. Me ayudó a escribir este guión.

Entonces, la primera parte del script es enviar la imagen al Docker Hub. Esto es bastante simple El esquema de etiquetado que utilicé implica combinar un git hash y una etiqueta git, si existe. Esto permite la creación de una etiqueta única y simplifica la identificación del ensamblaje en el que se basa. DOCKER_USERNAMEy DOCKER_PASSWORDson variables de entorno del usuario que se pueden configurar mediante la interfaz Travis CI. Travis CI procesa automáticamente los datos confidenciales para que no caigan en las manos equivocadas.

Aquí está la primera parte del guión deploy.sh.

#!/bin/sh
set -e #     

IMAGE="<username>/<repository>"                             #  Docker
GIT_VERSION=$(git describe --always --abbrev --tags --long) # Git-  

#    
docker build -t ${IMAGE}:${GIT_VERSION} .
docker tag ${IMAGE}:${GIT_VERSION} ${IMAGE}:latest

#   Docker Hub   
echo "${DOCKER_PASSWORD}" | docker login -u "${DOCKER_USERNAME}" --password-stdin
docker push ${IMAGE}:${GIT_VERSION}

Lo que será la segunda parte del script depende completamente de qué host está utilizando y cómo está organizada la conexión. En mi caso, dado que uso Digital Ocean, los comandos doctl se usan para conectarse al servidor . Cuando trabaje con Aws, se utilizará una utilidad aws, etc.

Configurar el servidor no fue particularmente difícil. Entonces, configuré una gota basada en la imagen base. Cabe señalar que el sistema que seleccioné requiere una instalación manual única de Docker y un inicio manual único de Docker. Usé Ubuntu 18.04 para instalar Docker, así que si usas Ubuntu para hacer lo mismo, puedes seguir esta sencilla guía.

No estoy hablando aquí de comandos específicos para el servicio, ya que este aspecto puede variar mucho en diferentes casos. Solo daré un plan de acción general que se lleva a cabo después de conectarse a través de SSH al servidor en el que se implementará el proyecto:

  • Necesita encontrar el contenedor que se está ejecutando actualmente y detenerlo.
  • Luego, en segundo plano, debe iniciar un nuevo contenedor.
  • Deberá establecer el puerto del servidor local en un valor 80; esto le permitirá ingresar al sitio en la dirección del formulario example.com, sin especificar el puerto, y no usar la dirección como example.com:5000.
  • Y, por último, debe eliminar todos los contenedores e imágenes antiguos.

Aquí está la continuación del guión.

#  ID  
CONTAINER_ID=$(docker ps | grep takenote | cut -d" " -f1)

#   ,  ,  
docker stop ${CONTAINER_ID}
docker run --restart unless-stopped -d -p 80:5000 ${IMAGE}:${GIT_VERSION}
docker system prune -a -f

Algunas cosas a considerar


Quizás cuando se conecte al servidor a través de SSH desde Travis CI, verá una advertencia que no permitirá que la instalación continúe, ya que el sistema esperará a que el usuario responda.

The authenticity of host '<hostname> (<IP address>)' can't be established.
RSA key fingerprint is <key fingerprint>.
Are you sure you want to continue connecting (yes/no)?

Aprendí que la clave de cadena se puede codificar en base64 para guardarla en una forma en que sea conveniente y confiable trabajar con ella. En la etapa de instalación, puede decodificar la clave pública y escribirla en un archivo known_hostspara deshacerse del error anterior.

echo <public key> | base64 #  < ,   base64>

En la práctica, este comando puede verse así:

echo "123.45.67.89 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU
GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3
Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA
t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En
mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx
NrRFi9wrf+M7Q== you@example.com" | base64

Y esto es lo que da: una cadena codificada en base64:

MTIzLjQ1LjY3Ljg5IHNzaC1yc2EgQUFBQUIzTnphQzF5YzJFQUFBQUJJd0FBQVFFQWtsT1Vwa0RIcmZIWTE3U2JybVRJcE5MVEdLOVRqb20vQldEU1UKR1BsK25hZnpsSERUWVc3aGRJNHlaNWV3MThKSDRKVzlqYmhVRnJ2aVF6TTd4bEVMRVZmNGg5bEZYNVFWa2JQcHBTd2cwY2RhMwpQYnY3a09kSi9NVHlCbFdYRkNSK0hBbzNGWFJpdEJxeGlYMW5LaFhwSEFac01jaUxxOFY2UmpzTkFRd2RzZE1GdlNsVksvN1hBCnQzRmFvSm9Bc25jTTFROXg1KzNWMFd3NjgvZUlGbWIxenVVRmxqUUpLcHJyWDg4WHlwTkR2allOYnk2dncvUGIwcndlcnQvRW4KbVorQVc0T1pQblRQSTg5WlBtVk1MdWF5ckQyY0U4NlovaWw4YitndzNyMysxbkthdG1Ja2puMnNvMWQwMVFyYVRsTXFWU3NieApOclJGaTl3cmYrTTdRPT0geW91QGV4YW1wbGUuY29tCg==

Aquí está el equipo mencionado anteriormente

install:
  - echo <  ,   base64> | base64 -d >> $HOME/.ssh/known_hosts

Se puede usar el mismo enfoque con una clave privada cuando se establece una conexión, ya que es posible que necesite una clave privada para acceder al servidor. Cuando trabaje con una clave, solo necesita garantizar su almacenamiento seguro en la variable de entorno de Travis CI, para que no se muestre en ningún lado.

Otra cosa a la que debe prestar atención es que puede necesitar ejecutar todo el script de implementación, presentado como una sola línea, por ejemplo, usando doctl. Esto puede requerir un esfuerzo adicional.

doctl compute ssh <droplet> --ssh-command "    && "

TLS / SSL y equilibrio de carga


Después de hacer todo lo que se discutió anteriormente, el último problema que surgió ante mí fue que el servidor no tenía SSL. Como utilizo el servidor Node.js, para que los NXEX y Let's Encrypt Proxys revertidos funcionen , necesito jugar mucho.

Realmente no tenía ganas de hacer todas estas configuraciones SSL manualmente, así que creé un equilibrador de carga y grabé información al respecto en DNS. En el caso de DigitalOcean, por ejemplo, la creación de un certificado autofirmado autofirmado en un equilibrador de carga es un procedimiento simple, gratuito y rápido. Este enfoque tiene una ventaja adicional que, si es necesario, hace que sea muy fácil configurar SSL en una variedad de servidores que ejecutan un equilibrador de carga. Esto permite a los propios servidores no "pensar" en absoluto sobre SSL, sino usar el puerto como de costumbre 80. Por lo tanto, configurar SSL en un equilibrador de carga es mucho más simple y conveniente que los métodos de configuración SSL alternativos.

Ahora puede cerrar en el servidor todos los puertos que aceptan conexiones entrantes, excepto el puerto 80utilizado para la comunicación con el equilibrador de carga y el puerto 22para SSH. Como resultado, un intento de acceder directamente al servidor en cualquier puerto, con la excepción de estos dos, fallará.

Resumen


Después de hacer todo lo que se describe en este artículo, ya no tenía miedo de la plataforma Docker o del concepto de cadenas automatizadas de CI / CD. Pude configurar una cadena de integración continua, durante la cual se prueba el código antes de que entre en producción y el código se implementa automáticamente en el servidor. Todo esto para mí todavía es relativamente nuevo, y estoy seguro de que hay formas de mejorar mi flujo de trabajo automatizado y hacerlo más eficiente. Por lo tanto, si usted tiene alguna idea sobre este tema, dejar que me sé. Espero que este artículo te haya ayudado en tus asuntos. Quiero creer que después de leerlo, has aprendido tanto como yo, mientras descubrí todo lo que te dije al respecto.

PD: hay una imagen en nuestro mercadoDocker , que se instala con un solo clic. Puede verificar el funcionamiento de los contenedores en VPS . Todos los nuevos clientes tienen 3 días gratuitos para realizar las pruebas.

¡Queridos lectores! ¿Utiliza tecnologías CI / CD en sus proyectos?


All Articles