Tutorial

Como Instalar Linux, Nginx, MySQL, PHP (pilha LEMP) no Ubuntu 20.04

NginxUbuntuPHPLEMPUbuntu 20.04

Introdução

A pilha de software LEMP é um grupo de softwares que pode ser usado para exibir páginas e aplicativos Web dinâmicos escritos em PHP. Este é um acrônimo que descreve um sistema operacional Linux, com um servidor Web Nginx (se pronuncia “Engine-X). Os dados do backend são armazenados no banco de dados MySQL e o processamento dinâmico é tratado pelo PHP.

Este guia demonstra como instalar uma pilha LEMP em um servidor Ubuntu 20.04. O sistema operacional Ubuntu cuida do primeiro requisito. Vamos descrever como colocar o resto dos componentes em funcionamento.

Pré-requisitos

Para completar este tutorial, você precisará de acesso a um servidor Ubuntu 20.04, como um usuário sudo regular, não root , e um firewall habilitado em seu servidor. Para configurar isto, siga nosso guia de configuração inicial de servidor para o Ubuntu 20.04.

Passo 1 — Como instalar o servidor Web Nginx

Para mostrar páginas Web aos visitantes de nosso site, vamos usar o Nginx, um servidor Web de alto desempenho. Usaremos o gerenciador de pacotes apt para obter esse software.

Uma vez que essa é a primeira vez que vamos usar o apt para esta sessão, atualize o índice de pacotes do seu servidor. Em seguida, você pode usar o apt install para instalar o Nginx:

  • sudo apt update
  • sudo apt install nginx

Quando solicitado, digite y para confirmar se deseja instalar o Nginx. Assim que a instalação terminar, o servidor web Nginx estará ativo e em execução em seu servidor Ubuntu 20.04.

Se você tiver o firewall ufw habilitado, conforme recomendado em nosso guia de configuração inicial de servidor, você precisará permitir conexões com o Nginx. O Nginx registra alguns perfis diferentes de aplicações no UFW após a instalação. Para verificar quais perfis do UFW estão disponíveis, execute:

  • sudo ufw app list
Output
Available applications: Nginx Full Nginx HTTP Nginx HTTPS OpenSSH

É recomendável que você habilite o perfil mais restritivo que, ainda assim, permitirá o tráfego que você precisa. Como você ainda não configurou o SSL para seu servidor neste guia, você precisará apenas permitir o tráfego HTTP regular na porta 80.

Habilite isso digitando:

  • sudo ufw allow 'Nginx HTTP'

Verifique a mudança executando:

  • sudo ufw status

A saída deste comando irá mostrar que o tráfego HTTP está permitido agora:

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

Com essas novas regras adicionadas no firewall, você pode testar se o servidor está funcionando acessando o nome do domínio do seu servidor ou endereço IP público no seu navegador Web.

Se você não tiver um nome de domínio apontando para o seu servidor e você não souber o endereço IP público dele, é possível encontrá-lo executando o seguinte comando:

  • ip addr show eth0 | grep inet | awk '{ print $2; }' | sed 's/\/.*$//'

Isso irá mostrar na tela alguns endereços IP. Você pode testar cada um deles em seu navegador Web.

Como uma alternativa, verifique qual endereço IP está acessível, como visto por outros locais na internet:

  • curl -4 icanhazip.com

Digite o endereço que receber no seu navegador Web e ele irá levá-lo para a página inicial do Nginx:

http://server_domain_or_IP

Nginx default page

Se você vir essa página, significa que você instalou o Nginx com sucesso e habilitou o tráfego HTTP para seu servidor web.

Passo 2 — Instalando o MySQL

Agora que você tem um servidor web funcionando, você precisa instalar um sistema de banco de dados, para conseguir armazenar e gerenciar os dados do seu site. O MySQL é um sistema de gerenciamento de banco de dados popular, usado em ambientes PHP.

Novamente, utilize o apt para adquirir e instalar este software:

  • sudo apt install mysql-server

Quando solicitado, confirme a instalação digitando Y e, depois, ENTER.

Quando a instalação terminar, é recomendável que você execute um script de segurança que vem pré-instalado com o MySQL. Esse script removerá algumas configurações padrão inseguras e irá bloquear o acesso ao seu sistema de banco de dados. Inicie o script interativo executando:

  • sudo mysql_secure_installation

Este script irá perguntar se você deseja configurar o VALIDATE PASSWORD PLUGIN.

Atenção: ativar esta característica é uma decisão sua. Se habilitada, as senhas que não corresponderem ao critério especificado serão rejeitadas pelo MySQL com um erro. É seguro deixar a validação desativada, mas sempre utilize senhas fortes e únicas para as credenciais do banco de dados.

Responda Y para sim, ou qualquer outra coisa para continuar sem a habilitar.

VALIDATE PASSWORD PLUGIN can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD plugin?

Press y|Y for Yes, any other key for No:

Se você responder "yes”, você será solicitado a selecionar um nível de validação por senha. Lembre-se de que se você digitar 2 para o nível mais forte você receberá erros ao tentar definir qualquer senha que não contenha números, letras maiúsculas e minúsculas, e caracteres especiais, ou que baseiam-se em palavras comuns do dicionário.

There are three levels of password validation policy:

LOW    Length >= 8
MEDIUM Length >= 8, numeric, mixed case, and special characters
STRONG Length >= 8, numeric, mixed case, special characters and dictionary              file

Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 1

Independentemente de você ter escolhido VALIDATE PASSWORD PLUGIN, seu servidor irá pedir a você para selecionar e confirmar uma senha para o.root user do MySQL. Isso não deve ser confundido com o root do sistema. O usuário root do banco de dados é um usuário administrativo com privilégios totais sobre o sistema de banco de dados. Embora o método de autenticação predefinido para o usuário root dispense o uso de uma senha, mesmo quando uma senha está definida, você deve definir uma senha forte aqui como uma medida de segurança adicional. Vamos falar sobre isso em breve.

Se você habilitar a validação por senha, será apresentado a você a força da senha para a senha root. e o seu servidor perguntará se você deseja continuar com essa senha. Se estiver satisfeito com sua senha atual, digite Y para “yes” no prompt:

Estimated strength of the password: 100
Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : y

Para o resto das perguntas, pressione Y e pressione a tecla ENTER em cada prompt. Isso removerá alguns usuários anônimos e o banco de dados de teste, desativará os logins remotos para o root e carregará essas novas regras para que o MySQL respeite imediatamente as alterações que você fez.

Quando terminar, teste se você consegue fazer login no console do MySQL digitando:

  • sudo mysql

Isso conectará ao servidor MySQL como usuário administrativo root do banco de dados, o que é pressuposto pelo uso do sudo ao executar esse comando. Você deve ver um resultado como este:

Output
Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 22 Server version: 8.0.19-0ubuntu5 (Ubuntu) Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>

Para sair do console do MySQL, digite:

  • exit

Note que você não precisa fornecer uma senha para se conectar como root user, embora você tenha definido uma ao executar o script mysql_secure_installation. Isso é porque o método de autenticação padrão para o usuário administrativo do MySQL é unix_socket, em vez de password (senha). Embora, num primeiro momento, isso possa parecer um problema de segurança, tal medida torna o servidor de banco de dados mais seguro, uma vez que que os únicos usuários autorizados a fazer login como usuário root do MySQL são os usuários do sistema com privilégios sudo que conectam-se pelo console ou através de uma aplicação executando com os mesmos privilégios. Em termos práticos, isso significa que você não conseguirá usar o usuário root do banco de dados administrativo para se conectar a partir do seu aplicativo PHP. Definir uma senha para a conta root do MySQL funciona como uma salvaguarda, caso o método de autenticação padrão seja alterado de unix_socket para password.

Para aumentar a segurança, o melhor é configurar contas de usuário dedicadas, com privilégios menos abrangentes em relação a cada banco de dados, especialmente se você planeja ter vários bancos de dados hospedados no seu servidor.

Nota: no momento em que este artigo foi escrito, a biblioteca nativa do PHP para o MySQL mysqlnd não suporta o caching_sha2_authentication, o método de autenticação padrão para o MySQL 8. Por essa razão, ao criar usuários de banco de dados para aplicações PHP no MySQL 8, você precisará garantir que eles estejam configurados para usar o mysql_native_password. Vamos demonstrar como fazer isso no Passo 6.

Agora, seu servidor MySQL está instalado e protegido. Em seguida, instalaremos o PHP, o componente final na pilha LEMP.

Passo 3 — Instalando o PHP

Você tem o Nginx instalado para exibir seu conteúdo e o MySQL instalado para armazenar e gerenciar seus dados. Agora, você pode instalar o PHP para processar código e gerar conteúdo dinâmico para o servidor Web.

Enquanto o Apache incorpora o interpretador PHP em cada solicitação, o Nginx necessita de um programa externo para lidar com o processamento PHP e atuar como uma ponte entre o próprio interpretador PHP e o servidor web. Isso permite um desempenho global melhor na maioria dos sites baseados em PHP, mas exige configuração adicional. Será necessário instalar o php-fpm, que significa “Gerenciador de processos PHP fastCGI”, e dizer ao Nginx para enviar as solicitações PHP para esse software para processamento. Adicionalmente, você precisará do php-mysql , um módulo PHP que permite ao PHP se comunicar com os bancos de dados baseados em MySQL. Os pacotes básicos do PHP serão instalados automaticamente como dependências.

Para instalar os pacotes php-fpm e php-mysql, execute:

  • sudo apt install php-fpm php-mysql

Quando solicitado, digite Y e ENTER para confirmar a instalação.

Agora, você tem seus componentes PHP instalados. Em seguida, você configurará o Nginx para utilizá-los.

Passo 4 — Configurando o Nginx para Usar o Processador PHP

Ao usar o servidor web Nginx, podemos utilizar os blocos de servidor (similares aos virtual hosts no Apache) para encapsular detalhes de configuração e hospedar mais de um domínio em um único servidor. Neste guia, usaremos your_domain como um nome de domínio de exemplo. Para aprender mais sobre como configurar um nome de domínio com a DigitalOcean, veja nossa Introdução ao DNS do DigitalOcean.

No Ubuntu 20.04, o Nginx tem um bloco de servidor habilitado por padrão que está configurado para servir documentos do diretório /var/www/html. Enquanto isso funciona bem para um único site, isso se torna difícil de gerenciar se você estiver hospedando vários sites. Em vez de modificar o /var/www/html, vamos criar uma estrutura de diretórios dentro do /var/www para o site your_domain, deixando o /var/www/html intocado como o diretório padrão para ser servido se uma solicitação de cliente não corresponder a nenhum outro site.

Crie o diretório para your_domain como segue:

  • sudo mkdir /var/www/your_domain

Em seguida, atribua a propriedade do diretório com a variável de ambiente $USER, que deve fazer referência ao seu usuário de sistema atual:

  • sudo chown -R $USER:$USER /var/www/your_domain

Em seguida, abra um novo arquivo de configuração no diretório sites-available do Nginx usando seu editor de linha de comando preferido. Aqui, usaremos o nano:

  • sudo nano /etc/nginx/sites-available/your_domain

Isso criará um novo arquivo em branco. Cole nele a seguinte configuração:

/etc/nginx/sites-available/your_domain
server {
    listen 80;
    server_name your_domain www.your_domain;
    root /var/www/your_domain;

    index index.html index.htm index.php;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
     }

    location ~ /\.ht {
        deny all;
    }

}


Aqui está o que cada um desses blocos de localização e diretrizes fazem:

  • listen — Define em qual porta o Nginx irá escutar. Neste caso, ele irá escutar na porta 80, a porta padrão para o HTTP.
  • root — Define o document root onde os arquivos servidos por este site são armazenados.
  • index — Define em que ordem o Nginx irá priorizar os arquivos de index para este site. É uma prática comum listar arquivos index.html com uma precedência superior aos arquivos index.php para permitir uma configuração rápida de uma página inicial de manutenção em aplicações PHP. Você pode ajustar essas configurações para melhor se adaptar às necessidades da sua aplicação.
  • server_name — Define para quais nomes de domínio e/ou endereços IP este bloco de servidor deve responder. Aponte esta diretiva para o nome de domínio do seu servidor ou endereço IP público.
  • location/ — O primeiro bloco de localização inclui uma diretiva try_files, que verifica a existência de arquivos ou diretórios que correspondam a uma requisição de URI. Se o Nginx não puder encontrar o recurso apropriado, ele irá retornar um erro 404.
  • location ~ \.php$ — Este bloco de localização lida com o processamento PHP real, apontando o Nginx para o arquivo de configuração fastcgi-php.conf e o arquivo php7.4-fpm.sock, que declara qual soquete está associado ao php-fpm.
  • location ~ /\.ht — O último bloco de localização lida com os arquivos .htaccess, que o Nginx não processa. Ao adicionar a diretiva deny all, se acontecer de algum arquivo .htaccess ser encontrado no caminho do document root, ele não será apresentado aos visitantes.

Quando terminar de editar, salve e feche o arquivo. Se você estiver usando o nano, você pode fazer isso digitando CTRL+X e, depois, y e ENTER para confirmar.

Ative sua configuração vinculando ao arquivo de configuração no diretório sites-enabled do Nginx:

  • sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/

Isso dirá ao Nginx para usar a configuração da próxima vez que ela for recarregada. Teste a configuração para conferir erros de sintaxe digitando:

  • sudo nginx -t

Se algum erro for reportado, volte para seu arquivo de configuração para revisar seu conteúdo antes de continuar.

Quando estiver pronto, recarregue o Nginx para aplicar as alterações:

  • sudo systemctl reload nginx

Agora, seu novo site está ativo, mas o web root /var/www/your_domain ainda está vazio. Crie um arquivo index.html naquele local para que possamos testar se o seu novo bloco de servidor funciona conforme esperado:

  • nano /var/www/your_domain/index.html

Inclua o conteúdo a seguir neste arquivo:

/var/www/your_domain/index.html
<html>
  <head>
    <title>your_domain website</title>
  </head>
  <body>
    <h1>Hello World!</h1>

    <p>This is the landing page of <strong>your_domain</strong>.</p>
  </body>
</html>

Agora, vá para seu navegador e acesse o nome de domínio ou endereço IP do seu servidor, conforme listado na diretiva server_name em seu arquivo de configuração de bloco de servidor:

http://server_domain_or_IP

Você verá uma página como esta:

Nginx server block

Se você vir esta página, isso significa que seu bloco de servidor do Nginx está funcionando como esperado.

Você pode deixar esse arquivo funcionando como uma página principal temporária para sua aplicação até que você configure um arquivo index.php para substituí-lo. Assim que fizer isso, lembre-se de remover ou renomear o arquivo index.html de seu document root pois isso teria precedência sobre um arquivo index.php por padrão.

Sua pilha LEMP está totalmente configurada agora. No próximo passo, criaremos um script PHP para testar se o Nginx é, de fato, capaz de lidar com arquivos .php dentro do seu site recém configurado.

Passo 5 — Testando o PHP com o Nginx

Sua pilha LEMP agora deve estar configurada completamente. Você pode testá-la para validar que o Nginx pode manusear corretamente os arquivos .php para o seu processador PHP.

Você pode fazer isso criando um arquivo PHP de teste em seu document root. Abra um novo arquivo chamado info.php dentro do documento raiz no editor de texto:

  • nano /var/www/your_domain/info.php

Digite ou cole as seguintes linhas dentro do novo arquivo: Este é um código PHP válido que irá retornar informações sobre seu servidor:

/var/www/your_domain/info.php
<?php
phpinfo();

Quando você terminar, salve e feche o arquivo digitando CTRL+X e, depois, y e ENTER para confirmar.

Agora, você pode acessar essa página em seu navegador web visitando o nome de domínio ou o endereço IP público que você configurou em seu arquivo de configuração do Nginx, seguido por /info.php:

http://server_domain_or_IP/info.php

Você verá uma página web contendo informações detalhadas sobre seu servidor:

PHPInfo Ubuntu 20.04

Após verificar as informações relevantes sobre seu servidor PHP através dessa página, é melhor remover o arquivo que você criou, uma vez que ele contém informações sensíveis sobre seu ambiente PHP e seu servidor Ubuntu. Use o rm para remover esse arquivo:

  • sudo rm /var/www/your_domain/info.php

Você sempre pode gerar esse arquivo novamente se você precisar dele mais tarde.

Passo 6 — Testando a Conexão com o Banco de Dados pelo PHP (Opcional)

Se você quiser testar se o PHP é capaz de se conectar ao MySQL e executar consultas ao banco de dados, você pode criar uma tabela de teste, com dados fictícios, e fazer uma consulta em seu conteúdo, a partir de um script PHP. Antes que possamos fazer isso, precisamos criar um banco de dados de teste e um novo usuário do MySQL corretamente configurado para acessá-lo.

No momento em que este artigo foi escrito, a biblioteca mysqlnd nativa do PHP para o MySQL não suporta o caching_sha2_authentication, o método de autenticação padrão para o MySQL 8. Precisaremos criar um novo usuário com o método de autenticação mysql_native_password para conseguir se conectar ao banco de dados MySQL a partir do PHP.

Vamos criar um banco de dados chamado example_database e um usuário chamado example_user, mas você pode substituir esses nomes por valores diferentes.

Primeiro, conecte-se ao console do MySQL usando a conta root:

  • sudo mysql

Para criar um novo banco de dados, execute o seguinte comando a partir do seu console do MySQL:

  • CREATE DATABASE example_database;

Agora, crie um usuário e lhe conceda privilégios completos sobre o banco de dados personalizado que acabou de criar.

O comando a seguir cria um novo usuário chamado example_user usando o mysql_native_password como o método de autenticação padrão. Vamos definir a senha do usuário como password, mas você deve substituir esse valor por uma senha segura de sua própria escolha:

  • CREATE USER 'example_user'@'%' IDENTIFIED WITH mysql_native_password BY 'password';

Agora, precisamos dar a este usuário permissão para o banco de dados example_database:

  • GRANT ALL ON example_database.* TO 'example_user'@'%';

Isso dará ao usuário example_user privilégios totais sobre o banco de dados example_database, ao mesmo tempo que impedirá que esse usuário crie ou altere outros bancos de dados no seu servidor.

Agora, saia do shell do MySQL com:

  • exit

Você pode testar se o novo usuário tem as permissões adequadas fazendo login no console MySQL novamente, desta vez usando as credenciais de usuário personalizadas:

  • mysql -u example_user -p

Note a flag -p neste comando, a qual irá solicitar a senha utilizada ao criar o usuário example_user. Após fazer login no console do MySQL, confirme se você tem acesso ao banco de dados example_database:

  • SHOW DATABASES;

Isso gerará o seguinte resultado:

Output
+--------------------+ | Database | +--------------------+ | example_database | | information_schema | +--------------------+ 2 rows in set (0.000 sec)

Em seguida, criaremos uma tabela de teste chamada todo_list. A partir do console do MySQL, execute a seguinte instrução:

  • CREATE TABLE example_database.todo_list (
  • item_id INT AUTO_INCREMENT,
  • content VARCHAR(255),
  • PRIMARY KEY(item_id)
  • );

Insira algumas linhas de conteúdo na tabela de teste. Talvez queira repetir o próximo comando algumas vezes, usando valores diferentes:

  • INSERT INTO example_database.todo_list (content) VALUES ("My first important item");

Para confirmar se os dados foram salvos com sucesso em sua tabela, execute:

  • SELECT * FROM example_database.todo_list;

Você verá o seguinte resultado:

Output
+---------+--------------------------+ | item_id | content | +---------+--------------------------+ | 1 | My first important item | | 2 | My second important item | | 3 | My third important item | | 4 | and this one more thing | +---------+--------------------------+ 4 rows in set (0.000 sec)

Após confirmar que você tem dados válidos em sua tabela de teste, saia do console do MySQL:

  • exit

Agora, você pode criar o script PHP que se conectará ao MySQL e irá consultar seu conteúdo. Crie um arquivo do PHP no seu diretório raiz da Web personalizado, usando seu editor preferido. Usaremos o nano para isso:

  • nano /var/www/your_domain/todo_list.php

O script PHP a seguir se conecta ao banco de dados MySQL e consulta o conteúdo da tabela todo_list, mostrando os resultados em uma lista. Se houver um problema com a conexão do banco de dados, ele irá gerar uma exceção. Copie este conteúdo para seu script todo_list.php:

/var/www/your_domain/todo_list.php
<?php
$user = "example_user";
$password = "password";
$database = "example_database";
$table = "todo_list";

try {
  $db = new PDO("mysql:host=localhost;dbname=$database", $user, $password);
  echo "<h2>TODO</h2><ol>";
  foreach($db->query("SELECT content FROM $table") as $row) {
    echo "<li>" . $row['content'] . "</li>";
  }
  echo "</ol>";
} catch (PDOException $e) {
    print "Error!: " . $e->getMessage() . "<br/>";
    die();
}

Salve e feche o arquivo quando terminar de editar.

Agora, você pode acessar esta página em seu navegador web visitando o nome de domínio ou o endereço IP público para seu site, seguido de /todo_list.php:

http://server_domain_or_IP/todo_list.php

Você deve ver uma página como esta, mostrando o conteúdo que você inseriu em sua tabela de teste:

Example PHP todo list​​​​​

Isso significa que seu ambiente PHP está pronto para se conectar e interagir com seu servidor MySQL.

Conclusão

Neste guia, construímos uma base flexível para servir sites e aplicações PHP aos seus visitantes, usando o Nginx como servidor web e o MySQL como sistema de banco de dados.

Há um número de passos que você pode tomar a partir daqui. Por exemplo, certifique-se de que as conexões para seu servidor estejam seguras. Para isso, você pode proteger sua instalação Nginx com o Let’s Encrypt. Ao seguir este guia, você receberá um certificado TLS/SSL gratuito para seu servidor, permitindo que apresente conteúdo em HTTPS.

Creative Commons License