One place for hosting & domains

      Configuração

      Configuração inicial de servidor com o Ubuntu 20.04


      Introdução

      Ao criar um servidor do Ubuntu 20.04, deve-se executar alguns passos de configuração importantes como parte da configuração básica. Esses passos aumentarão a segurança e a usabilidade do seu servidor e darão a você uma base sólida para ações subsequentes.

      Passo 1 — Fazendo login como raiz

      Para fazer login no seu servidor, você precisará saber o endereço IP público do seu servidor. Você também precisará da senha ou, caso tenha instalado uma chave SSH para autenticação, da chave privada para a conta do usuário root. Se você ainda não estiver conectado ao seu servidor, aconselhamos seguir nosso guia sobre como se conectar ao seu Droplet com o SSH, o qual trata desse processo em detalhes.

      Se ainda não estiver conectado ao seu servidor, faça login como usuário root usando o seguinte comando (substitua a parte destacada do comando pelo endereço IP público do seu servidor):

      Aceite o aviso sobre a autenticidade do host, se ele for exibido. Se estiver usando autenticação por senha, insira sua senha root para fazer login. Se estiver usando uma chave SSH, protegida por frase secreta, você pode ser solicitado a digitar a frase secreta na primeira vez que usar a chave a cada sessão. Se esta for a primeira vez que você se conecta ao servidor com com uma senha, pode ser que também seja solicitado a alterar a senha root.

      Sobre o usuário raiz

      O usuário root é o usuário administrativo em um ambiente Linux e tem privilégios bastante amplos. Por conta dos privilégios elevados da conta root, desencorajamos sua utilização de maneira regular. Isto se dá porque parte da autoridade inerente à conta root é a capacidade de fazer alterações muito destrutivas, mesmo por acidente.

      O próximo passo será configurar uma nova conta de usuário com privilégios reduzidos para o uso no dia a dia. Ensinaremos mais tarde como obter privilégios aumentados apenas nos momentos em que precisar deles.

      Passo 2 — Criando um novo usuário

      Assim que fizer login como root, estaremos preparados para adicionar a nova conta de usuário. No futuro, faremos o login como esta nova conta em vez da conta root.

      Este exemplo cria um novo usuário chamado sammy, mas você deve substituí-lo pelo nome de usuário que preferir:

      Você terá de responder algumas perguntas, começando pela senha da conta.

      Digite uma senha forte e, de maneira opcional, preencha qualquer uma das informações adicionais se quiser. Isso não é necessário. Você pode apertar ENTER em qualquer campo que quiser ignorar.

      Passo 3 — Concedendo privilégios administrativos

      Agora, temos uma nova conta de usuário com privilégios de conta regular. No entanto, às vezes, pode ser que precisemos realizar tarefas administrativas.

      Para evitar ter que sair do nosso usuário normal e fazer login com a conta root, podemos configurar o que é conhecido como superusuário, ou privilégios root para nossa conta normal. Isso permitirá que nosso usuário normal execute comandos com privilégios administrativos, ao colocar a palavra sudo antes de cada comando.

      Para adicionar esses privilégios ao nosso novo usuário, precisamos adicionar o usuário ao grupo sudo. Por padrão, no Ubuntu 20.04, os usuários que são membros do grupo sudo têm permissão para utilizar o comando sudo.

      Como root, execute este comando para adicionar seu novo usuário ao grupo sudo (substitua a palavra destacada pelo seu novo nome de usuário):

      Agora, quando conectado com o usuário regular, você pode digitar sudo antes dos comandos para executar ações com privilégios de superusuário.

      Passo 4 — Configurando um firewall básico

      Os servidores do Ubuntu 20.04 podem utilizar o firewall UFW para garantir que sejam permitidas apenas conexões a certos serviços. Podemos configurar um firewall básico facilmente usando este aplicativo.

      Nota: se os seus servidores estiverem em execução na plataforma da DigitalOcean, você pode utilizar, de maneira opcional, os Firewalls da DigitalOcean em nuvem, em vez do firewall UFW. Recomendamos que use apenas um firewall de cada vez para evitar regras conflitantes que podem ser difíceis de difícil depuração.

      Após a instalação, os aplicativos podem registrar seus perfis com o UFW. Esses perfis permitem que o UFW gerencie esses aplicativos por nome. O OpenSSH, serviço que nos permite conectar ao nosso servidor agora, tem um perfil registrado com o UFW.

      Você ver isso digitando:

      Output

      Available applications: OpenSSH

      Precisamos garantir que o firewall permita conexões SSH para que possamos fazer login da próxima vez. Podemos permitir essas conexões digitando:

      Depois disso, podemos habilitar o firewall digitando:

      Digite y e pressione ENTER para continuar. Você pode ver se as conexões SSH ainda são permitidas digitando:

      Output

      Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6)

      Como o firewall está bloqueando todas as conexões exceto as SSH, se você instalar e configurar serviços adicionais, precisará ajustar as configurações de firewall para permitir o tráfego de entrada. Você pode aprender algumas operações comuns do UFW em nosso guia de Essenciais do UFW.

      Passo 5 — Habilitando o acesso externo ao seu usuário regular

      Agora que temos um usuário comum para o uso diário, precisamos confirmar se conseguimos acessar o SSH diretamente na conta.

      Nota: até verificar se você pode fazer login e usar o sudo com seu novo usuário, recomendamos que fique conectado como root. Desta forma, caso tenha problemas, pode solucioná-los e fazer as alterações necessárias como root. Se estiver usando um Droplet da DigitalOcean e tiver problemas com sua conexão raiz via SSH root, você pode fazer login no Droplet usando o console da DigitalOcean.

      O processo para configurar o acesso via SSH para seu novo usuário depende de se a conta root do seu servidor usa uma senha ou chaves SSH para autenticação.

      Se a conta raiz utiliza autenticação por senha

      Se você fez login na sua conta raiz usando uma senha, então a autenticação por senha está habilitada para o SSH. Você pode conectar-se via SSH à sua nova conta de usuário, abrindo uma nova sessão no terminal e usando o SSH com seu novo nome de usuário:

      Após digitar a senha do seu usuário regular, você estará conectado. Lembre-se, caso precise executar um comando com privilégios administrativos, digite sudo antes dele, desta forma:

      Será solicitado que você digite a senha do seu usuário regular ao usar o sudo pela primeira vez em cada sessão (e periodicamente após isso).

      Para melhorar a segurança do seu servidor, recomendamos fortemente que configure chaves SSH, em vez de usar autenticação por senha. Siga nosso guia sobre como configurar as chaves SSH no Ubuntu 20.04 para aprender como configurar a autenticação baseada em chaves.

      Se a conta raiz utiliza autenticação por chave SSH

      Se você fez login na sua conta root usando chaves SSH, então a autenticação por senha está desabilitada para SSH. Você precisará adicionar uma cópia da sua chave pública local ao arquivo ~/.ssh/authorized_keys do novo usuário para fazer login com sucesso.

      Como sua chave pública já está no arquivo ~/.ssh/authorized_keys da conta root no servidor, podemos copiar aquele arquivo e a estrutura do diretório para nossa nova conta de usuário existente.

      A maneira mais simples de copiar os arquivos com a propriedade e permissões corretas é com o comando rsync. Isso irá copiar o diretório .ssh do usuário root, preservar as permissões e modificar os proprietários dos arquivos, tudo em um único comando. Certifique-se de alterar as partes destacadas do comando abaixo para corresponder ao nome do seu usuário regular:

      Nota: o comando rsync trata as fontes e os destinos que terminam com uma barra à direita de maneira diferente daqueles sem uma barra. Ao usar o rsync abaixo, certifique-se de que o diretório fonte (~/.ssh) não inclui uma barra à direita (verifique para garantir que não está usando ~/.ssh/).

      Se adicionar uma barra à direita acidentalmente no comando, o rsync copiará o conteúdo do diretório ~/.ssh da conta root para o diretório home do usuário sudo, em vez copiar toda a estrutura do diretório ~/.ssh. Os arquivos ficarão no local errado e o SSH não conseguirá encontrar e usar esses arquivos.

      • rsync --archive --chown=sammy:sammy ~/.ssh /home/sammy

      Agora, abra uma nova sessão de terminal em sua máquina local e utilize o SSH com seu novo nome de usuário:

      Você deve estar conectado com a conta do novo usuário, sem usar uma senha. Lembre-se, caso precise executar um comando com privilégios administrativos, digite sudo antes dele, desta forma:

      Será solicitado que você digite a senha do seu usuário regular ao usar o sudo pela primeira vez em cada sessão (e periodicamente após isso).

      Para onde partir daqui?

      Neste ponto, você possui uma base sólida para seu servidor. Agora, você já pode instalar qualquer software que precisar em seu servidor.



      Source link

      Como usar o Migrations de banco de dados e o Seeders para abstrair a configuração do banco de dados em Laravel


      Migrations [Migrações] e seeders [Propagadores] são utilitários de banco de dados eficazes, fornecidos pela framework do Laravel para PHP, que permite que os desenvolvedores façam a inicialização, destruição e recriação do banco de dados de um aplicativo rapidamente. Esses utilitários ajudam a minimizar problemas de inconsistência de banco de dados que podem surgir com vários desenvolvedores trabalhando no mesmo aplicativo: novos colaboradores precisam apenas executar alguns comandos do artisan para definir o banco de dados em uma nova instalação.

      Neste guia, vamos criar migrations (migrações) e seeders (propagadores) para preencher o banco de dados de um aplicativo de demonstração do Laravel com dados de amostra. No final, você poderá destruir e recriar as tabelas de seu banco de dados quantas vezes quiser, usando apenas comandos do artisan.

      Pré-requisitos

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

      Nota: neste guia, utilizaremos um ambiente de desenvolvimento em contêiner, gerenciado pelo Docker Compose para executar o aplicativo, mas você também pode optar por executar o aplicativo em um servidor LEMP. Para configurar isso, siga nosso guia sobre Como instalar e configurar o Laravel com LEMP no Ubuntu 18.04.

      Passo 1 — Obtendo o aplicativo Demo

      Para começar, iremos buscar o aplicativo de demonstração do Laravel a partir de seu repositório do GitHub. Estamos interessados na ramificação do tutorial-02, que inclui uma Configuração do Docker Compose para executar o aplicativo em contêineres. Neste exemplo, baixaremos o aplicativo para nossa pasta base, mas também é possível usar qualquer diretório de sua escolha:

      • cd ~
      • curl -L https://github.com/do-community/travellist-laravel-demo/archive/tutorial-2.0.1.zip -o travellist.zip

      Como baixamos o código do aplicativo como um arquivo .zip, precisaremos do comando unzip para desempacotá-lo. Se não tiver feito isso recentemente, atualize o índice de pacotes local de sua máquina:

      Depois, instale o pacote unzip:

      Em seguida, descompacte o conteúdo do aplicativo:

      Em seguida, renomeie o diretório descompactado como travellist-demo para facilitar o acesso:

      • mv travellist-laravel-demo-tutorial-2.0.1 travellist-demo

      No próximo passo, vamos criar um arquivo de configuração .env para configurar o aplicativo.

      Passo 2 — Configurando o arquivo .env do aplicativo

      No Laravel, o arquivo .env é usado para configurar as configurações dependentes de ambiente, como credenciais e quaisquer informações que possam variar entre as implantações. Esse arquivo não está incluído no controle de revisão.

      Aviso: o arquivo de configuração de ambiente contém informações confidenciais sobre o seu servidor, incluindo credenciais para o banco de dados e chaves de segurança. Por esse motivo, nunca compartilhe esse arquivo publicamente.

      Os valores contidos no arquivo .env terão precedência sobre os valores definidos nos arquivos de configuração regulares, localizados no diretório config. Cada instalação em um novo ambiente exige um arquivo de ambiente personalizado para definir coisas como as configurações de conexão com o banco de dados, as opções de depuração, o URL do aplicativo, entre outros itens que possam variar, dependendo do ambiente em que o aplicativo esteja funcionando.

      Navegue até o diretório travellist-demo:

      Agora, vamos criar um novo arquivo .env para personalizar as opções de configuração do ambiente de desenvolvimento que estamos preparando. O Laravel vem com um exemplo de arquivo do .env que podemos copiar para criar o nosso:

      Abra este arquivo, usando o nano ou outro editor de texto de sua escolha:

      Esta é a aparência do seu arquivo .env agora:

      .env

      APP_NAME=Travellist
      APP_ENV=dev
      APP_KEY=
      APP_DEBUG=true
      APP_URL=http://localhost:8000
      
      LOG_CHANNEL=stack
      
      DB_CONNECTION=mysql
      DB_HOST=db
      DB_PORT=3306
      DB_DATABASE=travellist
      DB_USERNAME=travellist_user
      DB_PASSWORD=password

      O arquivo .env atual do aplicativo de demonstração travellist contém configurações para usar o ambiente em contêiner que criamos com o Docker Compose na última parte desta série. Você não precisa alterar nenhum desses valores, mas fique à vontade para modificar o DB_DATABASE, o DB_USERNAME e o DB_PASSWORD se quiser, uma vez que eles são puxados automaticamente pelo nosso arquivo docker-compose.yml para configurar o banco de dados de desenvolvimento. Certifique-se apenas de que a variável DB_HOST permaneça inalterada, uma vez que ela faz referência ao nome do nosso serviço de banco de dados dentro do ambiente do Docker Compose.

      Caso faça quaisquer alterações no arquivo, certifique-se de salvar e fechar ele pressionando CTRL + X, Y e, então, ENTER.

      Nota: caso tenha optado por executar o aplicativo em um servidor LEMP, será necessário alterar os valores destacados para refletir as configurações do seu próprio banco de dados, incluindo a variável DB_HOST.

      Agora, usaremos o Composer, uma ferramenta de gerenciamento de dependências do PHP, para instalar as dependências do aplicativo e garantir que possamos executar os comandos do artisan.

      Abra seu ambiente do Docker Compose com o comando a seguir. Isso compilará a imagem do travellist para o serviço do app e extrairá imagens adicionais do Docker – exigidas pelos serviços nginx e db, para criar o ambiente do aplicativo:

      Output

      Creating network "travellist-demo_travellist" with driver "bridge" Building app Step 1/11 : FROM php:7.4-fpm ---> fa37bd6db22a Step 2/11 : ARG user ---> Running in 9259bb2ac034 … Creating travellist-app ... done Creating travellist-nginx ... done Creating travellist-db ... done

      Esta operação pode levar alguns minutos para completar. Assim que o processo terminar, podemos executar o Composer para instalar as dependências do aplicativo.

      Para executar o composer e outros comandos no contêiner de serviço do app, utilizaremos o docker-compose exec. O comando exec permite que executemos qualquer comando de nossa escolha em contêineres gerenciados pelo Docker Compose. Ele usa a seguinte sintaxe: docker-compose exec service_name command.

      Nota: caso tenha optado por usar um servidor LEMP para executar o aplicativo de demonstração, ignore a parte do docker-compose exec app dos comandos listados durante todo este guia. Por exemplo, em vez de executar o seguinte comando como ele está escrito, você apenas executaria:

      Para executar o composer install no contêiner do app, execute:

      • docker-compose exec app composer install

      Output

      Loading composer repositories with package information Installing dependencies (including require-dev) from lock file Package operations: 85 installs, 0 updates, 0 removals - Installing doctrine/inflector (1.3.1): Downloading (100%) - Installing doctrine/lexer (1.2.0): Downloading (100%) - Installing dragonmantank/cron-expression (v2.3.0): Downloading (100%) …

      Quando o Composer terminar de instalar as dependências do aplicativo, você poderá executar os comandos do artisan. Para testar se o aplicativo consegue se conectar ao banco de dados, execute o seguinte comando que limpará quaisquer tabelas pré-existentes:

      • docker-compose exec app php artisan db:wipe

      Esse comando removerá quaisquer tabelas pré-existentes do banco de dados configurado. Se ele foi executado com sucesso e o aplicativo conseguiu se conectar ao banco de dados, você verá um resultado parecido com este:

      Output

      Dropped all tables successfully.

      Agora que você tem as dependências do aplicativo instaladas com o Composer, você pode utilizar a ferramenta artisan para criar migrations e seeders.

      Passo 4 — Criando migrations de banco de dados

      A ferramenta de linha de comando do artisan que vem com o Laravel contém uma série de comandos auxiliares que podem ser usados para gerenciar o aplicativo e inicializar novas classes. Para gerar uma nova classe de migration, podemos usar o comando make:migration como segue:

      • docker-compose exec app php artisan make:migration create_places_table

      O Laravel deduz a operação a ser executada (create), o nome da tabela (places) e se essa migration criará uma nova tabela ou não, com base no nome descritivo fornecido para o comando make:migration.

      Você verá um resultado semelhante a este:

      Output

      Created Migration: 2020_02_03_143622_create_places_table

      Isso gerará um novo arquivo no diretório database/migrations do aplicativo. O carimbo de data/hora no arquivo gerado automaticamente é utilizado pelo Laravel para determinar em qual ordem as migrations devem ser executadas.

      Utilize seu editor de texto preferido para abrir o arquivo migration gerado. Lembre-se de substituir o valor destacado pelo nome de arquivo de migration de sua escolha:

      • nano database/migrations/2020_02_03_143622_create_places_table.php

      O arquivo de migration gerado contém uma classe chamada CreatePlacesTable:

      database/migrations/2020_02_03_143622_create_places_table.php

      <?php
      
      use IlluminateDatabaseMigrationsMigration;
      use IlluminateDatabaseSchemaBlueprint;
      use IlluminateSupportFacadesSchema;
      
      class CreatePlacesTable extends Migration
      {
          /**
           * Run the migrations.
           *
           * @return void
           */
          public function up()
          {
              Schema::create('places', function (Blueprint $table) {
                  $table->bigIncrements('id');
                  $table->timestamps();
              });
          }
      
          /**
           * Reverse the migrations.
           *
           * @return void
           */
          public function down()
          {
              Schema::dropIfExists('places');
          }
      }
      
      

      Essa classe tem dois métodos: up e down. Ambos os métodos contêm o código de inicialização que podem ser estendidos para personalizar o que acontece quando essa migration for executada e também o que acontece quando ela for revertida.

      Vamos modificar o método up, de modo que a tabela places reflita a estrutura que já estamos usando na versão atual do aplicativo:

      • id: campo de chave primária.
      • name: nome do lugar.
      • visited: se este lugar já foi visitado ou não.

      O compilador de esquemas do Laravel expõe métodos para a criação, atualização e exclusão de tabelas em um banco de dados. A classe Blueprint define a estrutura da tabela e ela proporciona vários métodos para abstrair a definição de cada campo da tabela.

      O código gerado automaticamente define um campo de id primário chamado id. O método timestamps cria dois campos de datetime que são atualizados automaticamente pelas classes de banco de dados subjacentes, quando os dados são inseridos ou atualizados dentro dessa tabela. Além disso, precisaremos incluir um campo name e um visited.

      Nosso campo name será do tipo string e nosso campo visited será definido com o tipo boolean. Também vamos definir um valor padrão de 0 para o campo visited, de modo que se nenhum valor for transferido, significa que o lugar ainda não foi visitado. É assim que o método up se parecerá agora:

      database/migrations/2020_02_03_143622_create_places_table.php

      …
          public function up()
          {
              Schema::create('places', function (Blueprint $table) {
                  $table->bigIncrements('id');
                  $table->string('name', 100);
                  $table->boolean('visited')->default(0);
                  $table->timestamps();
              });
          }
      …
      

      Nota: você pode encontrar a lista completa dos tipos de coluna disponíveis na documentação do Laravel.

      Após incluir as duas linhas destacadas em seu próprio script de migration, salve e feche o arquivo.

      Agora, sua migration está pronta para ser executada através do artisan migrate. No entanto, isso criaria apenas uma tabela vazia; também precisamos conseguir inserir dados da amostra para o desenvolvimento e teste. No próximo passo, veremos como fazer isso usando os seeders de banco de dados.

      Passo 5 — Criando os Seeders de banco de dados

      Um seeder é uma classe especial utilizada para gerar e inserir dados de amostra (seeds) em um banco de dados. Essa é uma característica importante em ambientes de desenvolvimento, uma vez que permite que você recrie o aplicativo com um banco de dados novo, usando valores de amostra que, de qualquer forma você teria que inserir manualmente toda vez que o banco de dados fosse recriado.

      Agora, utilizaremos o comando artisan para gerar uma nova classe de seeders para nossa tabela de places chamada PlacesTableSeeder:

      • docker-compose exec app php artisan make:seeder PlacesTableSeeder

      O comando criará um novo arquivo chamado PlacesTableSeeder.php dentro do diretório database/seeds. Abra aquele arquivo usando seu editor de texto preferido:

      • nano database/seeds/PlacesTableSeeder.php

      É assim que o arquivo PlacesTableSeeder.php, gerado automaticamente, se parece:

      database/seeds/PlacesTableSeeder.php

      <?php
      
      use IlluminateDatabaseSeeder;
      
      class PlacesTableSeeder extends Seeder
      {
          /**
           * Run the database seeds.
           *
           * @return void
           */
          public function run()
          {
              //
          }
      }
      
      

      Nossa nova classe de seeder contém um método vazio chamado run. Esse método será chamado quando o comando db:seed do Artisan for executado.

      Precisamos editar o método run para incluir instruções para inserir dados de amostra no banco de dados. Vamos utilizar o compilador de consultas do Laravel para simplificar esse processo.

      O compilador de consultas do Laravel oferece uma interface fluente para as operações de banco de dados como a inserção, atualização e recuperação de dados. Ele também introduz proteções contra ataques de injeção de SQL. O compilador de consulta é exposto pela facade do DB – um proxy estático para as classes de banco de dados subjacentes no contêiner de serviço.

      Para começar, criaremos uma variável de classe estática para reter todos os locais das amostras que desejamos inserir no banco de dados como uma matriz. Isso nos permitirá usar um loop foreach para iterar em todos os valores, inserindo cada um no banco de dados utilizando o compilador de consulta.

      Chamaremos essa variável de $places:

      database/seeds/PlacesTableSeeder.php

      <?php
      
      use IlluminateDatabaseSeeder;
      
      class PlacesTableSeeder extends Seeder
      {
          static $places = [
              'Berlin',
              'Budapest',
              'Cincinnati',
              'Denver',
              'Helsinki',
              'Lisbon',
              'Moscow',
              'Nairobi',
              'Oslo',
              'Rio',
              'Tokyo'
          ];

      Em seguida, precisaremos incluir uma instrução use no topo de nossa classe PlacesTableSeeder para facilitar a referência da facade DB em todo o código:

      database/seeds/PlacesTableSeeder.php

      <?php
      
      use IlluminateDatabaseSeeder;
      use IlluminateSupportFacadesDB;
      
      class PlacesTableSeeder extends Seeder
      …
      

      Agora, podemos iterar através dos valores da matriz $places, usando um loop foreach e inserir cada um deles em nossa tabela places com o compilador de consultas:

      database/seeds/PlacesTableSeeder.php

      …
          public function run()
          {
              foreach (self::$places as $place) {
                  DB::table('places')->insert([
                      'name' => $place,
                      'visited' => rand(0,1) == 1
                  ]);
              }
          }
      
      

      O loop foreach itera através de cada valor da matriz estática $places. Em cada iteração, usamos a facade DB para inserir uma nova linha na tabela places. Definimos o campo name para o nome do lugar que acabamos de obter da matriz $places e definimos o campo visited para um valor aleatório de 0 ou 1.

      É assim que a classe PlacesTableSeeder completa se parecerá após todas as atualizações:

      database/seeds/PlacesTableSeeder.php

      <?php
      
      use IlluminateDatabaseSeeder;
      use IlluminateSupportFacadesDB;
      
      class PlacesTableSeeder extends Seeder
      {
          static $places = [
              'Berlin',
              'Budapest',
              'Cincinnati',
              'Denver',
              'Helsinki',
              'Lisbon',
              'Moscow',
              'Nairobi',
              'Oslo',
              'Rio',
              'Tokyo'
          ];
      
          /**
           * Run the database seeds.
           *
           * @return void
           */
          public function run()
          {
              foreach (self::$places as $place) {
                  DB::table('places')->insert([
                      'name' => $place,
                      'visited' => rand(0,1) == 1
                  ]);
              }
          }
      }
      

      Salve e feche o arquivo quando terminar de fazer essas alterações.

      As classes do seeder não são carregadas automaticamente no aplicativo. Precisamos editar a classe principal, DatabaseSeeder, para incluir uma chamada para o seeder que acabamos de criar.

      Abra o arquivo database/seeds/DatabaseSeeder.php com o nano ou com o seu editor favorito:

      • nano database/seeds/DatabaseSeeder.php

      A classe DatabaseSeeder se parece com qualquer outro seeder: ela se estende a partir da classe Seeder e tem um método run. Atualizaremos esse método para incluir uma chamada para o PlacesTableSeeder.

      Atualize o método run atual, dentro da classe DatabaseSeeder, excluindo a linha comentada e substituindo-a pelo código destacado a seguir:

      database/seeds/DatabaseSeeder.php

      …
          public function run()
          {
              $this->call(PlacesTableSeeder::class);
          }
      ...
      

      É assim que a classe DatabaseSeeder completa se parecerá após a atualização:

      database/seeds/DatabaseSeeder.php

      <?php
      
      use IlluminateDatabaseSeeder;
      
      class DatabaseSeeder extends Seeder
      {
          /**
           * Seed the application's database.
           *
           * @return void
           */
          public function run()
          {
              $this->call(PlacesTableSeeder::class);
          }
      }
      
      
      

      Salve e feche o arquivo quando terminar de atualizar seu conteúdo.

      Agora, terminamos a configuração da migration e de um seeder para nossa tabela places. No próximo passo, veremos como executá-las.

      Passo 6 — Executando as migrations e os seeders do banco de dados

      Antes de prosseguir, precisamos garantir que seu aplicativo esteja em funcionamento. Vamos configurar a chave de criptografia do aplicativo e, depois, acessar o aplicativo a partir de um navegador para testar o servidor Web.

      Para gerar a chave de criptografia que o Laravel exige, utilize o comando artisan key:generate:

      • docker-compose exec app php artisan key:generate

      Assim que a chave tiver sido gerada, você poderá acessar o aplicativo, apontando seu navegador para o nome do host ou endereço IP do servidor na porta 8000:

      http://server_host_or_ip:8000
      

      Você verá uma página como esta:

      Erro do MySQL

      Isso significa que o aplicativo conseguiu conectar-se ao banco de dados, mas que não encontrou uma tabela chamada places. Vamos criar a tabela places agora, utilizando o comando do artisan migrate:

      • docker-compose exec app php artisan migrate

      Você obterá um resultado parecido com este:

      Output

      Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table (0.06 seconds) Migrating: 2014_10_12_100000_create_password_resets_table Migrated: 2014_10_12_100000_create_password_resets_table (0.06 seconds) Migrating: 2019_08_19_000000_create_failed_jobs_table Migrated: 2019_08_19_000000_create_failed_jobs_table (0.03 seconds) Migrating: 2020_02_10_144134_create_places_table Migrated: 2020_02_10_144134_create_places_table (0.03 seconds)

      Você verá que algumas outras migrations foram executadas junto com a migration create_places_table que configuramos. Essas migrations são geradas automaticamente quando o Laravel é instalado. Embora não estejamos usando essas tabelas adicionais agora, elas serão necessárias no futuro quando expandirmos o aplicativo para ele ter usuários registrados e trabalhos agendados. Por enquanto, deixe-as como estão.

      Neste ponto, nossa tabela ainda está vazia. Precisamos executar o comando db:seed para propagar o banco de dados com nossas amostras de locais:

      • docker-compose exec app php artisan db:seed

      Isso executará nosso seeder e irá inserir os valores da amostra que definimos dentro da nossa classe PlacesTableSeeder. Você verá um resultado semelhante a este:

      Output

      Seeding: PlacesTableSeeder Seeded: PlacesTableSeeder (0.06 seconds) Database seeding completed successfully.

      Agora, recarregue a página do aplicativo no seu navegador. Você verá uma página parecida com esta:

      Demo do aplicativo Laravel

      Sempre que precisar começar do zero, você poderá remover todas as tabelas de banco de dados com:

      • docker-compose exec app php artisan db:wipe

      Output

      Dropped all tables successfully.

      Para executar o aplicativo migrations e propagar as tabelas em um único comando, utilize:

      • docker-compose exec app php artisan migrate --seed

      Output

      Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table (0.06 seconds) Migrating: 2014_10_12_100000_create_password_resets_table Migrated: 2014_10_12_100000_create_password_resets_table (0.07 seconds) Migrating: 2019_08_19_000000_create_failed_jobs_table Migrated: 2019_08_19_000000_create_failed_jobs_table (0.03 seconds) Migrating: 2020_02_10_144134_create_places_table Migrated: 2020_02_10_144134_create_places_table (0.03 seconds) Seeding: PlacesTableSeeder Seeded: PlacesTableSeeder (0.06 seconds) Database seeding completed successfully.

      Se quiser reverter uma migration, você pode executar:

      • docker-compose exec app php artisan migrate:rollback

      Isso acionará o método down para cada classe de migration dentro da pasta migrations. Normalmente, ele removerá todas as tabelas que foram criadas através das classes de migration, deixando sozinha quaisquer outras tabelas que possam ter sido criadas manualmente. Você verá um resultado como este:

      Output

      Rolling back: 2020_02_10_144134_create_places_table Rolled back: 2020_02_10_144134_create_places_table (0.02 seconds) Rolling back: 2019_08_19_000000_create_failed_jobs_table Rolled back: 2019_08_19_000000_create_failed_jobs_table (0.02 seconds) Rolling back: 2014_10_12_100000_create_password_resets_table Rolled back: 2014_10_12_100000_create_password_resets_table (0.02 seconds) Rolling back: 2014_10_12_000000_create_users_table Rolled back: 2014_10_12_000000_create_users_table (0.02 seconds)

      O comando de reversão é especialmente útil quando estiver fazendo alterações nos modelos do aplicativo e um comando db:wipe não puder ser usado – por exemplo, caso vários sistemas dependerem de um mesmo banco de dados.

      Conclusão

      Neste guia, vimos como usar as migrations e os seeders de banco de dados para facilitar a configuração de bancos de dados para desenvolvimento e teste para um aplicativo Laravel 6.

      Como um passo seguinte, talvez você queira conferir a documentação do Laravel para obter mais informações sobre como usar o compilador de consultas e como usar os Modelos eloquentes para se concentrar ainda mais no esquema do banco de dados do seu aplicativo.



      Source link

      Uma Introdução ao Gerenciamento de Configuração


      Introdução

      Em um aspecto mais amplo, o gerenciamento de configuração (GC) refere-se ao processo de manipular sistematicamente as alterações em um sistema, de maneira a manter a integridade ao longo do tempo. Embora esse processo não tenha sido originado no setor de TI, o termo é amplamente usado para se referir ao gerenciamento de configuração de servidor.

      A automação desempenha um papel essencial no gerenciamento de configuração de servidor. É o mecanismo usado para fazer o servidor alcançar um estado desejável, definido anteriormente por scripts de provisionamento usando a linguagem e os recursos específicos de uma ferramenta. A automação é, de fato, o coração do gerenciamento de configurações de servidores, e é por isso que é comum também se referir às ferramentas de gerenciamento de configuração como Ferramentas de Automação ou Ferramentas de Automação de TI.

      Outro termo comum usado para descrever os recursos de automação implementados pelas ferramentas de gerenciamento de configuração é Orquestração de Servidor ou Orquestração de TI, uma vez que essas ferramentas geralmente são capazes de gerenciar de um a centenas de servidores a partir de uma máquina controladora central.

      Existem várias ferramentas de gerenciamento de configuração disponíveis no mercado. Puppet, Ansible, Chef e Salt são escolhas populares. Embora cada ferramenta tenha suas próprias características e funcione de maneiras ligeiramente diferentes, todas elas são orientadas pelo mesmo propósito: garantir que o estado do sistema corresponda ao estado descrito pelos seus scripts de provisionamento.

      Benefícios do Gerenciamento de Configuração para Servidores

      Embora o uso do gerenciamento de configuração geralmente exija mais planejamento e esforço iniciais do que a administração manual do sistema, todas as infraestruturas de servidor, exceto as mais simples, serão aprimoradas pelos benefícios que ele oferece. Para citar alguns:

      Provisionamento Rápido de Novos Servidores

      Sempre que um novo servidor precisa ser deployado, uma ferramenta de gerenciamento de configuração pode automatizar a maior parte, se não todo, do processo de provisionamento para você. A automação torna o provisionamento muito mais rápido e eficiente, pois permite que tarefas tediosas sejam executadas com mais rapidez e precisão do que qualquer ser humano poderia. Mesmo com a documentação adequada e completa, o deployment manual de um servidor web, por exemplo, pode levar horas em comparação a alguns minutos com o gerenciamento/automação da configuração.

      Recuperação Rápida de Eventos Críticos

      Com o provisionamento rápido, vem outro benefício: recuperação rápida de eventos críticos. Quando um servidor fica offline devido a circunstâncias desconhecidas, pode levar várias horas para se auditar adequadamente o sistema e descobrir o que realmente aconteceu. Em cenários como esse, fazer o deploy de um servidor substituto geralmente é a maneira mais segura de colocar seus serviços online novamente enquanto uma inspeção detalhada é feita no servidor afetado. Com o gerenciamento e a automação da configuração, isso pode ser feito de maneira rápida e confiável.

      Não mais Servidores Snowflake

      À primeira vista, a administração manual do sistema pode parecer uma maneira fácil de fazer deploy e corrigir rapidamente os servidores, mas isso geralmente tem um preço. Com o tempo, pode se tornar extremamente difícil saber exatamente o que está instalado em um servidor e quais alterações foram feitas quando o processo não é automatizado. Os hotfixes manuais, os ajustes de configuração e as atualizações de software podem transformar os servidores em snowflakes exclusivos, difíceis de gerenciar e ainda mais difíceis de replicar. Usando uma ferramenta de GC, o procedimento necessário para lançar um novo servidor ou atualizar um existente estará documentado nos scripts de provisionamento.

      Controle de Versão para o Ambiente do Servidor

      Depois de ter sua configuração do servidor traduzida em um conjunto de scripts de provisionamento, você poderá aplicar ao ambiente do seu servidor muitas das ferramentas e fluxos de trabalho que você normalmente usa para o código-fonte de software.

      Ferramentas de controle de versão como o Git, podem ser usadas para acompanhar as alterações feitas no provisionamento e manter ramificações separadas para as versões antigas dos scripts. Você também pode usar o controle de versão para implementar uma política de code review para os scripts de provisionamento, onde todas as alterações devem ser submetidas como um pull request e aprovadas pelo líder do projeto antes de serem aceitas. Essa prática adicionará consistência extra à sua configuração de infraestrutura.

      Ambientes Replicados

      O gerenciamento de configuração torna trivial replicar ambientes com exatamente o mesmo software e as mesmas configurações. Isso permite que você crie efetivamente um ecossistema de vários estágios, com servidores de produção, desenvolvimento e teste. Você pode até usar máquinas virtuais locais para desenvolvimento, criadas com os mesmos scripts de provisionamento. Essa prática minimizará os problemas causados por discrepâncias no ambiente que ocorrem com frequência quando as aplicações são deployadas na produção ou compartilhadas entre colegas de trabalho com diferentes configurações de máquina (sistema operacional diferente, versões de software e/ou configurações).

      Visão Geral das Ferramentas de Gerenciamento de Configuração

      Embora cada ferramenta de GC tenha seus próprios termos, filosofia e ecossistema, elas geralmente compartilham muitas características e têm conceitos semelhantes.

      A maioria das ferramentas de gerenciamento de configuração usa um modelo de controlador/mestre e node/agente. Essencialmente, o controlador direciona a configuração dos nodes, com base em uma série de instruções ou tasks definidas em seus scripts de provisionamento.

      Abaixo, você encontra os recursos mais comuns presentes na maioria das ferramentas de gerenciamento de configuração para servidores:

      Framework de Automação

      Cada ferramenta de gerenciamento de configuração fornece uma sintaxe específica e um conjunto de recursos que você pode usar para escrever scripts de provisionamento. A maioria das ferramentas possui recursos que tornam sua linguagem semelhante às linguagens de programação convencionais, mas de maneira simplificada. Variáveis, loops e condicionais são recursos comuns fornecidos para facilitar a criação de scripts de provisionamento mais versáteis.

      Comportamento Idempotente

      As ferramentas de gerenciamento de configuração controlam o estado dos recursos para evitar a repetição de tarefas que foram executadas anteriormente. Se um pacote já estiver instalado, a ferramenta não tentará instalá-lo novamente. O objetivo é que, após cada execução de provisionamento, o sistema atinja (ou mantenha) o estado desejado, mesmo que você o execute várias vezes. É isso que caracteriza essas ferramentas como tendo um comportamento idempotente. Esse comportamento não é necessariamente imposto em todos os casos, no entanto.

      Fatos do Sistema (Facts)

      As ferramentas de gerenciamento de configuração geralmente fornecem informações detalhadas sobre o sistema que está sendo provisionado. Esses dados estão disponíveis através de variáveis globais, conhecidas como facts. Eles incluem coisas como interfaces de rede, endereços IP, sistema operacional e distribuição. Cada ferramenta fornecerá um conjunto diferente de facts. Eles podem ser usados para tornar os scripts e templates de provisionamento mais adaptáveis a vários sistemas.

      Sistema de Templates

      A maioria das ferramentas de GC fornecerá um sistema de templates interno que pode ser usado para facilitar a criação de arquivos e serviços de configuração. Os templates geralmente suportam variáveis, loops e condicionais que podem ser usados para maximizar a versatilidade. Por exemplo, você pode usar um template para configurar facilmente um novo virtual host no Apache, enquanto reutiliza o mesmo template para várias instalações de servidores. Em vez de ter apenas valores estáticos codificados, um template deve conter espaços reservados (placeholders) para valores que podem mudar de host para host, como NameServer e DocumentRoot.

      Extensibilidade

      Embora os scripts de provisionamento possam ser muito especializados para as necessidades e demandas de um servidor específico, há muitos casos em que você tem configurações semelhantes de servidor ou partes de uma configuração que podem ser compartilhadas entre vários servidores. A maioria das ferramentas de provisionamento fornecerá maneiras pelas quais você pode reutilizar e compartilhar facilmente pequenos blocos de sua configuração de provisionamento como módulos ou plugins.

      Módulos e plugins de terceiros geralmente são fáceis de encontrar na Internet, especialmente para configurações comuns de servidores, como a instalação de um servidor web PHP. As ferramentas de GC tendem a ter uma comunidade forte criada em torno delas e os usuários são incentivados a compartilhar suas extensões personalizadas. O uso de extensões fornecidas por outros usuários pode economizar muito tempo, além de servir como uma excelente maneira de aprender como outros usuários resolveram problemas comuns usando a ferramenta de sua escolha.

      Escolhendo uma Ferramenta de Gerenciamento de Configuração

      Existem muitas ferramentas de GC disponíveis no mercado, cada uma com um conjunto diferente de recursos e diferentes níveis de complexidade. As escolhas populares incluem Chef, Ansible e Puppet. O primeiro desafio é escolher uma ferramenta que seja adequada às suas necessidades.

      Há algumas coisas que você deve levar em consideração antes de fazer uma escolha:

      Complexidade da Infraestrutura

      A maioria das ferramentas de gerenciamento de configuração requer uma hierarquia mínima composta por uma máquina controladora e um node que será gerenciado por ela. O Puppet, por exemplo, exige que uma aplicação agent seja instalada em cada node e um aplicação master seja instalada na máquina do controlador. O Ansible, por outro lado, possui uma estrutura descentralizada que não requer instalação de software adicional nos nodes, mas depende do SSH para executar as tarefas de provisionamento. Para projetos menores, uma infraestrutura simplificada pode parecer melhor, no entanto, é importante levar em consideração aspectos como escalabilidade e segurança, que podem não ser impostos pela ferramenta.

      Algumas ferramentas podem ter mais componentes e partes móveis, o que pode aumentar a complexidade da sua infraestrutura, impactando na curva de aprendizado e possivelmente aumentando o custo geral de implementação.

      Curva de Aprendizado

      Como mencionado anteriormente neste artigo, as ferramentas de GC fornecem uma sintaxe personalizada, às vezes usando uma linguagem de domínio específico (DSL) e um conjunto de recursos que compõem seu framework de automação. Como nas linguagens de programação convencionais, algumas ferramentas exigem uma curva de aprendizado mais alta para serem dominadas. Os requisitos de infraestrutura também podem influenciar a complexidade da ferramenta e a rapidez com que você poderá ver um retorno do investimento.

      Custo

      A maioria das ferramentas de GC oferece versões gratuitas ou open source, com assinaturas pagas para recursos e serviços avançados. Algumas ferramentas terão mais limitações que outras, portanto, dependendo de suas necessidades específicas e de como sua infraestrutura cresce, você pode acabar tendo que pagar por esses serviços. Você também deve considerar o treinamento como um custo extra em potencial, não apenas em termos monetários, mas também em relação ao tempo necessário para atualizar sua equipe com a ferramenta que você acabou escolhendo.

      Ferramentas Avançadas

      Como mencionado anteriormente, a maioria das ferramentas oferece serviços pagos que podem incluir suporte, extensões e ferramentas avançadas. É importante analisar suas necessidades específicas, o tamanho da sua infraestrutura e se há ou não a necessidade de usar esses serviços. Os painéis de gerenciamento, por exemplo, são um serviço comum oferecido por essas ferramentas e podem facilitar muito o processo de gerenciamento e monitoramento de todos os seus servidores a partir de um ponto central. Mesmo que você ainda não precise desses serviços, considere as opções para uma possível necessidade futura.

      Comunidade e Suporte

      Uma comunidade forte e acolhedora pode ser extremamente útil em termos de suporte e documentação, pois os usuários geralmente ficam felizes em compartilhar seu conhecimento e suas extensões (módulos, plugins e scripts de provisionamento) com outros usuários. Isso pode ser útil para acelerar sua curva de aprendizado e evitar custos extras com suporte ou treinamento pagos.

      Visão Geral das Ferramentas Populares

      A tabela abaixo deve lhe fornecer uma rápida visão geral das principais diferenças entre as três ferramentas de gerenciamento de configuração mais populares disponíveis no mercado atualmente: Ansible, Puppet e Chef.

      Ansible Puppet Chef
      Linguagem do Script YAML DSL personalizada baseada em Ruby Ruby
      Infraestrutura A máquina controladora aplica a configuração nos nodes via SSH O Puppet Master sincroniza a configuração nos Puppet Nodes As Workstations do Chef enviam a configuração para o Chef Server, a partir do qual os nodes do Chef serão atualizados
      Requer software especializado para os nodes Não Sim Sim
      Fornece ponto de controle centralizado Não. Qualquer computador pode ser um controlador Sim, via Puppet Master Sim, via Chef Server
      Terminologia do script Playbook / Roles Manifests / Modules Recipes / Cookbooks
      Ordem de Execução das Tarefas Sequencial Não-sequencial Sequencial

      Próximos Passos

      Até agora, vimos como o gerenciamento de configuração funciona para servidores e o que considerar ao escolher uma ferramenta para criar sua infraestrutura de gerenciamento de configuração. Nos guias subsequentes desta série, teremos uma experiência prática com três ferramentas populares de gerenciamento de configuração: Ansible, Puppet e Chef.

      Para que você possa comparar essas ferramentas por si mesmo, usaremos um exemplo simples de configuração de servidor que deve ser totalmente automatizado por cada ferramenta. Essa configuração consiste em um servidor Ubuntu 18.04 executando o Apache para hospedar uma página web simples.

      Conclusão

      O gerenciamento de configuração pode melhorar drasticamente a integridade dos servidores ao longo do tempo, fornecendo um framework para automatizar processos e acompanhar as alterações feitas no ambiente do sistema. No próximo guia dessa série, veremos como implementar uma estratégia de gerenciamento de configuração na prática usando Ansible como ferramenta.



      Source link