Criando uma cadeia CI/CD e automatizando o trabalho com Docker

Escrevi meus primeiros sites no final dos anos 90. Naquela época era muito fácil colocá-los em funcionamento. Havia um servidor Apache em alguma hospedagem compartilhada, você poderia fazer login neste servidor via FTP escrevendo algo como ftp://ftp.example.com. Então você teve que inserir seu nome e senha e enviar os arquivos para o servidor. Houve tempos diferentes, tudo era mais simples do que agora.

Criando uma cadeia CI/CD e automatizando o trabalho com Docker

Nas duas décadas desde então, tudo mudou muito. Os sites se tornaram mais complexos; eles devem ser montados antes de serem lançados em produção. Um único servidor tornou-se muitos servidores rodando atrás de balanceadores de carga, e o uso de sistemas de controle de versão tornou-se comum.

Para o meu projeto pessoal tive uma configuração especial. E eu sabia que precisava implantar o site em produção executando apenas uma ação: escrever código em uma ramificação master no GitHub. Além disso, eu sabia que para garantir o funcionamento da minha pequena aplicação web, não queria gerenciar um enorme cluster Kubernetes, nem usar a tecnologia Docker Swarm, nem manter uma frota de servidores com pods, agentes e todo tipo de outros complexidades. Para atingir o objetivo de facilitar ao máximo o trabalho, precisei me familiarizar com CI/CD.

Se você tem um projeto pequeno (neste caso, um projeto Node.js) e gostaria de saber como automatizar a implantação deste projeto, garantindo ao mesmo tempo que o que está armazenado no repositório corresponde exatamente ao que funciona na produção, então eu acho que você pode estar interessado neste artigo.

Pré-requisitos

Espera-se que o leitor deste artigo tenha um conhecimento básico da linha de comando e da escrita de scripts Bash. Além disso, ele precisará de contas Travis C.I. и Hub do Docker.

Objetivos

Não direi que este artigo possa ser incondicionalmente chamado de “tutorial”. Este é mais um documento no qual falo sobre o que aprendi e descrevo o processo que me convém para testar e implantar código em produção, realizado em uma passagem automatizada.

Foi assim que meu fluxo de trabalho acabou sendo.

Para código postado em qualquer ramificação do repositório, exceto master, as seguintes ações são executadas:

  • A construção do projeto no Travis CI é iniciada.
  • Todos os testes unitários, de integração e ponta a ponta são realizados.

Somente para código que se enquadra master, é realizado o seguinte:

  • Tudo o que foi mencionado acima, mais...
  • Construindo uma imagem Docker com base no código, configurações e ambiente atuais.
  • Implantando a imagem no Docker Hub.
  • Conexão com o servidor de produção.
  • Fazendo upload de uma imagem do Docker Hub para o servidor.
  • Interrompendo o contêiner atual e iniciando um novo com base na nova imagem.

Se você não sabe absolutamente nada sobre Docker, imagens e containers, não se preocupe. Eu vou te contar tudo sobre isso.

O que é CI/CD?

A abreviatura CI/CD significa “integração contínua/implantação contínua”.

▍Integração contínua

A integração contínua é um processo no qual os desenvolvedores fazem commits no repositório de código-fonte principal do projeto (geralmente um branch master). Ao mesmo tempo, a qualidade do código é garantida através de testes automatizados.

▍Implantação contínua

A implantação contínua é a implantação frequente e automatizada de código na produção. A segunda parte da sigla CI/CD às vezes é escrita como “entrega contínua”. Isto é basicamente o mesmo que “implantação contínua”, mas “entrega contínua” implica a necessidade de confirmar manualmente as alterações antes de iniciar o processo de implantação do projeto.

Introdução

O aplicativo que usei para aprender tudo isso se chama Tome nota. Este é um projeto web em que estou trabalhando, projetado para fazer anotações. No começo eu tentei fazer JAMStack-project, ou apenas um aplicativo front-end sem servidor, para aproveitar as vantagens dos recursos padrão de hospedagem e implantação de projetos que ele oferece Netlify. À medida que a complexidade do aplicativo crescia, precisei criar sua parte de servidor, o que significava que precisaria formular minha própria estratégia para integração automatizada e implantação automatizada do projeto.

No meu caso, o aplicativo é um servidor Express rodando no ambiente Node.js, servindo um aplicativo React de página única e suportando uma API segura do lado do servidor. Esta arquitetura segue a estratégia que pode ser encontrada em esta Guia de autenticação de pilha completa.

eu consultei com другом, que é especialista em automação, e perguntei o que eu precisava fazer para que tudo funcionasse do jeito que eu queria. Ele me deu a ideia de como deveria ser um fluxo de trabalho automatizado, descrita na seção Metas deste artigo. Ter esses objetivos significava que eu precisava descobrir como usar o Docker.

Estivador

Docker é uma ferramenta que, graças à tecnologia de conteinerização, permite que aplicações sejam facilmente distribuídas, implantadas e executadas no mesmo ambiente, mesmo que a própria plataforma Docker seja executada em ambientes diferentes. Primeiro, eu precisava colocar as mãos nas ferramentas de linha de comando (CLI) do Docker. Instrução O guia de instalação do Docker não pode ser considerado muito claro e compreensível, mas com ele você pode aprender que para dar o primeiro passo de instalação, você precisa baixar o Docker Desktop (para Mac ou Windows).

Docker Hub é praticamente a mesma coisa que GitHub para repositórios git ou registro npm para pacotes JavaScript. Este é um repositório online para imagens Docker. É a isso que o Docker Desktop se conecta.

Portanto, para começar a usar o Docker, você precisa fazer duas coisas:

Depois disso, você pode verificar se o Docker CLI está funcionando executando o seguinte comando para verificar a versão do Docker:

docker -v

Em seguida, faça login no Docker Hub digitando seu nome de usuário e senha quando solicitado:

docker login

Para usar o Docker, você deve compreender os conceitos de imagens e contêineres.

▍Imagens

Uma imagem é algo como um projeto que contém instruções para montar o contêiner. Este é um instantâneo imutável do sistema de arquivos e das configurações do aplicativo. Os desenvolvedores podem compartilhar imagens facilmente.

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

Este comando gerará uma tabela com o seguinte cabeçalho:

REPOSITORY     TAG     IMAGE ID     CREATED     SIZE
---

A seguir veremos alguns exemplos de comandos no mesmo formato - primeiro há um comando com um comentário e depois um exemplo do que ele pode gerar.

▍Contêineres

Um contêiner é um pacote executável que contém tudo o que é necessário para executar um aplicativo. Uma aplicação com essa abordagem funcionará sempre da mesma forma, independente da infraestrutura: em um ambiente isolado e no mesmo ambiente. A questão é que instâncias da mesma imagem são lançadas em ambientes diferentes.

# Перечисление всех контейнеров
docker ps -a
CONTAINER ID     IMAGE     COMMAND     CREATED     STATUS     PORTS     NAMES
---

▍Tags

Uma tag é uma indicação de uma versão específica de uma imagem.

▍Uma ​​referência rápida aos comandos do Docker

Aqui está uma visão geral de alguns comandos do Docker comumente usados.

Equipe

Contexto

Ação

construção do docker

Image

Construindo uma imagem a partir de um Dockerfile

etiqueta docker

Image

Marcação de imagens

imagens docker

Image

Listando imagens

Docker Run

recipiente

Executando um contêiner com base em uma imagem

empurrão do docker

Image

Fazendo upload de uma imagem para o registro

puxão de encaixe

Image

Carregando uma imagem do registro

Docker PS

recipiente

Listando contêineres

remoção do sistema docker

Imagem/Contêiner

Removendo contêineres e imagens não utilizados

▍Arquivo Docker

Eu sei como executar um aplicativo de produção localmente. Eu tenho uma configuração do Webpack projetada para construir um aplicativo React pronto. A seguir, tenho um comando que inicia um servidor baseado em Node.js na porta 5000. Se parece com isso:

npm i         # установка зависимостей
npm run build # сборка React-приложения
npm run start # запуск Node-сервера

Deve-se observar que não tenho um exemplo de aplicação para este material. Mas aqui, para experimentos, qualquer aplicativo Node simples servirá.

Para usar o contêiner, você precisará fornecer instruções ao Docker. Isso é feito através de um arquivo chamado Dockerfile, localizado no diretório raiz do projeto. Este arquivo, a princípio, parece bastante incompreensível.

Mas o que ele contém apenas descreve, com comandos especiais, algo semelhante à configuração de um ambiente de trabalho. Aqui estão alguns desses comandos:

  • A PARTIR DE — Este comando inicia um arquivo. Ele especifica a imagem base na qual o contêiner é construído.
  • CÓPIA — Copiar arquivos de uma fonte local para um contêiner.
  • DIRTRABALHO — Configurando o diretório de trabalho para os comandos a seguir.
  • CORRE - Execute comandos.
  • EXPOR — Configurações de porta.
  • PONTO DE ENTRADA — Indicação do comando a ser executado.

Dockerfile pode ser algo assim:

# Загрузить базовый образ
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

Dependendo da imagem base escolhida, pode ser necessário instalar dependências adicionais. O fato é que algumas imagens base (como Node Alpine Linux) são criadas com o objetivo de torná-las o mais compactas possível. Como resultado, eles podem não ter alguns dos programas que você espera.

▍Construir, marcar e executar o contêiner

A montagem local e o lançamento do contêiner ocorrem depois de termos Dockerfile, as tarefas são bastante simples. Antes de enviar a imagem para o Docker Hub, você precisa testá-la localmente.

▍Montagem

Primeiro você precisa coletar imagem, especificando um nome e, opcionalmente, uma tag (se uma tag não for especificada, o sistema atribuirá automaticamente uma tag à imagem latest).

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

Depois de executar este comando, você pode observar o Docker construir a imagem.

Sending build context to Docker daemon   2.88MB
Step 1/9 : FROM node:12-alpine
 ---> ...выполнение этапов сборки...
Successfully built 123456789123
Successfully tagged <image>:<tag>

A compilação pode levar alguns minutos - tudo depende de quantas dependências você possui. Assim que a compilação for concluída, você pode executar o comando docker images e veja a descrição da sua nova imagem.

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

▍Lançamento

A imagem foi criada. Isso significa que você pode executar um contêiner baseado nele. Porque quero poder acessar o aplicativo em execução no contêiner em localhost:5000, eu, no lado esquerdo do par 5000:5000 no próximo comando instalado 5000. Do lado direito está o porto de contêineres.

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

Agora que o contêiner foi criado e em execução, você pode usar o comando docker ps para ver informações sobre este contêiner (ou você pode usar o comando docker ps -a, que exibe informações sobre todos os contêineres, não apenas sobre os que estão em execução).

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

Se você for agora para o endereço localhost:5000 — você pode ver uma página de um aplicativo em execução que se parece exatamente com a página de um aplicativo em execução em um ambiente de produção.

▍ Marcação e publicação

Para utilizar uma das imagens criadas no servidor de produção, precisamos conseguir baixar esta imagem do Docker Hub. Isso significa que primeiro você precisa criar um repositório para o projeto no Docker Hub. Depois disso, teremos um local para onde poderemos enviar a imagem. A imagem precisa ser renomeada para que seu nome comece com nosso nome de usuário Docker Hub. Isto deve ser seguido pelo nome do repositório. Qualquer tag pode ser colocada no final do nome. Abaixo está um exemplo de nomeação de imagens usando este esquema.

Agora você pode construir a imagem com um novo nome e executar o comando docker push para enviá-lo para o repositório 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

Se tudo correr bem, a imagem estará disponível no Docker Hub e poderá ser facilmente carregada no servidor ou transferida para outros desenvolvedores.

Próximos passos

Até agora verificamos que o aplicativo, na forma de um contêiner Docker, está sendo executado localmente. Carregamos o contêiner no Docker Hub. Tudo isto significa que já fizemos progressos muito bons em direcção ao nosso objectivo. Agora precisamos resolver mais duas questões:

  • Configurando uma ferramenta de CI para testar e implantar código.
  • Configurando o servidor de produção para que ele possa baixar e executar nosso código.

No nosso caso, usamos Travis C.I.. Como servidor - Ditigal Ocean.

Deve-se notar que aqui você pode usar outra combinação de serviços. Por exemplo, em vez do Travis CI, você pode usar CircleCI ou Github Actions. E em vez de DigitalOcean - AWS ou Linode.

Decidimos trabalhar com o Travis CI, e já tenho algo configurado neste serviço. Portanto, agora falarei brevemente sobre como prepará-lo para o trabalho.

Travis C.I.

Travis CI é uma ferramenta para testar e implantar código. Não gostaria de entrar nos meandros da montagem do Travis CI, pois cada projeto é único e isso não trará muitos benefícios. Mas abordarei o básico para você começar, caso decida usar o Travis CI. Quer você escolha Travis CI, CircleCI, Jenkins ou qualquer outra coisa, métodos de configuração semelhantes serão usados ​​em todos os lugares.

Para começar a usar o Travis CI, vá para site do projeto e crie uma conta. Em seguida, integre o Travis CI à sua conta GitHub. Ao configurar o sistema, você precisará especificar o repositório com o qual deseja automatizar o trabalho e permitir o acesso a ele. (Eu uso o GitHub, mas tenho certeza de que o Travis CI pode ser integrado ao BitBucket, GitLab e outros serviços semelhantes).

Cada vez que o Travis CI é iniciado, é iniciado um servidor que executa os comandos especificados no arquivo de configuração, incluindo a implantação das ramificações do repositório correspondentes.

▍Ciclo de vida do trabalho

Arquivo de configuração do Travis CI chamado .travis.yml e armazenado no diretório raiz do projeto, suporta o conceito de eventos ciclo da vida tarefas. Esses eventos estão listados na ordem em que ocorrem:

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

▍Teste

No arquivo de configuração vou configurar o servidor Travis CI local. Selecionei o Nó 12 como idioma e disse ao sistema para instalar as dependências necessárias para usar o Docker.

Tudo o que está listado em .travis.yml, será executado quando todas as solicitações pull forem feitas para todas as ramificações do repositório, a menos que especificado de outra forma. Este é um recurso útil porque significa que podemos testar todo o código que chega ao repositório. Isso permite saber se o código está pronto para ser gravado na ramificação. mastere se isso interromperá o processo de construção do projeto. Nesta configuração global, instalo tudo localmente, executo o servidor de desenvolvimento Webpack em segundo plano (este é um recurso do meu fluxo de trabalho) e executo testes.

Se você quiser que seu repositório exiba ícones de cobertura de teste, aqui Você pode encontrar instruções breves sobre como usar Jest, Travis CI e Coveralls para coletar e exibir essas informações.

Então aqui está o conteúdo do arquivo .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

É aqui que terminam as ações executadas para todas as ramificações do repositório e para solicitações pull.

▍Implantação

Com base na suposição de que todos os testes automatizados foram concluídos com êxito, podemos, o que é opcional, implantar o código no servidor de produção. Como queremos fazer isso apenas para o código do branch master, fornecemos instruções apropriadas ao sistema nas configurações de implantação. Antes de tentar usar o código que veremos a seguir em seu projeto, gostaria de avisar que você deve ter um script real chamado para implantação.

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

O script de implantação resolve dois problemas:

  • Construa, marque e envie a imagem para o Docker Hub usando uma ferramenta de CI (no nosso caso, Travis CI).
  • Carregando a imagem no servidor, parando o container antigo e iniciando um novo (no nosso caso, o servidor roda na plataforma DigitalOcean).

Primeiro, você precisa configurar um processo automático para construir, marcar e enviar a imagem para o Docker Hub. Tudo isso é muito parecido com o que já fizemos manualmente, exceto que precisamos de uma estratégia para atribuir tags exclusivas às imagens e automatizar logins. Tive dificuldade com alguns detalhes do script de implantação, como estratégia de marcação, login, codificação de chave SSH, estabelecimento de conexão SSH. Mas felizmente meu namorado é muito bom com bash, assim como com muitas outras coisas. Ele me ajudou a escrever esse roteiro.

Portanto, a primeira parte do script é fazer o upload da imagem para o Docker Hub. Isso é muito fácil de fazer. O esquema de marcação que usei envolve a combinação de um hash git e uma tag git, se existir. Isso garante que a tag seja exclusiva e facilita a identificação do assembly no qual ela se baseia. DOCKER_USERNAME и DOCKER_PASSWORD são variáveis ​​de ambiente do usuário que podem ser definidas usando a interface do Travis CI. O Travis CI processará automaticamente dados confidenciais para que não caiam em mãos erradas.

Aqui está a primeira parte do script 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}

O que será a segunda parte do script depende inteiramente de qual host você está usando e de como a conexão com ele está organizada. No meu caso, como utilizo o Digital Ocean, utilizo os comandos para conectar ao servidor documento. Ao trabalhar com AWS, o utilitário será usado awsetc.

Configurar o servidor não foi particularmente difícil. Então, configurei um droplet com base na imagem base. Deve-se observar que o sistema que escolhi requer uma instalação manual única do Docker e uma inicialização manual única do Docker. Usei o Ubuntu 18.04 para instalar o Docker, então se você também estiver usando o Ubuntu para fazer o mesmo, basta seguir este guia simples.

Não estou falando aqui de comandos específicos para o serviço, pois esse aspecto pode variar bastante em diferentes casos. Darei apenas um plano geral de ação a ser executado após a conexão via SSH ao servidor no qual o projeto será implantado:

  • Precisamos encontrar o contêiner que está em execução e interrompê-lo.
  • Então você precisa iniciar um novo contêiner em segundo plano.
  • Você precisará definir a porta local do servidor para 80 - isso permitirá que você entre no site em um endereço como example.com, sem especificar a porta, em vez de usar um endereço como example.com:5000.
  • Finalmente, você precisa excluir todos os contêineres e imagens antigos.

Aqui está a continuação do roteiro.

# Найти 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

Algumas coisas para prestar atenção

É possível que ao se conectar ao servidor via SSH do Travis CI, você veja um aviso que o impedirá de continuar com a instalação, pois o sistema aguardará a resposta do usuário.

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)?

Aprendi que uma chave de string pode ser codificada em base64 para salvá-la em um formato no qual possa ser trabalhada de maneira conveniente e confiável. Na fase de instalação, você pode decodificar a chave pública e gravá-la em um arquivo known_hosts para se livrar do erro acima.

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

Na prática, este comando pode ser assim:

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

E aqui está o que ele produz - uma string codificada em base64:

MTIzLjQ1LjY3Ljg5IHNzaC1yc2EgQUFBQUIzTnphQzF5YzJFQUFBQUJJd0FBQVFFQWtsT1Vwa0RIcmZIWTE3U2JybVRJcE5MVEdLOVRqb20vQldEU1UKR1BsK25hZnpsSERUWVc3aGRJNHlaNWV3MThKSDRKVzlqYmhVRnJ2aVF6TTd4bEVMRVZmNGg5bEZYNVFWa2JQcHBTd2cwY2RhMwpQYnY3a09kSi9NVHlCbFdYRkNSK0hBbzNGWFJpdEJxeGlYMW5LaFhwSEFac01jaUxxOFY2UmpzTkFRd2RzZE1GdlNsVksvN1hBCnQzRmFvSm9Bc25jTTFROXg1KzNWMFd3NjgvZUlGbWIxenVVRmxqUUpLcHJyWDg4WHlwTkR2allOYnk2dncvUGIwcndlcnQvRW4KbVorQVc0T1pQblRQSTg5WlBtVk1MdWF5ckQyY0U4NlovaWw4YitndzNyMysxbkthdG1Ja2puMnNvMWQwMVFyYVRsTXFWU3NieApOclJGaTl3cmYrTTdRPT0geW91QGV4YW1wbGUuY29tCg==

Aqui está o comando mencionado acima

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

A mesma abordagem pode ser usada com uma chave privada ao estabelecer uma conexão, já que você pode precisar de uma chave privada para acessar o servidor. Ao trabalhar com a chave, você só precisa garantir que ela esteja armazenada com segurança em uma variável de ambiente do Travis CI e que não seja exibida em nenhum lugar.

Outra coisa a observar é que pode ser necessário executar todo o script de implantação como uma linha, por exemplo - com doctl. Isso pode exigir algum esforço extra.

doctl compute ssh <droplet> --ssh-command "все команды будут здесь && здесь"

TLS/SSL e balanceamento de carga

Depois de fazer tudo o que foi mencionado acima, o último problema que encontrei foi que o servidor não tinha SSL. Como uso um servidor Node.js, para forçar работать proxy reverso Nginx e Let's Encrypt, você precisa mexer muito.

Eu realmente não queria fazer toda essa configuração SSL manualmente, então apenas criei um balanceador de carga e registrei seus detalhes no DNS. No caso da DigitalOcean, por exemplo, criar um certificado autoassinado com renovação automática no balanceador de carga é um procedimento simples, gratuito e rápido. Essa abordagem tem o benefício adicional de facilitar a configuração do SSL em vários servidores executados atrás de um balanceador de carga, se necessário. Isso permite que os próprios servidores não “pensem” em SSL, mas ao mesmo tempo usem a porta normalmente 80. Portanto, configurar SSL em um balanceador de carga é muito mais fácil e conveniente do que métodos alternativos de configuração de SSL.

Agora você pode fechar todas as portas do servidor que aceitam conexões de entrada - exceto a porta 80, usado para se comunicar com o balanceador de carga e a porta 22 para SSH. Como resultado, uma tentativa de acessar diretamente o servidor em qualquer porta diferente dessas duas falhará.

Resultados de

Depois de fazer tudo o que falei neste material, nem a plataforma Docker nem os conceitos de cadeias automatizadas de CI/CD me assustaram mais. Consegui configurar uma cadeia de integração contínua, durante a qual o código é testado antes de entrar em produção e é implantado automaticamente no servidor. Tudo isso ainda é relativamente novo para mim e tenho certeza de que existem maneiras de melhorar meu fluxo de trabalho automatizado e torná-lo mais eficiente. Então, se você tiver alguma idéia sobre esse assunto, por favor me avise. me saber. Espero que este artigo tenha ajudado você em seus empreendimentos. Quero acreditar que depois de lê-lo você aprendeu tanto quanto eu aprendi ao descobrir tudo o que falei nele.

PS В нашем Mercado há uma imagem Estivador, que é instalado com um clique. Você pode verificar os contêineres funcionam VPS. Todos os novos clientes recebem 3 dias de testes gratuitos.

Caros leitores! Você utiliza tecnologias CI/CD em seus projetos?

Criando uma cadeia CI/CD e automatizando o trabalho com Docker

Fonte: habr.com

Adicionar um comentário