One place for hosting & domains

      Como compilar um aplicativo Node.js com o Docker [Início rápido]


      Introdução

      Este tutorial traz um passo a passo para ajudá-lo na criação de uma imagem de aplicativo para um website estático que utilize o framework Express e o Bootstrap. Em seguida, você irá compilar um contêiner usando essa imagem, irá enviá-la para o Docker Hub e a utilizará para compilar outro contêiner, demonstrando como é possível recriar e dimensionar o seu aplicativo.

      Para obter uma versão mais detalhada deste tutorial, com explicações mais detalhadas de cada passo, consulte o tutorial Como compilar um aplicativo Node.js com o Docker.

      Pré-requisitos

      Para seguir este tutorial, você vai precisar do seguinte:

      • Um usuário sudo em seu servidor ou em seu ambiente local.
      • O Docker.
      • Node.js e npm.
      • Uma conta do Docker Hub.

      Passo 1 — Instalando as dependências do seu aplicativo

      Primeiro, crie um diretório para seu projeto em seu diretório home do usuário não raiz:

      Navegue até este diretório:

      Esse será o diretório raiz do projeto.

      Em seguida, crie um package.json com as dependências do seu projeto:

      Adicione as seguintes informações sobre o projeto ao arquivo; certifique-se de substituir as informações do autor pelo seu nome e detalhes de contato:

      ~/node_project/package.json

      {
        "name": "nodejs-image-demo",
        "version": "1.0.0",
        "description": "nodejs image demo",
        "author": "Sammy the Shark <sammy@example.com>",
        "license": "MIT",
        "main": "app.js",
        "scripts": {
          "start": "node app.js",
          "test": "echo "Error: no test specified" && exit 1"
        },
        "keywords": [
          "nodejs",
          "bootstrap",
          "express"
        ],
        "dependencies": {
          "express": "^4.16.4"
        }
      }
      

      Instale as dependências do seu projeto:

      Passo 2 — Criando os arquivos do aplicativo

      Criaremos um site que fornece informações aos usuários sobre tubarões.

      Abra o app.js no diretório principal do projeto para definir as rotas do projeto:

      Adicione o conteúdo a seguir ao arquivo para criar o aplicativo Express e os objetos Router, definir o diretório base, a porta e o host como variáveis, definir as rotas e, em seguida, montar o middleware router junto com os ativos estáticos do aplicativo:

      ~/node_project/app.js

      var express = require("express");
      var app = express();
      var router = express.Router();
      
      var path = __dirname + '/views/';
      
      // Constants
      const PORT = 8080;
      const HOST = '0.0.0.0';
      
      router.use(function (req,res,next) {
        console.log("/" + req.method);
        next();
      });
      
      router.get("/",function(req,res){
        res.sendFile(path + "index.html");
      });
      
      router.get("/sharks",function(req,res){
        res.sendFile(path + "sharks.html");
      });
      
      app.use(express.static(path));
      app.use("/", router);
      
      app.listen(8080, function () {
        console.log('Example app listening on port 8080!')
      })
      

      Em seguida, vamos adicionar conteúdo estático ao aplicativo. Crie o diretório views:

      Abra o index.html:

      Adicione o código a seguir ao arquivo, que importará o Boostrap e criará um componente jumbotron com um link para a página de informações mais detalhadas do sharks.html:

      ~/node_project/views/index.html

      <!DOCTYPE html>
      <html lang="en">
         <head>
            <title>About Sharks</title>
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
            <link href="css/styles.css" rel="stylesheet">
            <link href='https://fonts.googleapis.com/css?family=Merriweather:400,700' rel='stylesheet' type='text/css'>
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
            <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
         </head>
         <body>
            <nav class="navbar navbar-inverse navbar-static-top">
               <div class="container">
                  <div class="navbar-header">
                     <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                     <span class="sr-only">Toggle navigation</span>
                     <span class="icon-bar"></span>
                     <span class="icon-bar"></span>
                     <span class="icon-bar"></span>
                     </button>
                     <a class="navbar-brand" href="https://www.digitalocean.com/#">Everything Sharks</a>
                  </div>
                  <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                     <ul class="nav navbar-nav mr-auto">
                        <li class="active"><a href="/">Home</a></li>
                        <li><a href="http://www.digitalocean.com/sharks">Sharks</a></li>
                     </ul>
                  </div>
               </div>
            </nav>
            <div class="jumbotron">
               <div class="container">
                  <h1>Want to Learn About Sharks?</h1>
                  <p>Are you ready to learn about sharks?</p>
                  <br>
                  <p><a class="btn btn-primary btn-lg" href="http://www.digitalocean.com/sharks" role="button">Get Shark Info</a></p>
               </div>
            </div>
            <div class="container">
               <div class="row">
                  <div class="col-md-6">
                     <h3>Not all sharks are alike</h3>
                     <p>Though some are dangerous, sharks generally do not attack humans. Out of the 500 species known to researchers, only 30 have been known to attack humans.</p>
                  </div>
                  <div class="col-md-6">
                     <h3>Sharks are ancient</h3>
                     <p>There is evidence to suggest that sharks lived up to 400 million years ago.</p>
                  </div>
               </div>
            </div>
         </body>
      </html>
      

      Em seguida, abra um arquivo chamado sharks.html:

      Adicione o código a seguir, o qual importará o Bootstrap e a folha de estilos personalizada e fornecerá informações detalhadas sobre certos tubarões:

      ~/node_project/views/sharks.html

      <!DOCTYPE html>
      <html lang="en">
         <head>
            <title>About Sharks</title>
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
            <link href="css/styles.css" rel="stylesheet">
            <link href='https://fonts.googleapis.com/css?family=Merriweather:400,700' rel='stylesheet' type='text/css'>
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
            <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
         </head>
         <nav class="navbar navbar-inverse navbar-static-top">
            <div class="container">
               <div class="navbar-header">
                  <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                  <span class="sr-only">Toggle navigation</span>
                  <span class="icon-bar"></span>
                  <span class="icon-bar"></span>
                  <span class="icon-bar"></span>
                  </button>
                  <a class="navbar-brand" href="https://www.digitalocean.com/#">Everything Sharks</a>
               </div>
               <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                  <ul class="nav navbar-nav mr-auto">
                     <li><a href="/">Home</a></li>
                     <li class="active"><a href="http://www.digitalocean.com/sharks">Sharks</a></li>
                  </ul>
               </div>
            </div>
         </nav>
         <div class="jumbotron text-center">
            <h1>Shark Info</h1>
         </div>
         <div class="container">
            <div class="row">
               <div class="col-md-6">
                  <p>
                  <div class="caption">Some sharks are known to be dangerous to humans, though many more are not. The sawshark, for example, is not considered a threat to humans.</div>
                  <img src="https://assets.digitalocean.com/articles/docker_node_image/sawshark.jpg" alt="Sawshark">
                  </p>
               </div>
               <div class="col-md-6">
                  <p>
                  <div class="caption">Other sharks are known to be friendly and welcoming!</div>
                  <img src="https://assets.digitalocean.com/articles/docker_node_image/sammy.png" alt="Sammy the Shark">
                  </p>
               </div>
            </div>
          </div>
         </body>
      </html>
      

      Por fim, crie a folha de estilos CSS personalizada que você vinculou ao index.html e ao sharks.html, criando primeiro uma pasta css no diretório views:

      Abra a folha de estilos e adicione o código a seguir, o qual definirá a cor e a fonte desejadas para nossas páginas:

      ~/node_project/views/css/styles.css

      .navbar {
              margin-bottom: 0;
      }
      
      body {
              background: #020A1B;
              color: #ffffff;
              font-family: 'Merriweather', sans-serif;
      }
      h1,
      h2 {
              font-weight: bold;
      }
      p {
              font-size: 16px;
              color: #ffffff;
      }
      
      
      .jumbotron {
              background: #0048CD;
              color: white;
              text-align: center;
      }
      .jumbotron p {
              color: white;
              font-size: 26px;
      }
      
      .btn-primary {
              color: #fff;
              text-color: #000000;
              border-color: white;
              margin-bottom: 5px;
      }
      
      img, video, audio {
              margin-top: 20px;
              max-width: 80%;
      }
      
      div.caption: {
              float: left;
              clear: both;
      }
      

      Inicie o aplicativo:

      Use seu navegador para ir para o endereço http://your_server_ip:8080 ou localhost:8080, se estiver trabalhando localmente. Você verá a seguinte página inicial:

      Página inicial do aplicativo

      Clique no botão Get Shark Info. Você verá a seguinte página de informações:

      Página de informações sobre tubarões

      Agora, você tem um aplicativo em funcionamento. Quando estiver pronto, saia do servidor, digitando CTRL+C.

      Passo 3 — Escrevendo o Dockerfile

      No diretório raiz do seu projeto, crie o Dockerfile:

      Adicione o código a seguir ao arquivo:

      ~/node_project/Dockerfile

      
      FROM node:10-alpine
      
      RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app
      
      WORKDIR /home/node/app
      
      COPY package*.json ./
      
      USER node
      
      RUN npm install
      
      COPY --chown=node:node . .
      
      EXPOSE 8080
      
      CMD [ "node", "app.js" ]
      

      Esse Dockerfile utiliza uma imagem base alpine, assegurando que o usuário node não raiz detenha a propriedade dos arquivos do aplicativo. Por padrão, a imagem Node do Docker inclui o usuário node não raiz.

      Em seguida, adicione seus módulos node locais, os registros npm, o Dockerfile e o .dockerignore ao seu arquivo .dockerignore:

      ~/node_project/.dockerignore

      node_modules
      npm-debug.log
      Dockerfile
      .dockerignore
      

      Compile a imagem do aplicativo usando o comando docker build:

      • docker build -t your_dockerhub_username/nodejs-image-demo .

      O . especifica que o contexto de compilação é o diretório atual.

      Verifique suas imagens:

      Você verá o seguinte resultado:

      Output

      REPOSITORY TAG IMAGE ID CREATED SIZE your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 8 seconds ago 895MB node 10 f09e7c96b6de 17 hours ago 893MB

      Execute o comando a seguir para compilar um contêiner usando esta imagem:

      • docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo

      Usando o docker ps, verifique a lista dos contêineres em execução:

      Você verá o seguinte resultado:

      Output

      CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e50ad27074a7 your_dockerhub_username/nodejs-image-demo "npm start" 8 seconds ago Up 7 seconds 0.0.0.0:80->8080/tcp nodejs-image-demo

      Com seu contêiner em execução, agora você pode acessar o seu aplicativo, utilizando seu navegador para acessar o endereço http://your_server_ip ou o localhost. Você verá a página inicial do seu aplicativo novamente:

      Página inicial do aplicativo

      Agora que você criou uma imagem para seu aplicativo, é possível encaminhá-la para o Docker Hub para uso futuro.

      O primeiro passo para enviar a imagem é fazer o login na sua conta do Docker Hub:

      • docker login -u your_dockerhub_username -p your_dockerhub_password

      Acessar dessa maneira criará um arquivo ~/.docker/config.json no diretório home do seu usuário, com as suas credenciais do Docker Hub.

      Envie sua imagem, usando seu próprio nome de usuário no lugar de your_dockerhub_username:

      • docker push your_dockerhub_username/nodejs-image-demo

      Se quiser, teste o utilitário do registro de imagens, destruindo o contêiner e a imagem atuais do seu aplicativo; depois, recompile-os.

      Primeiro, liste os contêineres em execução:

      Você verá o seguinte resultado:

      Output

      CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e50ad27074a7 your_dockerhub_username/nodejs-image-demo "npm start" 3 minutes ago Up 3 minutes 0.0.0.0:80->8080/tcp nodejs-image-demo

      Usar o CONTAINER ID listada em sua saída interromperá o contêiner do aplicativo em execução. Certifique-se de substituir o ID destacado abaixo pelo seu próprio CONTAINER ID:

      Liste todas as suas imagens com o sinalizador -a:

      Você verá o seguinte resultado com o nome de sua imagem, your_dockerhub_username/nodejs-image-demo, junto com a imagem node e outras imagens da sua compilação:

      Output

      REPOSITORY TAG IMAGE ID CREATED SIZE your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 7 minutes ago 895MB <none> <none> e039d1b9a6a0 7 minutes ago 895MB <none> <none> dfa98908c5d1 7 minutes ago 895MB <none> <none> b9a714435a86 7 minutes ago 895MB <none> <none> 51de3ed7e944 7 minutes ago 895MB <none> <none> 5228d6c3b480 7 minutes ago 895MB <none> <none> 833b622e5492 8 minutes ago 893MB <none> <none> 5c47cc4725f1 8 minutes ago 893MB <none> <none> 5386324d89fb 8 minutes ago 893MB <none> <none> 631661025e2d 8 minutes ago 893MB node 10 f09e7c96b6de 17 hours ago 893MB

      Usando o comando abaixo, remova o contêiner suspenso e todas as imagens, incluindo as imagens não utilizadas ou pendentes:

      Com todas as suas imagens e contêineres excluídos, agora você poderá extrair a imagem do aplicativo do Docker Hub:

      • docker pull your_dockerhub_username/nodejs-image-demo

      Liste as suas imagens novamente:

      Você verá a imagem do seu aplicativo:

      Output

      REPOSITORY TAG IMAGE ID CREATED SIZE your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 11 minutes ago 895MB

      Agora, você pode recompilar seu contêiner, usando o comando do Passo 3:

      • docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo

      Liste seus contêineres em execução:

      Output

      CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f6bc2f50dff6 your_dockerhub_username/nodejs-image-demo "npm start" 4 seconds ago Up 3 seconds 0.0.0.0:80->8080/tcp nodejs-image-demo

      Acesse novamente o http://your_server_ip ou o localhost para visualizar seu aplicativo em execução.

      Tutoriais relacionados

      Aqui estão os links para os guias mais detalhados relacionados a este tutorial:

      Você também pode revisar a série mais extensa do artigo intitulado De contêineres a Kubernetes com o Node.js, a partir da qual este tutorial foi adaptado.

      Além disso, consulte nossa biblioteca completa dos Recursos do Docker para obter mais detalhes sobre o Docker.



      Source link

      Como configurar os hosts virtuais do Apache no Ubuntu 18.04 [Guia de início rápido]


      Introdução

      Este tutorial irá guiá-lo na configuração de vários domínios e sites usando hosts virtuais do Apache em um servidor Ubuntu 18.04. Durante esse processo, você aprenderá como distribuir conteúdo diferente para visitantes diferentes, dependendo de quais domínios eles estiverem solicitando.

      Para uma versão mais detalhada deste tutorial, com mais explicações de cada passo, consulte o tutorial sobre Como configurar hosts virtuais do Apache no Ubuntu 18.04.

      Pré-requisitos

      Para completar este tutorial, será necessário ter acesso ao seguinte em um servidor Ubuntu 18.04:

      • Um usuário sudo no seu servidor
      • Um servidor Web Apache2, que pode ser instalado com sudo apt install apache2

      Passo 1 — Criar a estrutura de diretório

      Primeiro, vamos criar uma estrutura de diretórios que retenha os dados do site que vamos distribuir aos visitantes em nosso diretório Apache de nível superior. Vamos usar exemplos de nomes de domínio, conforme destacadosabaixo. Você deverá substituí-los por seus próprios nomes de domínio.

      • sudo mkdir -p /var/www/example.com/public_html
      • sudo mkdir -p /var/www/test.com/public_html

      Passo 2 — Conceder permissões

      Agora, devemos alterar as permissões para que nosso usuário não raiz atual consiga modificar os arquivos.

      • sudo chown -R $USER:$USER /var/www/example.com/public_html
      • sudo chown -R $USER:$USER /var/www/test.com/public_html

      Além disso, vamos garantir que o acesso de leitura seja concedido ao diretório Web geral – e todos os arquivos e pastas que ele contém, para que as páginas possam ser atendidas corretamente.

      • sudo chmod -R 755 /var/www

      Passo 3 — Criar páginas de demonstração para cada host virtual

      Vamos criar um conteúdo para distribuir. Além disso, criaremos uma página index.html de demonstração para cada site. Podemos abrir um arquivo index.html em um editor de texto para nosso primeiro site, usando o nano por exemplo.

      • nano /var/www/example.com/public_html/index.html

      Dentro desse arquivo, crie um documento HTML específico do domínio, como o seguinte:

      /var/www/example.com/public_html/index.html

      <html>
        <head>
          <title>Welcome to Example.com!</title>
        </head>
        <body>
          <h1>Success! The example.com virtual host is working!</h1>
        </body>
      </html>
      

      Salve e feche o arquivo e, em seguida, copie esse arquivo para usar como base para nosso segundo site:

      • cp /var/www/example.com/public_html/index.html /var/www/test.com/public_html/index.html

      Abra o arquivo e modifique as informações relevantes:

      • nano /var/www/test.com/public_html/index.html

      /var/www/test.com/public_html/index.html

      <html>
        <head>
          <title>Welcome to Test.com!</title>
        </head>
        <body> <h1>Success! The test.com virtual host is working!</h1>
        </body>
      </html>
      

      Salve e feche esse arquivo também.

      Passo 4 — Criar arquivos do host virtual

      O Apache vem com um arquivo de host virtual padrão chamado 000-default.conf que usaremos como modelo. Vamos copiá-lo para criar um arquivo de host virtual para cada um dos nossos domínios.

      Crie o primeiro arquivo de host virtual

      Comece copiando o arquivo para o primeiro domínio:

      • sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/example.com.conf

      Abra o novo arquivo no seu editor (estamos usando o nano abaixo) com privilégios raiz:

      • sudo nano /etc/apache2/sites-available/example.com.conf

      Vamos personalizar esse arquivo para nosso próprio domínio. Modifique o texto destacado abaixo de acordo com suas próprias necessidades suas próprias circunstâncias.

      /etc/apache2/sites-available/example.com.conf

      <VirtualHost *:80>
          ServerAdmin admin@example.com
          ServerName example.com
          ServerAlias www.example.com
          DocumentRoot /var/www/example.com/public_html
          ErrorLog ${APACHE_LOG_DIR}/error.log
          CustomLog ${APACHE_LOG_DIR}/access.log combined
      </VirtualHost>
      

      Neste ponto, salve e feche o arquivo.

      Copiar o primeiro host virtual e personalizar para o segundo domínio

      Agora que temos o nosso primeiro arquivo de host virtual estabelecido, podemos criar nosso segundo, copiando aquele arquivo e ajustando o arquivo, conforme necessário.

      Comece copiando-o:

      • sudo cp /etc/apache2/sites-available/example.com.conf /etc/apache2/sites-available/test.com.conf

      Abra o novo arquivo com privilégios raiz em seu editor:

      • sudo nano /etc/apache2/sites-available/test.com.conf

      Agora, será necessário modificar todas as informações para referenciar seu segundo domínio. O arquivo final deve se parecer com este, com o texto destacado correspondendo às suas próprias informações de domínio relevantes.

      /etc/apache2/sites-available/test.com.conf

      <VirtualHost *:80>
          ServerAdmin admin@test.com
          ServerName test.com
          ServerAlias www.test.com
          DocumentRoot /var/www/test.com/public_html
          ErrorLog ${APACHE_LOG_DIR}/error.log
          CustomLog ${APACHE_LOG_DIR}/access.log combined
      </VirtualHost>
      

      Salve e feche o arquivo quando você terminar.

      Passo 5 — Habilitar os novos arquivos de host virtual

      Com nossos arquivos de host virtual criados, precisamos habilitá-los. Vamos usar a ferramenta a2ensite para alcançar esse objetivo.

      • sudo a2ensite example.com.conf
      • sudo a2ensite test.com.conf

      Em seguida, desabilite o site padrão definido em 000-default.conf:

      • sudo a2dissite 000-default.conf

      Quando terminar, será necessário reiniciar o Apache para essas alterações fazerem efeito e usar o systemctl status para verificar o sucesso da reinicialização.

      • sudo systemctl restart apache2

      Agora, seu servidor deve estar configurado para atender dois sites.

      Passo 6 — Configurar o arquivo de hosts locais (opcional)

      Se você ainda não estiver usando seus próprios nomes de domínios para testar esse procedimento, mas venha usando alguns exemplos domínios, você poderá testar o seu trabalho, alterando temporariamente o arquivo hosts em seu computador local.

      Em uma máquina local Mac ou Linux, digite o seguinte:

      Para uma máquina local Windows, encontre instruções sobre como alterar o arquivo hosts aqui.

      Utilizando os domínios usados neste guia e substituindo o IP do seu servidor pelo texto your_server_IP, seu arquivo deverá ficar com a seguinte aparência:

      /etc/hosts

      127.0.0.1   localhost
      127.0.1.1   guest-desktop
      your_server_IP example.com
      your_server_IP test.com
      

      Salve e feche o arquivo. Isso direcionará quaisquer pedidos para o example.com e o test.com em nosso computador e os enviará para nosso servidor.

      Passo 7 — Testar seus resultados

      Agora que seus hosts virtuais estão configurados, você pode testar suas configurações, acessando os domínios que configurou em seu navegador Web.

      http://example.com
      

      Você deve ver uma página como esta:

      Exemplo de host virtual do Apache

      Você também pode acessar sua segunda página e ver o arquivo que criou para seu segundo site.

      http://test.com
      

      Teste do host virtual do Apache

      Caso ambos esses sites funcionarem conforme o esperado, significa que você configurou dois hosts virtuais no mesmo servidor.

      Caso tenha ajustado o arquivo hosts do seu computador caseiro, exclua as linhas que adicionou.

      Tutoriais relacionados

      Aqui estão os links para outros guias relacionados a este tutorial:



      Source link

      Como Migrar Dados do Redis para um Banco de Dados Gerenciado na DigitalOcean


      Introdução

      Existem vários métodos que você pode usar para migrar dados de uma instância Redis para outra, tais como a replicação ou o snapshotting. No entanto, as migrações podem ficar mais complicadas quando você está movendo dados para uma instância Redis gerenciada por um provedor de nuvem, uma vez que os bancos de dados gerenciados muitas vezes limitam o controle que você tem sobre a configuração dos mesmos.

      Este tutorial descreve um método que você pode usar para migrar dados para uma instância do Redis gerenciada pela DigitalOcean. O método usa o comando interno migrate do Redis para transmitir dados com segurança por um túnel TLS configurado com o stunnel. Este guia também abordará algumas outras estratégias de migração comumente usadas, e por que elas são problemáticas ao migrar para um Banco de dados gerenciado na DigitalOcean.

      Pré-requisitos

      Para concluir este tutorial, você precisará de:

      Nota: Para ajudar a manter as coisas claras, este guia fará referência à instância Redis hospedada no seu servidor Ubuntu como a “origem”. Da mesma forma, ele se referirá à instância gerenciada pela DigitalOcean como o “destino” ou o “Banco de Dados Gerenciado”.

      Coisas a Considerar ao Migrar Dados do Redis para um Banco de Dados Gerenciado

      Existem vários métodos que você pode empregar para migrar dados de uma instância Redis para outra. No entanto, algumas dessas abordagens apresentam problemas ao migrar dados para uma instância Redis gerenciada pela DigitalOcean.

      Por exemplo, você pode usar a replicação para transformar sua instância Redis de destino em uma cópia exata da origem. Para fazer isso, você se conectaria ao servidor Redis de destino e executaria o comando replicaof com a seguinte sintaxe:

      • replicaof ip_ou_hostname_da_origem porta_da_origem

      Isso fará com que a instância de destino replique todos os dados mantidos na origem sem destruir nenhum dado que estava armazenado anteriormente nela. Depois disso, você promoveria a réplica de volta a ser uma instância primária com o seguinte comando:

      No entanto, as instâncias Redis gerenciadas pela DigitalOcean são configuradas para se tornarem somente réplicas de leitura. Se você tiver clientes gravando dados no banco de dados de origem, você não poderá configurá-los para gravar na instância gerenciada, pois ela está replicando dados. Isso significa que você perderia todos os dados enviados pelos clientes após promover a instância gerenciada como uma réplica e antes de configurá-los para começar a gravar dados nela, tornando a replicação uma solução de migração ineficiente.

      Outro método para migrar dados do Redis é tirar um snapshot ou instantâneo dos dados mantidos em sua instância de origem com um dos comandos save ou bgsave do Redis. Ambos os comandos exportam o snapshot para um arquivo que termina em .rdb, que você então transfere para o servidor de destino. Depois disso, você reiniciaria o serviço Redis para que ele possa carregar os dados.

      No entanto, muitos provedores de bancos de dados gerenciados — incluindo a DigitalOcean — não permitem acessar o sistema de arquivos subjacente do servidor de banco de dados gerenciado. Isso significa que não há como fazer upload do arquivo de snapshot ou fazer as alterações necessárias no arquivo de configuração do banco de dados de destino para permitir que os Redis importe os dados.

      Como a configuração dos bancos de dados gerenciados da DigitalOcean limita a eficácia tanto da replicação e quanto do snapshotting como meio de migração de dados, este tutorial utilizará o comando migrate do Redis para mover dados da origem para o destino. O comando migrate é projetado para mover apenas uma chave de cada vez, mas vamos usar alguns truques de linha de comando para mover um banco de dados Redis inteiro com um único comando.

      Este passo opcional envolve o carregamento da instância Redis de origem com alguns dados de amostra para que você possa experimentar a migração de dados para o banco de dados Redis gerenciado. Se você já possui dados que deseja migrar para sua instância de destino, você pode avançar para o Passo 2.

      Para começar, execute o seguinte comando para acessar o seu servidor Redis:

      Se você configurou seu servidor Redis para exigir autenticação por senha, execute o comando auth seguido da sua senha Redis:

      Em seguida, execute os seguintes comandos. Isso criará um número de chaves contendo algumas strings, um hash, uma lista e um set:

      • mset string1 "Redis" string2 "is" string3 "fun!"
      • hmset hash1 field1 "Redis" field2 "is" field3 "fast!"
      • rpush list1 "Redis" "is" "feature-rich!"
      • sadd set1 "Redis" "is" "free!"

      Além disso, execute os seguintes comandos expire para fornecer um tempo limite para algumas dessas chaves. Isso as tornará voláteis, o que significa que o Redis as excluirá após o período especificado, 7500 segundos:

      • expire string2 7500
      • expire hash1 7500
      • expire set1 7500

      Com isso, você tem alguns dados de exemplo que podem ser exportados para sua instância Redis de destino. Você pode manter o prompt do redis-cli aberto por enquanto, pois executaremos mais alguns comandos a partir dele no próximo passo para fazer backup desses dados.

      Passo 2 — Fazendo Backup dos Seus Dados

      Anteriormente, discutimos o uso do comando bgsave do Redis para tirar uma snapshot de um banco de dados Redis e migrá-lo para outra instância. Embora não utilizemos o bgsave como meio de migrar os dados do Redis, vamos usá-lo aqui para fazer backup dos dados, caso encontremos um erro durante o processo de migração.

      Se você ainda não o tiver aberto, comece abrindo a interface de linha de comandos do Redis:

      Além disso, se você configurou o seu servidor Redis para exigir autenticação por senha, execute o comando auth seguido da sua senha Redis:

      Em seguida, execute o comando bgsave. Isso criará um snapshot do seu data set atual e o exportará para um arquivo de dump cujo nome termina em .rdb:

      Nota: Conforme mencionado na seção anterior Coisas a Considerar, você pode tirar um snapshot do seu banco de dados Redis com os comandos save ou bgsave. A razão pela qual usamos o comando bgsave aqui é que o comando save é executado de forma síncrona, o que significa que ele bloqueará quaisquer outros clientes conectados ao banco de dados. Por isto, a documentação do comando save recomenda que esse comando quase nunca seja executado em um ambiente de produção.

      Em vez disso, ela sugere o uso do comando bgsave, que executa de forma assíncrona. Isso fará com que o Redis faça um fork do banco de dados em dois processos: o processo pai continuará a servir os clientes enquanto o filho salva o banco de dados antes de sair:

      Observe que se os clientes adicionarem ou modificarem dados enquanto a operação bgsave estiver em execução ou após a conclusão, essas alterações não serão capturadas no snapshot.

      Depois disso, você pode fechar a conexão com sua instância Redis executando o comando exit:

      Se você precisar no futuro, você poderá encontrar este arquivo de dump no seu diretório de trabalho da instalação do Redis. Se você não tiver certeza de qual diretório é esse, pode verificar abrindo seu arquivo de configuração Redis com o seu editor de texto preferido. Aqui, usaremos o nano:

      • sudo nano /etc/redis/redis.conf

      Navegue até a linha que começa com dbfilename. Por padrão, ele se apresentará assim:

      /etc/redis/redis.conf

      . . .
      # The filename where to dump the DB
      dbfilename dump.rdb
      . . .
      

      Esta diretiva define o arquivo para o qual o Redis exportará snapshots. A próxima linha (após qualquer comentário) ficará assim:

      /etc/redis/redis.conf

      . . .
      dir /var/lib/redis
      . . .
      

      A diretiva dir define o diretório de trabalho do Redis onde os snapshots são armazenados. Por padrão, isso é definido como /var/lib/redis, como mostrado neste exemplo.

      Feche o arquivo redis.conf. Supondo que você não tenha alterado o arquivo, você pode fazer isso pressionando CTRL+X.

      Em seguida, liste o conteúdo do seu diretório de trabalho Redis para confirmar que ele está mantendo o arquivo de dump de dados exportado:

      Se o arquivo de dump foi exportado corretamente, você o verá na saída deste comando:

      Output

      dump.rdb

      Depois de confirmar que você fez backup dos seus dados com êxito, você pode iniciar o processo de migração para o seu Banco de Dados Gerenciado.

      Passo 3 — Migrando os Dados

      Lembre-se de que este guia usa o comando interno migrate do Redis para mover as chaves uma a uma do banco de dados de origem para o destino. No entanto, ao contrário dos passos anteriores deste tutorial, não executaremos este comando no prompt redis-cli. Em vez disso, vamos executá-lo diretamente no prompt bash do servidor. Isso nos permitirá usar alguns truques do bash para migrar todas as chaves no banco de dados de origem com um comando.

      Nota: Se você tiver clientes gravando dados na sua instância Redis de origem, agora seria um bom momento para configurá-los para também gravar dados no seu Banco de Dados Gerenciado. Dessa forma, você pode migrar os dados existentes da origem para o seu destino sem perder nenhuma gravação que ocorra após a migração.

      Além disso, esteja ciente de que este comando de migração não substituirá nenhuma chave existente no banco de dados de destino, a menos que uma das chaves existentes tenha o mesmo nome da chave que você está migrando.

      A migração ocorrerá após a execução do seguinte comando. Antes de executá-lo, porém, vamos dividi-lo parte por parte:

      • redis-cli -n banco_de_dados_de_origem -a senha_da_origem scan 0 | while read key; do redis-cli -n banco_de_dados_de_origem -a senha_da_origem MIGRATE localhost 8000 "$key" banco_de_dados_de_destino 1000 COPY AUTH senha_do_redis_gerenciado; done

      Vamos analisar cada parte deste comando separadamente:

      • redis-cli -n banco_de_dados_de_origem -a senha_da_origem scan 0 . . .

      A primeira parte do comando, redis-cli, abre uma conexão com o servidor Redis local. A flag -n especifica a qual dos bancos de dados lógicos do Redis se conectar. O Redis possui 16 bancos de dados prontos para uso (com o primeiro sendo numerado como 0, o segundo numerado como 1 e assim por diante), portanto, banco_de_dados_de_origem pode ser qualquer número entre 0 e 15. Se sua instância de origem mantém apenas dados no banco de dados padrão (numerado como 0), você não precisará incluir a flag -n ou especificar um número de banco de dados.

      A seguir, vem a flag -a e a senha da instância de origem, que juntos autenticam a conexão. Se sua instância de origem não exigir autenticação por senha, você não precisará incluir a flag -a.

      Em seguida, ele executa o comando scan do Redis, que itera sobre as chaves mantidas no data set e as retorna como uma lista. O scan requer ser seguido de um cursor — a iteração começa quando o cursor está definido como 0, e termina quando o servidor retorna um cursor 0. Portanto, seguimos o scan com um cursor 0 para iterar sobre todas as chaves do conjunto.

      • . . . | while read key; do . . .

      A próxima parte do comando começa com uma barra vertical (|). Nos sistemas tipo Unix, as barras verticais são conhecidas como pipes e são usadas para direcionar a saída de um processo para a entrada de outro.

      A seguir, é iniciado o loop while. No bash, assim como na maioria das linguagens de programação, um loop while é uma declaração de fluxo de controle que permite repetir um determinado processo, código ou comando, enquanto uma certa condição permanecer verdadeira.

      A condição neste caso é o subcomando read key, que lê a entrada que foi canalizada e a atribui à variável key. O ponto-e-vírgula (;) significa o final da declaração condicional do loop while, e o do a seguir precede a ação que será repetida enquanto a expressão while permanecer verdadeira. Toda vez que a instrução do for concluída, a instrução condicional lerá a próxima linha canalizada a partir do comando scan e atribuirá essa entrada à variável key.

      Essencialmente, esta seção diz “enquanto houver saída do comando scan para ser lida, execute a seguinte ação”.

      • . . . redis-cli -n banco_de_dados_de_origem -a senha_da_origem migrate localhost 8000 "$key" . . .

      Esta seção do comando é a que executa a migração real. Após outra chamada do redis-cli, ela especifica mais uma vez o número do banco de dados de origem com a flag -n e autentica com a flag -a. Você precisa incluí-las novamente, porque essa chamada redis-cli é distinta daquela no início do comando. Mais uma vez, porém, você não precisa incluir a flag -n ou o número do banco de dados se a instância Redis de origem mantém apenas dados no banco de dados padrão 0, e você não precisa incluir a flag -a se ela não requer autenticação por senha.

      A seguir, está o comando migrate. Sempre que você usar o comando migrate, deverá segui-lo com o nome do host ou endereço IP do banco de dados de destino e o número da porta. Aqui, seguimos a convenção estabelecida no tutorial de pré-requisito do stunnel e apontamos o comando migrate para localhost na porta 8000.

      $key é a variável definida na primeira parte do loop while e representa as chaves de cada linha da saída do comando scan.

      • . . . banco_de_dados_de_destino 1000 copy auth senha_do_redis_gerenciado; done

      Esta seção é uma continuação do comando migrate. Ela começa com banco_de_dados_de_destino, que representa o banco de dados lógico na instância de destino em que você deseja armazenar os dados. Novamente, este pode ser qualquer número entre 0 e 15.

      Em seguida está um número que representa um tempo limite. Esse tempo limite é a quantidade máxima de tempo de comunicação inativa entre as duas máquinas. Observe que este não é um limite de tempo para a operação, apenas que a operação deve sempre fazer algum nível de progresso dentro do tempo limite definido. Tanto o número do banco de dados quanto os argumentos de tempo limite são necessários para cada comando migrate.

      Após o tempo limite está a flag opcional copy. Por padrão, o migrate excluirá cada chave do banco de dados de origem depois de transferi-la para o destino; Ao incluir esta opção, você está instruindo o comando migrate a meramente copiar as chaves para que elas persistam na origem.

      Após o copy, aparece a flag auth, seguido da senha do seu Banco de Dados Redis Gerenciado. Isso não é necessário se você estiver migrando dados para uma instância que não requer autenticação, mas é necessário quando você estiver migrando dados para um banco gerenciado pela DigitalOcean.

      A seguir, outro ponto-e-vírgula, indicando o final da ação a ser executada enquanto a condição while for verdadeira. Finalmente, o comando fecha com done, indicando o fim do loop. O comando verifica a condição na instrução while e repete a ação na instrução do até que ela não seja mais verdadeira.

      Em conjunto, este comando executa os seguintes passos:

      • Examina um banco de dados na instância Redis de origem e retorna todas as chaves nela contidas
      • Passa cada linha da saída do comando scan para um loop while
      • Lê a primeira linha e atribui seu conteúdo à variável key
      • Migra qualquer chave no banco de dados de origem que corresponda à variável key para um banco de dados na instância Redis na outra extremidade do túnel TLS mantida em localhost na porta 8000
      • Volta e lê a próxima linha, e repete o processo até que não haja mais chaves para ler

      Agora que examinamos cada parte do comando de migração, você pode prosseguir e executá-lo.

      Se sua instância de origem tiver apenas dados no banco de dados 0 padrão, você não precisa incluir quaisquer das flags -n ou seus argumentos. Se, no entanto, você estiver migrando dados de qualquer banco de dados que não seja o 0 na sua instância de origem, você deve incluir as flags -n e alterar as duas ocorrências de banco_de_dados_de_origem para alinhar com o banco de dados que você deseja migrar.

      Se o seu banco de dados de origem exigir autenticação por senha, certifique-se de alterar senha_da_origem para a senha real da instância do Redis. Caso contrário, certifique-se de remover ambas as ocorrências de -a senha_da_origem do comando. Além disso, altere senha_do_redis_gerenciado para a senha do seu Banco de Dados Gerenciado e certifique-se de alterar banco_de_dados_de_destino para o número do banco de dados lógico na sua instância de destino em que você deseja gravar os dados:

      Nota: Se você não tiver a senha do seu banco de dados Redis gerenciado em mãos, poderá encontrá-la navegando primeiramente para o Painel de controle da DigitalOcean. A partir daí, clique em Databases no menu da barra lateral esquerda e depois clique no nome da instância Redis para a qual você deseja migrar os dados. Role para baixo até a seção Connection Details, onde você encontrará um campo chamado password. Clique no botão show para revelar a senha e copie e cole-a no comando de migração — substituindo senha_do_redis_gerenciado – para autenticar.

      • redis-cli -n banco_de_dados_de_origem -a senha_da_origem scan 0 | while read key; do redis-cli -n banco_de_dados_de_origem -a senha_da_origem MIGRATE localhost 8000 "$key" banco_de_dados_de_destino 1000 COPY AUTH senha_do_redis_gerenciado; done

      Você verá uma saída semelhante à seguinte:

      Output

      NOKEY OK OK OK OK OK OK

      Nota: Observe a primeira linha da saída do comando que lê NOKEY. Para entender o que isso significa, execute a primeira parte do comando de migração sozinho:

      • redis-cli -n banco_de_dados_de_origem -a senha_da_origem scan 0

      Se você migrou os dados de amostra adicionados no Passo 2, a saída deste comando será parecida com esta:

      Output

      1) "0" 2) 1) "hash1" 2) "string3" 3) "list1" 4) "string1" 5) "string2" 6) "set1"

      O valor "0" mantido na primeira linha não é uma chave mantida no seu banco de dados Redis de origem, mas um cursor retornado pelo comando scan. Como não há chaves no servidor denominadas “0”, não há nada lá para o comando migrate enviar à sua instância de destino e ele retorna NOKEY.

      No entanto, o comando não falha e sai. Em vez disso, ele continua lendo e migrando as chaves encontradas nas próximas linhas da saída do comando scan.

      Para testar se a migração foi bem-sucedida, conecte-se ao seu Banco de Dados Redis Gerenciado:

      • redis-cli -h localhost -p 8000 -a senha_do_redis_gerenciado

      Se você migrou dados para qualquer banco de dados lógico que não o padrão, conecte-se a esse banco de dados com o comando select:

      • select banco_de_dados_de_destino

      Execute um comando scan para ver quais chaves são mantidas lá:

      Se você concluiu o Passo 2 deste tutorial e adicionou os dados de exemplo ao seu banco de dados de origem, você verá resultados como este:

      Output

      1) "0" 2) 1) "set1" 2) "string2" 3) "hash1" 4) "list1" 5) "string3" 6) "string1"

      Por fim, execute um comando ttl em qualquer chave que você configurou para expirar para confirmar que ela ainda é volátil:

      Output

      (integer) 3944

      Esta saída mostra que, embora você tenha migrado a chave para o seu Banco de Dados Gerenciado, ela ainda está configurada para expirar com base no comando expireat que você executou anteriormente.

      Depois de confirmar que todas as chaves do seu banco de dados Redis de origem foram exportadas para o destino com êxito, você pode fechar sua conexão com o Banco de Dados Gerenciado. Se você tiver clientes gravando dados na instância Redis de origem e já os configurou para enviar suas gravações para o destino, nesse momento você pode configurá-los para parar de enviar dados para a origem.

      Conclusão

      Ao concluir este tutorial, você transferiu os dados do seu repositório de dados Redis autogerenciado para uma instância Redis gerenciada pela DigitalOcean. O processo descrito neste guia pode não ser o ideal em todos os casos. Por exemplo, você teria que executar o comando de migração várias vezes (uma vez para cada banco de dados lógico que contém dados) se sua instância de origem estiver usando bancos de dados diferentes do padrão. No entanto, quando comparado a outros métodos, como replicação ou snapshotting, este é um processo bastante direto que funciona bem com a configuração de um Banco de Dados Gerenciado pela DigitalOcean.

      Agora que você está usando um Banco de Dados Redis Gerenciado pela DigitalOcean para armazenar seus dados, você pode medir seu desempenho executando alguns testes de benchmarking. Além disso, se você é novo no trabalho com o Redis, você pode conferir nossa série Como Gerenciar um Banco de Dados Redis.



      Source link