Creando una cadena CI/CD y automatizando el trabajo con Docker

Escribí mis primeros sitios web a finales de los 90. Entonces fue muy fácil ponerlos en condiciones de funcionar. Había un servidor Apache en algún alojamiento compartido, se podía acceder a este servidor a través de FTP escribiendo en la línea del navegador algo como ftp://ftp.example.com. Luego era necesario ingresar un nombre y contraseña y subir los archivos al servidor. Hubo otros tiempos, entonces todo era más sencillo que ahora.

Creando una cadena CI/CD y automatizando el trabajo con Docker

Las cosas han cambiado mucho en las últimas dos décadas. Los sitios se han vuelto más complejos, deben ensamblarse antes de lanzarse a producción. Un único servidor se ha convertido en muchos servidores que se ejecutan detrás de balanceadores de carga y el uso de sistemas de control de versiones se ha vuelto 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 rama. master en GitHub. También sabía que no quería administrar un enorme clúster de Kubernetes, ni utilizar la tecnología Docker Swarm, ni mantener un parque de servidores con pods, agentes y todo tipo de otras complejidades para ejecutar mi pequeña aplicación web. Para lograr el objetivo de facilitar al máximo el trabajo, necesitaba familiarizarme con CI/CD.

Si tiene un proyecto pequeño (en nuestro caso, 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 con lo que funciona en producción, creo Quizás te interese este artículo.

Prerrequisitos

Se espera que el lector de este artículo tenga conocimientos básicos de línea de comandos y scripting Bash. Además, necesitará cuentas. Travis CI и Centro acoplable.

Objetivos

No diré que este artículo pueda llamarse incondicionalmente una "guía de formación". Este es más bien un documento en el que hablo sobre lo que aprendí y describo el proceso que más me conviene para probar e implementar código en producción, realizado en una sola pasada automatizada.

Así es como terminó luciendo mi flujo de trabajo.

Para código enviado a cualquier rama del repositorio que no sea master, se realizan las siguientes acciones:

  • Comienza la construcción del proyecto en Travis CI.
  • Se realizan todas las pruebas unitarias, de integración y de extremo a extremo.

Sólo para el código que termina en master, se hace lo siguiente:

  • Todo lo anterior, más...
  • Creación de una imagen de Docker basada en el código, la configuración y el entorno actuales.
  • Alojar la imagen en Docker Hub.
  • Conexión al servidor de producción.
  • Subir una imagen desde Docker Hub al servidor.
  • Detenga el contenedor actual e inicie uno nuevo basado en la nueva imagen.

Si no sabes absolutamente nada sobre Docker, imágenes y contenedores, no te preocupes. Te lo contaré todo.

¿Qué es CI/CD?

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

▍Integración continua

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

▍Implementación continua

La implementación continua es la implementación automatizada frecuente de código en producción. La segunda parte de la abreviatura CI / CD a veces se identifica como "entrega continua" ("entrega continua"). Esto es básicamente lo mismo que la "implementación continua", pero la "entrega continua" implica que los cambios deben confirmarse manualmente antes de iniciar el proceso de implementación del proyecto.

Primeros pasos

La aplicación en la que dominé todo esto se llama Tomar nota. Este es un proyecto web en el que estoy trabajando para tomar notas. Primero intenté hacer JAMstack-proyecto, o simplemente una aplicación front-end sin servidor, para aprovechar las opciones estándar de alojamiento e implementación de proyectos que ofrece Netlify. A medida que crecía la complejidad de la aplicación, necesitaba crear su back-end, lo que significaba que tendría que formular mi propia estrategia para la integración y la implementación automatizadas del proyecto.

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

Consulté con otro, que es un experto en automatización, y le pregunté qué debo hacer para que todo funcione como quiero. Me dio una idea de cómo debería ser el flujo de trabajo automatizado descrito en la sección Objetivos de este artículo. Establecer objetivos como este significaba que necesitaba descubrir cómo usar Docker.

Docker

Docker es una herramienta que, gracias a la tecnología de contenedorización, facilita la distribución de aplicaciones, así como su implementación y ejecución en el mismo entorno, incluso si la propia plataforma Docker se ejecuta en entornos diferentes. Primero, necesitaba tener en mis manos las herramientas de línea de comandos (CLI) de Docker. Instrucción La guía de instalación de Docker no es muy clara, pero puedes aprender de ella que para dar el primer paso de la instalación, necesitas descargar Docker Desktop (para Mac o Windows).

Docker Hub es casi lo mismo que GitHub para repositorios git o registro npm para paquetes de JavaScript. Este es un repositorio en línea para imágenes de Docker. Aquí es donde se conecta Docker Desktop.

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

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

docker -v

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

docker login

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

▍Imágenes

Una imagen es una especie de plano 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 imágenes fácilmente.

# Вывод сведений обо всех образах
docker images

Este comando generará una tabla con el siguiente título:

REPOSITORY     TAG     IMAGE ID     CREATED     SIZE
---

A continuación, consideraremos algunos ejemplos de comandos en el mismo formato: primero hay 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 necesario 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. Estamos hablando de que se lanzan instancias de la misma imagen en diferentes entornos.

# Перечисление всех контейнеров
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.

▍Referencia rápida para los comandos de Docker

A continuación se ofrece una descripción general de algunos comandos de Docker utilizados habitualmente.

Equipo

Contexto

Действие

Docker Build

Imagen

Construyendo una imagen a partir de un Dockerfile

etiqueta acoplable

Imagen

Etiquetado de imágenes

ventana acoplable

Imagen

Mostrar una lista de imágenes

Docker Run

envase

Ejecutar un contenedor basado en imágenes

docker push

Imagen

Envío de una imagen al Registro

estirar del estibador

Imagen

Cargando una imagen del Registro

docker ps

envase

Listado de contenedores

poda del sistema acoplable

Imagen/Contenedor

Eliminar contenedores e imágenes no utilizados

▍Archivo Docker

Sé cómo ejecutar una aplicación de producción localmente. Tengo una configuración de paquete web para crear una aplicación React terminada. 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 experimentos, cualquier aplicación de Nodo simple servirá.

Para utilizar el contenedor, deberá darle instrucciones a Docker. Esto se hace a través de un archivo llamado Dockerfileubicado en el directorio raíz del proyecto. Este expediente, al principio, parece bastante incomprensible.

Pero lo que contiene sólo describe, en comandos especiales, algo así como configurar un entorno de trabajo. Éstos son algunos de esos comandos:

  • DESDE — Este comando inicia un archivo. Especifica la imagen base a partir de la cual se construye el contenedor.
  • COPIA - Copiar archivos de una fuente local a un contenedor.
  • DIR.TRABAJO - Configurar el directorio de trabajo para los siguientes comandos.
  • CORRE - Ejecutar comandos.
  • EXPOSICION — Configuración del puerto.
  • PUNTO DE ENTRADA — Una indicación del comando a ejecutar.

Dockerfile podría verse algo como esto:

# Загрузить базовый образ
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 que elija, es posible que necesite instalar dependencias adicionales. El hecho es que algunas imágenes base (como Node Alpine Linux) están diseñadas para ser lo más compactas posible. Como resultado, es posible que no incluyan algunos de los programas que espera.

▍Construir, etiquetar y ejecutar un contenedor

El montaje local y la puesta en servicio del contenedor se realiza, una vez que hayamos Dockerfilelas tareas son bastante simples. Antes de enviar una imagen a Docker Hub, es necesario probarla localmente.

▍Montaje

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

# Сборка образа
docker build -t <image>:<tag> .

Después de ejecutar este comando, puede ver 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>

La construcción puede llevar un par de minutos; todo depende de cuántas dependencias tenga. Una vez completada la compilación, puede ejecutar el comando docker images y echa un vistazo a la descripción de tu nueva imagen.

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

▍Lanzamiento

La imagen ha sido creada. Y esto significa que, sobre esta base, puede ejecutar un contenedor. Como quiero poder acceder a la aplicación que se ejecuta en el contenedor en localhost:5000, i, en el lado izquierdo del par 5000:5000 en el siguiente conjunto de comandos 5000. En el lado derecho está el puerto de contenedores.

# Запуск с использованием локального порта 5000 и порта контейнера 5000
docker run -p 5000:5000 <image>:<tag>

Ahora que el contenedor está creado y ejecutándose, puede usar el comando docker ps para ver información sobre este contenedor (o puede usar el comando docker ps -a, que muestra información sobre todos los contenedores, no solo los que se están ejecutando).

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 ahora vas a localhost:5000 - puede ver la página de la aplicación en ejecución, que tiene exactamente el mismo aspecto que la página de la aplicación que se ejecuta en el entorno de producción.

▍Asignación y publicación de etiquetas

Para utilizar una de las imágenes creadas en el servidor de producción, debemos poder descargar esta imagen desde Docker Hub. Esto significa que primero debes crear un repositorio para el proyecto en Docker Hub. Posteriormente tendremos a nuestra disposición un lugar donde podrás enviar la imagen. Es necesario cambiar el nombre de la imagen para que su nombre comience con nuestro nombre de usuario de Docker Hub. Esto debe ir seguido del nombre del repositorio. Se puede colocar cualquier etiqueta al final del nombre. A continuación se muestra un ejemplo de cómo nombrar imágenes según este esquema.

Ahora puede crear la imagen con un nuevo nombre asignado y ejecutar el comando docker push para enviarlo 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 podrá cargarse fácilmente en el servidor o compartirse con otros desarrolladores.

Próximos pasos

Hasta ahora, hemos verificado que la aplicación, en forma de contenedor Docker, se está ejecutando localmente. Hemos subido el contenedor a Docker Hub. Todo esto significa que ya hemos avanzado mucho hacia nuestro objetivo. 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 descargar y ejecutar nuestro código.

En nuestro caso, como solución CI / CD, utilizamos Travis CI. Como servidor - Océano Digital.

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

Decidimos trabajar con Travis CI y ya tengo algo configurado en este servicio. 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 quiero entrar en detalles sobre la configuración de Travis CI, ya que cada proyecto es único y no será de mucha utilidad. Pero cubriré los conceptos básicos para que pueda comenzar si decide utilizar Travis CI. Elija lo que elija: Travis CI, CircleCI, Jenkins u otra cosa, se aplicarán métodos de configuración similares en todas partes.

Para comenzar con Travis CI, vaya a sitio del proyecto y crear una cuenta. Luego integre Travis CI con su cuenta de GitHub. Al configurar el sistema, deberá especificar el repositorio que desea automatizar y habilitar el acceso a él. (Uso GitHub, pero estoy seguro de que Travis CI puede integrarse con BitBucket, GitLab y otros servicios similares).

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

▍Ciclo de vida del trabajo

Archivo de configuración de Travis CI llamado .travis.yml y almacenado en el directorio raíz del proyecto, admite el concepto de eventos ciclo vital tareas. Aquí están los eventos, enumerados 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 un servidor Travis CI local. Elegí el nodo 12 como idioma y le dije al sistema que instalara las dependencias necesarias para usar Docker.

Todo lo que figura en .travis.yml, se ejecutará en todas las solicitudes de extracción en 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 escribirse en la sucursal. mastery si interrumpirá el proceso de construcción del proyecto. En esta configuración global, instalo todo localmente, ejecuto el servidor de desarrollo Webpack en segundo plano (esta es una característica de mi flujo de trabajo) y ejecuto las pruebas.

Si desea que su repositorio muestre íconos de cobertura de código, aquí Puede encontrar un tutorial rápido sobre cómo utilizar Jest, Travis CI y Coveralls 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í es donde terminan las acciones que se realizan para todas las ramas del repositorio y para las solicitudes de extracción.

▍Implementación

Partiendo del supuesto de que todas las pruebas automatizadas se han completado correctamente, opcionalmente podemos implementar el código en el servidor de producción. Ya que sólo queremos hacer esto para el código de sucursal master, le damos al sistema las instrucciones apropiadas en la configuración de implementación. Antes de intentar utilizar el código que veremos a continuación en su proyecto, me gustaría advertirle que debe tener un script real llamado para su implementación.

deploy:
  # Собрать Docker-контейнер и отправить его на Docker Hub
  provider: script
  script: bash deploy.sh
  on:
    branch: master

El script de implementación hace dos cosas:

  • Construir, etiquetar y enviar la imagen a Docker Hub usando una herramienta CI (en nuestro caso es Travis CI).
  • Cargando la imagen en el servidor, deteniendo el contenedor antiguo e iniciando uno nuevo (en nuestro caso, el servidor se ejecuta en la plataforma DigitalOcean).

Primero, debe configurar un proceso automático para crear, etiquetar y enviar la imagen a 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 la estrategia de etiquetado, el inicio de sesión, la codificación de claves SSH y el establecimiento de una conexión SSH. Pero afortunadamente mi novio es muy bueno con bash, además de con muchas otras cosas. Él me ayudó a escribir este guión.

Entonces, la primera parte del script es enviar la imagen a Docker Hub. Hacer esto es bastante simple. El esquema de etiquetado que he usado implica combinar el hash de git y la etiqueta de git, si existe. Esto garantiza que la etiqueta sea única y facilita la identificación del conjunto en el que se basa. DOCKER_USERNAME и DOCKER_PASSWORD son variables de entorno definidas por el usuario que se pueden configurar mediante la interfaz Travis CI. Travis CI procesará automáticamente datos confidenciales para que no caigan en las manos equivocadas.

Aquí tenéis 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 del host que esté utilizando y de cómo esté organizada la conexión. En mi caso como uso Digital Ocean los comandos sirven para conectarme al servidor doctor. Cuando se trabaja con Aws, se utilizará la utilidad. awsetc.

Configurar el servidor no fue particularmente difícil. Entonces, configuré una gota basada en la imagen base. Cabe señalar que el sistema que elegí requiere una instalación manual de Docker por única vez y un inicio manual de Docker por única vez. Usé Ubuntu 18.04 para instalar Docker, así que si también estás usando Ubuntu puedes seguir esta orientación sencilla.

No me refiero aquí a comandos específicos para el servicio, ya que este aspecto puede variar mucho en diferentes casos. Solo daré un plan de acción general a realizar después de conectarnos vía SSH al servidor donde se implementará el proyecto:

  • Debe encontrar el contenedor que se está ejecutando actualmente y detenerlo.
  • Luego necesitas iniciar un nuevo contenedor en segundo plano.
  • Deberá configurar el puerto local del servidor en 80 - esto le permitirá ingresar al sitio en la dirección del formulario example.com, sin especificar un puerto, en lugar de utilizar una dirección como example.com:5000.
  • Y finalmente, debe eliminar todos los contenedores e imágenes antiguos.

Aquí tenéis 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 tener en cuenta

Es posible que al conectarte al servidor vía SSH desde Travis CI, veas un aviso que no te permitirá continuar con la instalación, ya que el sistema esperará la respuesta del usuario.

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 una clave de cadena se puede codificar en base64 para almacenarla en una forma en la que se pueda trabajar con ella de manera conveniente y confiable. En la etapa de instalación, puede decodificar la clave pública y escribirla en un archivo. known_hosts para deshacerse del error anterior.

echo <public key> | base64 # выводит <публичный ключ, закодированный в base64>

En la práctica, este comando podría 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== [email protected]" | base64

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

MTIzLjQ1LjY3Ljg5IHNzaC1yc2EgQUFBQUIzTnphQzF5YzJFQUFBQUJJd0FBQVFFQWtsT1Vwa0RIcmZIWTE3U2JybVRJcE5MVEdLOVRqb20vQldEU1UKR1BsK25hZnpsSERUWVc3aGRJNHlaNWV3MThKSDRKVzlqYmhVRnJ2aVF6TTd4bEVMRVZmNGg5bEZYNVFWa2JQcHBTd2cwY2RhMwpQYnY3a09kSi9NVHlCbFdYRkNSK0hBbzNGWFJpdEJxeGlYMW5LaFhwSEFac01jaUxxOFY2UmpzTkFRd2RzZE1GdlNsVksvN1hBCnQzRmFvSm9Bc25jTTFROXg1KzNWMFd3NjgvZUlGbWIxenVVRmxqUUpLcHJyWDg4WHlwTkR2allOYnk2dncvUGIwcndlcnQvRW4KbVorQVc0T1pQblRQSTg5WlBtVk1MdWF5ckQyY0U4NlovaWw4YitndzNyMysxbkthdG1Ja2puMnNvMWQwMVFyYVRsTXFWU3NieApOclJGaTl3cmYrTTdRPT0geW91QGV4YW1wbGUuY29tCg==

Aquí está el comando mencionado anteriormente.

install:
  - echo < публичный ключ, закодированный в base64> | base64 -d >> $HOME/.ssh/known_hosts

El mismo enfoque se puede utilizar con una clave privada al establecer una conexión, ya que es posible que necesite una clave privada para acceder al servidor. Cuando trabaje con una clave, solo necesita asegurarse de que esté almacenada de forma segura en una variable de entorno de Travis CI y que no se muestre en ninguna parte.

Otra cosa a tener en cuenta es que es posible que deba ejecutar todo el script de implementación como una sola línea, por ejemplo, con 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 anterior, el último problema que tuve fue que el servidor no tenía SSL. Como estoy usando un servidor Node.js, para forzar работать proxy inverso Nginx y Let's Encrypt, necesitas jugar mucho.

Realmente no quería hacer todas estas configuraciones de SSL manualmente, así que solo creé un balanceador de carga y registré información al respecto en DNS. En el caso de DigitalOcean, por ejemplo, crear un certificado autofirmado de renovación automática en el balanceador de carga es un procedimiento simple, gratuito y rápido. Este enfoque tiene el beneficio adicional de hacer que sea muy fácil configurar SSL en varios servidores que se ejecutan detrás de un balanceador de carga si es necesario. Esto permite que los propios servidores no "piensen" en absoluto en SSL, pero al mismo tiempo utilicen, como de costumbre, el puerto 80. Por lo tanto, configurar SSL en un balanceador de carga es mucho más fácil y conveniente que los métodos de configuración SSL alternativos.

Ahora puede cerrar todos los puertos del servidor que aceptan conexiones entrantes, excepto el puerto 80, utilizado para comunicarse con el equilibrador de carga y el puerto 22 para SSH. Como resultado, cualquier intento de contactar directamente con el servidor en cualquier puerto distinto de estos dos fallará.

resultados

Después de hacer todo lo que hablé en este artículo, ni la plataforma Docker ni el concepto de cadenas CI/CD automatizadas me asustaron más. Pude configurar una cadena de integración continua, durante la cual el código se prueba antes de entrar en producción y el código se implementa automáticamente en el servidor. Todo esto todavía es relativamente nuevo para mí y estoy seguro de que hay formas de mejorar mi flujo de trabajo automatizado y hacerlo más eficiente. Entonces, si tienes alguna idea sobre esto, dale me saber. Espero que este artículo te haya ayudado en tus esfuerzos. Quiero creer que al leerlo aprendiste tanto como yo aprendí mientras yo lidiaba con todo lo que en él contaba.

PS En nuestro mercado hay una imagen Docker, que se instala con un solo clic. Puedes comprobar el funcionamiento de los contenedores. VPS. Todos los nuevos clientes reciben 3 días de prueba de forma gratuita.

Estimados lectores! ¿Utilizas tecnologías CI/CD en tus proyectos?

Creando una cadena CI/CD y automatizando el trabajo con Docker

Fuente: habr.com

Añadir un comentario