Encadeamento de CI / CD e automação de Docker

Eu escrevi meus primeiros sites no final dos anos 90. Então trazê-los à condição de trabalho era muito simples. Havia um servidor Apache em alguma hospedagem compartilhada; era possível fazer login nesse servidor via FTP, escrevendo algo assim na linha do navegador ftp://ftp.example.com. Em seguida, foi necessário digitar um nome e senha e fazer upload de arquivos para o servidor. Houve outros momentos, tudo ficou mais fácil do que agora. Nas últimas duas décadas, tudo mudou muito. Os sites se tornaram mais complexos, devem ser montados antes de serem lançados em produção. Um único servidor tornou-se uma pluralidade de servidores trabalhando atrás de balanceadores de carga; o uso de sistemas de controle de versão tornou-se comum.





Para o meu projeto pessoal, eu tinha uma configuração especial. E sabia que precisava implantar um site em produção, executando apenas uma ação: gravar código em uma filial masterno GitHub. Além disso, eu sabia que, para garantir a operação do meu pequeno aplicativo da Web, não queria gerenciar um grande cluster Kubernetes, nem usar a tecnologia Docker Swarm, nem manter um parque de servidores com pods, agentes e todos os tipos de outras dificuldades. Para atingir o objetivo de simplificar o trabalho o máximo possível, eu precisava me familiarizar com o CI / CD.

Se você tem um projeto pequeno (no nosso caso, estamos falando de um projeto Node.js.) e gostaria de aprender sobre como automatizar a implantação desse projeto, assegurando que o que está armazenado no repositório corresponda exatamente o que funciona na produção, acho que você pode estar interessado neste artigo.

Pré-requisitos


Espera-se que o leitor deste artigo tenha conhecimentos básicos da área de linha de comando e escreva scripts Bash. Além disso, ele precisará de contas Travis CI e Docker Hub .

Metas


Não direi que este artigo possa ser incondicionalmente chamado de "manual de treinamento". É um documento no qual falo sobre o que aprendi e descrevo o processo de teste e implantação de código na produção que me convém, executada em uma passagem automatizada.

Foi assim que meu fluxo de trabalho terminou.

Exceto pelo código enviado para qualquer ramificação do repositório, as masterseguintes ações são executadas:

  • Crie o projeto no Travis CI.
  • Todos os testes de unidade, integração e ponta a ponta são realizados.

Somente para o código que entra nas masterseguintes retenções:

  • Tudo o que foi dito acima, mais ...
  • Crie a imagem do Docker com base no código, configurações e ambiente atuais.
  • Colocando uma imagem no Docker Hub.
  • Conexão com o servidor de produção.
  • Carregando a imagem do Docker Hub para o servidor.
  • Pare o contêiner atual e inicie um novo com base na nova imagem.

Se você não sabe absolutamente nada sobre o Docker, sobre imagens e contêineres - não se preocupe. Vou lhe contar tudo sobre isso.

O que é um CI / CD?


A abreviatura CI / CD significa "integração contínua / implantação contínua" - "integração contínua / implantação contínua".

Integration Integração contínua


A integração contínua é um processo durante o qual os desenvolvedores se comprometem com o repositório principal do código-fonte do projeto (geralmente em uma filial master). Ao mesmo tempo, a qualidade do código é garantida através da realização de testes automatizados.

Deployment Implantação contínua


A implantação contínua é a implantação automatizada frequente de código na produção. A segunda parte da abreviatura CI / CD às vezes é divulgada como "entrega contínua" ("entrega contínua"). Geralmente, é o mesmo que "implantação contínua", mas "entrega contínua" implica a necessidade de confirmação manual de alterações antes de iniciar o processo de implantação do projeto.

Início do trabalho


O aplicativo no qual eu dominei tudo é chamado TakeNote . Este é o projeto da Web em que estou trabalhando, projetado para fazer anotações. No começo, tentei criar um projeto JAMStack , ou apenas um aplicativo front-end sem servidor, para aproveitar os recursos padrão de hospedagem e implantação oferecidos pelo Netlify . À medida que a complexidade do aplicativo aumentava, eu precisava criar sua parte do servidor, o que significava que teria que formar minha própria estratégia para integração automatizada e implantação automatizada do projeto.

No meu caso, o aplicativo é um servidor Express em execução no ambiente Node.js., atende a um aplicativo React de página única e suporta uma API de servidor seguro. Essa arquitetura segue a estratégia encontrada neste guia de autenticação de pilha cheia.

Consultei um amigo que é especialista em automação e perguntei o que eu precisava fazer para que funcionasse da maneira que eu precisava. Ele me deu uma idéia de como deveria ser um fluxo de trabalho automatizado, descrito na seção Metas deste artigo. O fato de eu ter definido essas metas significava que precisava descobrir como usar o Docker.

Docker


O Docker é uma ferramenta que, graças à tecnologia de contêiner, facilita a distribuição de aplicativos, além de implantá-los e iniciá-los no mesmo ambiente, mesmo que a própria plataforma do Docker funcione em diferentes ambientes. Para iniciantes, eu precisava ter as ferramentas de linha de comando do Docker (CLI) à minha disposição. As instruções para instalar o Docker não podem ser consideradas muito claras e compreensíveis, mas você pode aprender com isso que, para dar o primeiro passo da instalação, é necessário fazer o download do Docker Desktop (para Mac ou Windows).

O Docker Hub é quase o mesmo que o GitHub para repositórios git ou o registro npmpara pacotes JavaScript. Este é um repositório online para imagens do Docker. Ele se conecta ao Docker Desktop.

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


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

docker -v

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

docker login

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

▍ Imagens


Uma imagem é algo como um plano que contém instruções para a construção de um 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 exibirá uma tabela com o seguinte cabeçalho:

REPOSITORY     TAG     IMAGE ID     CREATED     SIZE
---

A seguir, consideraremos alguns exemplos de comandos no mesmo formato - primeiro vem um comando com um comentário e, em seguida, um exemplo do que ele pode gerar.

▍Contêineres


Um contêiner é um pacote executável que contém tudo o que você precisa para executar um aplicativo. Um aplicativo com essa abordagem sempre funcionará da mesma maneira, independentemente da infraestrutura: em um ambiente isolado e no mesmo ambiente. O ponto é que em ambientes diferentes, instâncias da mesma imagem são iniciadas.

#   
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.

Summary Resumo do comando do Docker


Aqui está uma visão geral de alguns comandos do Docker usados ​​com freqüência.
Equipe
Contexto
Aja
construção do docker
Formato
Montando uma imagem do Dockerfile
tag docker
Formato
Marcação de imagem
imagens do docker
Formato
Listando imagens
docker run
Recipiente
Lançamento de contêiner baseado em imagem
pusher docker
Formato
Enviando uma imagem para o registro
tração docker
Formato
Baixar imagem do registro
docker ps
Recipiente
Contêiner de lista
poda do sistema docker
Imagem / Container
Remoção de contêineres e imagens não utilizados

▍ Dockerfile


Eu sei como executar um aplicativo de produção localmente. Eu tenho uma configuração Webpack projetada para criar um aplicativo React pronto. Em seguida, 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-

Note-se que não tenho um exemplo de aplicação para este material. Mas aqui, para experimentos, qualquer aplicativo Node simples é adequado.

Para usar o contêiner, você precisa dar instruções ao Docker. Isso é feito através de um arquivo chamado Dockerfilelocalizado no diretório raiz do projeto. Este arquivo, a princípio, parece bastante obscuro.

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

  • FROM - Este comando inicia um arquivo. Indica a imagem básica com base na qual o contêiner é construído.
  • COPY - Copia arquivos de uma fonte local para um contêiner.
  • WORKDIR - Definindo o diretório de trabalho para os seguintes comandos.
  • EXECUTAR - Executar comandos.
  • EXPOSIÇÃO - Configurações da porta.
  • ENTRYPOINT - Especifica o comando a ser executado.

Dockerfile pode ser algo como isto:

#   
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 selecionada, pode ser necessário instalar dependências adicionais. O fato é que algumas imagens básicas (como o Node Alpine Linux) foram projetadas para torná-las o mais compactas possível. Como resultado, eles podem não ter alguns dos programas com que você está contando.

▍ Construir, marcar e lançar contêiner


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

▍ Montagem


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

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

Após executar este comando, você pode observar como o Docker cria 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 montagem pode demorar alguns minutos - tudo depende de quantas dependências você possui. Após a montagem, você pode executar o comando docker imagese dar uma olhada na descrição da sua nova imagem.

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

▍Iniciar


A imagem é criada. E isso significa que, com base nisso, é possível lançar um contêiner. Como quero poder acessar o aplicativo em execução no contêiner no endereço localhost:5000que 5000:5000instalei no lado esquerdo do par no próximo comando 5000. No lado direito é a porta do contêiner.

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

Agora que o contêiner foi criado e iniciado, você pode usar o comando docker pspara examinar as informações sobre esse contêiner (ou pode usar o comando docker ps -aque exibe informações sobre todos os contêineres, não apenas sobre os que estão funcionando).

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 para o endereço agora localhost:5000, poderá ver a página do aplicativo em funcionamento, que parece exatamente igual à página do aplicativo em funcionamento no ambiente de produção.

▍ Atribuição e publicação de tags


Para usar uma das imagens criadas no servidor de produção, precisamos fazer o download dessa imagem no Docker Hub. Isso significa que você deve primeiro criar um repositório para o projeto no Docker Hub. Depois disso, teremos à nossa disposição um local onde você poderá consertar a imagem. A imagem deve ser renomeada para que seu nome comece com o nosso nome de usuário no Docker Hub. Depois disso, deve ser o nome do repositório. No final do nome pode haver qualquer tag. A seguir, é apresentado um exemplo de nomeação de imagens usando esse esquema.

Agora você pode coletar a imagem com um novo nome e executar o comando docker pushpara enviá-la ao repositório do 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 baixada no servidor ou transferida para outros desenvolvedores.

Próximos passos


Até o momento, garantimos que o aplicativo, na forma de um contêiner do Docker, funcione localmente. Carregamos o contêiner no Docker Hub. Tudo isso significa que já fizemos um progresso muito bom em direção à meta. Agora precisamos resolver mais duas perguntas:

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

No nosso caso, o Travis CI é usado como uma solução de CI / CD . Como servidor - DitigalOcean .

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

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

Travis ci


O Travis CI é uma ferramenta para testar e implantar código. Eu não gostaria de abordar os meandros da criação do Travis CI, já que cada projeto é único e isso não trará muitos benefícios. Mas vou falar sobre o básico que permitirá que você comece se você decidir usar o Travis CI. O que você escolher - Travis CI, CircleCI, Jenkins ou qualquer outra coisa, métodos de configuração semelhantes serão usados ​​em qualquer lugar.

Para começar a trabalhar com o Travis CI, acesse o site do projetoe crie uma conta. Em seguida, integre o Travis CI à sua conta do GitHub. Durante a configuração do sistema, você precisará especificar o repositório com o qual deseja automatizar e habilitar o acesso a ele. (Eu uso o GitHub, mas tenho certeza de que o Travis CI pode se integrar ao BitBucket, GitLab e outros serviços similares).

Cada vez que o Travis CI é levado para o trabalho, é 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 da tarefa


O arquivo de configuração do Travis CI, chamado .travis.ymle armazenado no diretório raiz do projeto, suporta o conceito de eventos do ciclo de vida do trabalho. Esses eventos sã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

▍Testes


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

Tudo o que estiver listado .travis.ymlserá executado quando todas as solicitações pull para todas as ramificações do repositório forem executadas, a menos que especificado de outra forma. Esse é um recurso útil, pois significa que podemos testar todo o código que entra no repositório. Isso permite que você saiba se o código está pronto para ser gravado na ramificação mastere se isso interromperá o processo de criação do projeto. Nesta configuração global, instalo tudo localmente, inicio o servidor do desenvolvedor Webpack em segundo plano (esse é um recurso do meu fluxo de trabalho) e executo os testes.

Se você deseja exibir ícones em seu repositório com informações sobre cobertura de código por testes, aqui você pode encontrar breves instruções sobre o uso de 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, as ações que são executadas para todas as ramificações do repositório e para solicitações pull terminam.

▍ Implantação


Com base no pressuposto de que todos os testes automatizados foram concluídos com êxito, opcionalmente, podemos implantar o código no servidor de produção. Como queremos fazer isso apenas para o código de uma ramificação master, fornecemos ao sistema instruções apropriadas nas configurações de implantação. Antes de tentar usar o código em seu projeto, que consideraremos posteriormente, 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:

  • Crie, identifique e envie a imagem ao Docker Hub usando a ferramenta CI (no nosso caso, é Travis CI).
  • Carregando a imagem no servidor, parando o contêiner antigo e iniciando o novo (no nosso caso, o servidor é executado na plataforma DigitalOcean).

Primeiro, você precisa configurar o processo automático de montagem, marcação e envio da imagem para o Docker Hub. Tudo isso é muito semelhante ao que já fizemos manualmente, exceto que aqui precisamos de uma estratégia para atribuir tags exclusivas às imagens e automatizar o login. Eu tive dificuldades com alguns detalhes do script de implantação, como uma estratégia de marcação, login, codificação de chaves SSH, estabelecimento de uma conexão SSH. Mas, felizmente, meu namorado lida com o bash muito bem, assim como muitas outras coisas. Ele me ajudou a escrever esse script.

Portanto, a primeira parte do script está enviando a imagem para o Docker Hub. Isso é bem simples. O esquema de marcação que usei envolve a combinação de um hash git e uma tag git, se houver. Isso permite a criação de uma tag exclusiva e simplifica a identificação da montagem na qual ela se baseia. DOCKER_USERNAMEe DOCKER_PASSWORDsão variáveis ​​de ambiente do usuário que podem ser definidas usando a interface do IC do Travis. O Travis CI processa automaticamente dados confidenciais para que não caiam nas 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 a segunda parte do script será completamente depende de qual host você está usando e como a conexão com ele está organizada. No meu caso, como uso o Digital Ocean, os comandos doctl são usados ​​para conectar-se ao servidor . Ao trabalhar com o Aws, um utilitário será usado awse assim por diante.

A configuração do servidor não foi particularmente difícil. Então, configurei uma gota com base na imagem base. Deve-se observar que o sistema que eu selecionei requer uma instalação manual única do Docker e um lançamento manual único do Docker. Eu usei o Ubuntu 18.04 para instalar o Docker, portanto, se você também usa 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 de ação geral que será executado após a conexão via SSH ao servidor no qual o projeto será implantado:

  • Você precisa encontrar o contêiner que está em execução no momento e pará-lo.
  • Em segundo plano, você precisa iniciar um novo contêiner.
  • Você precisará definir a porta do servidor local como um valor 80- isso permitirá que você insira o site no endereço do formulário example.com, sem especificar a porta, e não use o endereço como example.com:5000.
  • E, finalmente, você precisa remover todos os contêineres e imagens antigos.

Aqui está a continuação do script.

#  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 a considerar


Talvez quando você se conectar ao servidor via SSH do Travis CI, você verá um aviso que não permitirá que a instalação continue, 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 a chave de cadeia pode ser codificada em base64 para salvá-la de uma forma em que será conveniente e confiável trabalhar com ela. No estágio de instalação, você pode decodificar a chave pública e gravá-la em um arquivo known_hostspara 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== you@example.com" | base64

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

MTIzLjQ1LjY3Ljg5IHNzaC1yc2EgQUFBQUIzTnphQzF5YzJFQUFBQUJJd0FBQVFFQWtsT1Vwa0RIcmZIWTE3U2JybVRJcE5MVEdLOVRqb20vQldEU1UKR1BsK25hZnpsSERUWVc3aGRJNHlaNWV3MThKSDRKVzlqYmhVRnJ2aVF6TTd4bEVMRVZmNGg5bEZYNVFWa2JQcHBTd2cwY2RhMwpQYnY3a09kSi9NVHlCbFdYRkNSK0hBbzNGWFJpdEJxeGlYMW5LaFhwSEFac01jaUxxOFY2UmpzTkFRd2RzZE1GdlNsVksvN1hBCnQzRmFvSm9Bc25jTTFROXg1KzNWMFd3NjgvZUlGbWIxenVVRmxqUUpLcHJyWDg4WHlwTkR2allOYnk2dncvUGIwcndlcnQvRW4KbVorQVc0T1pQblRQSTg5WlBtVk1MdWF5ckQyY0U4NlovaWw4YitndzNyMysxbkthdG1Ja2puMnNvMWQwMVFyYVRsTXFWU3NieApOclJGaTl3cmYrTTdRPT0geW91QGV4YW1wbGUuY29tCg==

Aqui está a equipe mencionada 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, pois você pode precisar de uma chave privada para acessar o servidor. Ao trabalhar com uma chave, você só precisa garantir seu armazenamento seguro na variável de ambiente Travis CI e para que ela não seja exibida em nenhum lugar.

Outra coisa que você deve prestar atenção é que pode ser necessário executar o script de implantação inteiro, apresentado como uma única linha, por exemplo, usando doctl. Isso pode exigir algum esforço adicional.

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

TLS / SSL e balanceamento de carga


Depois de fazer tudo o que foi discutido acima, o último problema que surgiu diante de mim foi que o servidor não tinha SSL. Como eu uso o servidor Node.js., para fazer com que os proxies reversos Nginx e Let's Encrypt funcionem , preciso mexer muito.

Eu realmente não estava com vontade de fazer todas essas configurações de SSL manualmente, então criei um balanceador de carga e registrei informações sobre ele no DNS. No caso do DigitalOcean, por exemplo, a criação de um certificado autoassinado com renovação automática em um balanceador de carga é um procedimento simples, gratuito e rápido. Essa abordagem possui uma vantagem adicional, que, se necessário, facilita a configuração do SSL em vários servidores executando um balanceador de carga. Isso permite que os próprios servidores não “pensem” no SSL, mas usem a porta como de costume 80. Portanto, a configuração do SSL em um balanceador de carga é muito mais simples e mais conveniente do que os métodos alternativos de configuração do SSL.

Agora você pode fechar no servidor todas as portas que aceitam conexões de entrada - exceto a porta 80usada para comunicação com o balanceador de carga e a porta 22para SSH. Como resultado, uma tentativa de acessar diretamente o servidor em qualquer porta, com exceção dessas duas, falhará.

Sumário


Depois de fazer tudo o que foi descrito neste material, não tive mais medo da plataforma Docker ou do conceito de cadeias automatizadas de CI / CD. Consegui configurar uma cadeia de integração contínua durante a qual o código é testado antes de entrar em produção e o código é implantado automaticamente no servidor. Tudo isso para mim ainda é relativamente novo e tenho certeza de que existem maneiras de melhorar meu fluxo de trabalho automatizado e torná-lo mais eficiente. Portanto, se você tiver alguma idéia sobre esse assunto, me avise. Espero que este artigo tenha ajudado você em seus assuntos. Quero acreditar que, depois de ler, você aprendeu tanto quanto eu, enquanto descobri tudo o que contei.

PS Existe uma imagem em nosso mercadoDocker , que é instalado em um clique. Você pode verificar a operação de contêineres no VPS . Todos os novos clientes recebem 3 dias gratuitamente para testes.

Queridos leitores! Você usa tecnologias de CI / CD em seus projetos?


All Articles