Deploy Laravel 6 utilizando a ferramenta Deployer - Aristides Neto
Aprenda a fazer o deploy da sua aplicação Laravel utilizando uma ferramenta de deploy.
Por Aristides Neto , 28 Dec 2019 | Laravel
Mais um artigo hoje, no formato tutorial. Nesse artigo aprenderemos como fazer o deploy de uma aplicação desenvolvida com o Laravel, usando uma ferramenta de deploy.
O Deployer é uma ferramenta desenvolvida em PHP e que faz todo o trabalho pesado em realizar o deploy da sua aplicação PHP, seja usando um framework ou não.
Todos os passos a seguir, foram executados usando o sistema operacional Linux.
Conta no Bitbucket (ou em outro repositório git)
Uma VPS (estou usando a Digital Ocean)
Servidor com Nginx, PHP e Mysql instalados
Node e NPM instalados no servidor
Acesso root (ou sudo) ao servidor via SSH
Te indico a leitura de 3 artigos do meu blog que pode te ajudar em caso de alguma dúvida de alguns tópicos desse tutorial, são eles:
Configuração de um servidor web usando LEMP no Debian 9. Criando um usuário e configurando o SSH
Aprenda a configurar um servidor web usando LEMP no Debian 9. Iremos instalar o Nginx, MariaDB e PHP 7.2
Aprenda a instalação e a configuração básica de como criar um server block com o servidor web Nginx
Serão criados dois ambientes, de produção e homologação. Para acessarmos a aplicação, nesse tutorial iremos utilizar o IP do servidor, mas caso queira pode ser usado um domínio válido e configurado. Por exemplo, caso esteja usando um domínio, crie um subdomínio com o prefixo homolog.seusite.com.br. Esse será o endereço para o ambiente de homologação, e o seusite.com.br o endereço de produção.
Para o meu caso, irei usar o IP e definir as portas para diferenciar os ambientes, por exemplo, a porta 80 para produção e 81 para homologação.
Instalando o Deployer
A instalação deve ser feita na máquina de desenvolvimento. Para isso digite os 3 comandos abaixo em seu terminal.
No comando acima, é feito o download do arquivo deployer.phar e em seguinda movemos o arquivo para o diretório /usr/local/bin renomeando para dep, e para finalizar concedemos permissão de execução para o arquivo.
Para testar o deployer, execute no seu terminal o comando:
dep --version
Se aparecer a versão do Deployer, sucesso!
Nesse exemplo iremos baixar uma aplicação Laravel usando o composer. Não terá nenhuma regra de negócio na aplicação, apenas irei criar a autenticação padrão do Laravel e uma implementação a mais para que o deploy funcione corretamente.
mkdir -p ~/projetos/deployer/
cd ~/projetos/deployer
Com o projeto criado, entre no diretório da aplicação e execute os comandos abaixo para criar a autenticação padrão do Laravel 6 (Esse passo é somente para o Laravel 6+).
Para que esse exemplo funcione, é necessário criar um controller e alterar a rota barra ( / ) do Laravel. Durante o deploy é executado o comando artisan config:cache, e esse comando não funciona se existir uma rota que esteja usando uma função anônima, conhecida também como closure, ou seja, a rota inicial do Laravel utiliza uma função anônima.
Para resolver, crie um controller chamado WelcomeController e altere a rota para:
No arquivo WelcomeController, adicione no método index(), o return para a view welcome.
No arquivo de rotas da API routes/api.php também existe uma função anônima, nesse caso basta remover a rota que o problema é resolvido.
Até esse momento temos nossa aplicação Laravel funcionando e com a autenticação padrão gerada, apenas faltando a conexão com o banco de dados, mas agora não será preciso se preocupar com isso. Vamos fazer isso mais para frente.
Conhecendo o Deployer
Antes de começar com o deployer, vamos conhecer alguns de seus comandos. Digite no terminal:
Você verá os comandos disponíveis e dentre eles existe o comando init. Essa opção criará o template inicial de uma configuração, é possível também passar um parâmetro informando qual template gostaria de usar. Vamos ver na prática o comando dep init.
Dentro do diretório do seu projeto, digite o comando abaixo:
Veja o retorno do comando:
Welcome to the Deployer config generator
This utility will walk you through creating a deploy.php file.
Please select your project type [Common]:
[0 ] Common
[1 ] Laravel
[2 ] Symfony
[3 ] Yii
[4 ] Yii2 Basic App
[5 ] Yii2 Advanced App
[6 ] Zend Framework
[7 ] CakePHP
[8 ] CodeIgniter
[9 ] Drupal
[10] TYPO3
O resultado desse comando é uma lista de Tipos de Projeto disponíveis para o uso, o padrão é uma aplicação Common, que seria uma aplicação comum em PHP, sem o uso de frameworks.
Selecione a opção 1 para escolher o template Laravel. Em seguida será solicitado que informe o repositório de onde está seu projeto, apenas dê enter, iremos configurar depois. Em seguida ele pergunta se deseja contribuir com a ferramenta enviando informações anônimas, escolha sim ou não.
Finalizado esses passos, veja que no diretório raiz da sua aplicação foi criado um arquivo chamado deploy.php.
Dica: Podemos criar o mesmo arquivo deploy.php informando o parâmetro -t seguido do nome do template. Veja como ficaria para nosso exemplo:
Configurando o Deployer
Abra o arquivo deploy.php criado na raiz do seu projeto e vamos brincar um pouco.
No trecho abaixo, informamos o endereço do repositório onde a aplicação se encontra. Caso você não tenha essa url ainda, no tópico Versionando a aplicação eu falo sobre isso, deixe como está nesse momento, depois basta atualizar essa informação.
set('repository', '[email protected]:username/deployer-laravel.git');
Dica importante: O repositório fica disponível através de dois endereços: [email protected] e https://[email protected] Existem diferenças entre eles, para que a primeira opção funcione é necessário ter cadastrado a chave pública do SSH no Bitbucket. Na segunda opção é necessário informar a senha para cada requisição realizada.
Na próxima configuração, definimos o host da aplicação, podemos ter um, dois ou mais hosts configurados. Nesse exemplo criaremos dois, de produção e homologação.
->hostname('[email protected]')
->port(33458)
->stage('prod')
->set('keep_releases', 6)
->set('branch', 'master')
->set('deploy_path', '/var/www/html/production-my-app');
host('homolog')
->stage('hml')
->set('keep_releases', 3)
->set('branch', 'develop')
->set('deploy_path', '/var/www/html/homolog-my-app');
O código em si é bem simples de entender, mas vou explicar o que cada linha significa:
host: é o nome que identifica aquela conexão
hostname: usuário que será utilizado para fazer o deploy e o IP do servidor
port: porta SSH utilizada (se a porta for a padrão 22, essa opção pode ser omitida)
stage: um alias para o host (sempre utilize)
keep_releases: número de versões que será mantido no servidor
branch: branch que será utilizado ao realizar o deploy
deploy_path: diretório onde se encontra a aplicação
O parâmetro stage eu recomendo utilizar porque utilizando o stage com a opção abaixo, o default_stage, quer dizer que sempre ao realizar um deploy (sem informar o host como parâmetro) será realizado em homologação, assim evitando que seja feito deploy para produção sem querer.
// Stage default
set('default_stage', 'hml');
O restante das informações são bem auto explicativas, caso tiver com dúvidas deixe sua pergunta nos comentários, e não deixe de olhar a documentação do deployer, vale a pena.
Versionando a aplicação
Crie um repositório no bitbucket e copie a url do seu repositório, com essa url você poderá atualizar o arquivo deploy.php conforme mencionei no tópico anterior.
Dentro do diretório do seu projeto, vamos utilizar o git para versionar e enviar para o bitbucket.
cd ~/projetos/deployer/blog
git commit -m "Primeiro commit"
git remote add origin https://[email protected]/username/deployer-laravel.git
Acabamos de enviar para o repositório nossa aplicação.
Vamos criar um branch chamado develop, que será nosso branch de homologação. Também iremos enviar para o bitbucket.
Pronto! Até o momento temos nossa aplicação Laravel versionada no Bitbucket com dois branchs (master e develop).
Criando banco de dados e usuário Mysql
Agora os passos a seguir serão executados no servidor.
Acesse o servidor via SSH para criarmos o banco de dados da nossa aplicação. Digite no terminal os comandos abaixo para criar o banco:
mysql -uroot -psenha
CREATE USER 'deployer'@'localhost' IDENTIFIED BY 'senhaforteaqui';
GRANT ALL PRIVILEGES ON laravel . * TO 'deployer'@'localhost';
Pronto, criamos nosso banco de dados chamado laravel e criamos também um usuário com todos os privilégios para que possamos conectar no banco.
Configurando usuário deploy
Ainda logado no servidor, crie um usuário shell que será responsável em realizar o deploy da sua aplicação:
# Informe uma senha forte
# Adicionando o deploy no grupo www-data
Ainda no servidor, vamos criar dois diretórios que irão hospedar nossa aplicação web e alterar o dono para o usuário deploy. Digite os seguintes comandos:
mkdir -p /var/www/html/production-my-app
mkdir -p /var/www/html/homolog-my-app
chown deploy:deploy /var/www/html/production-my-app
chown deploy:deploy /var/www/html/homolog-my-app
Configurando arquivo host do Nginx
Entre no diretório de configuração de sites do nginx e crie dois arquivos de configuração.
touch production.conf homolog.conf
Agora copie e cole o conteúdo abaixo dentro do arquivo production.conf.
Lembre-se de alterar as informações referente ao seu host, por exemplo o IP e a porta caso necessário.
# Arquivo production.conf
server_name 174.138.55.236;
# Directory root
root /var/www/html/production-my-app/current/public;
# Note que aqui definimos a versao que iremos utilizar do PHP
# Set header expirations on per-project basis
Abra o arquivo homolog.conf e cole o conteúdo abaixo:
# Arquivo homolog.conf
root /var/www/html/homolog-my-app/current/public;
Ative os dois sites que acabamos de configurar:
ln -s /etc/nginx/sites-available/production.conf /etc/nginx/sites-enabled/
ln -s /etc/nginx/sites-available/homolog.conf /etc/nginx/sites-enabled/
Pronto. Arquivos vhost do nginx configurados. Se você tentar acessar agora, não funcionará, pois ainda falta realizar o deploy da aplicação, calma que vamos chegar lá.
Configurando chaves SSH no Bitbucket
Para que o deploy funcione sem a necessidade de informar a senha, vamos criar uma chave SSH para o usuário deploy.
Logue no servidor com o usuário deploy criado neste tutorial e digite o comando:
# Acessando o servidor com o usuário deploy
# Gerar chaves SSH
Confirme as informações, quando solicitar uma senha, não é necessário informar, apenas dê enter até finalizar.
Será gerado dois arquivos em /home/deploy/.ssh chamado id_rsa (chave privada) e id_rsa.pub (chave pública).
Copie todo o conteúdo do arquivo id_rsa.pub e siga os passos:
Abra sua conta do bitbucket
Clique sobre sua foto de perfil e em Bitbucket settings
No painel da esquerda clique em SSH Keys
Clique no botão Add key e cole o conteúdo no campo key
Dê um nome para identificar essa chave
Clique em Add key para salvar as informações
Nesse ponto a comunicação do servidor e bitbucket já pode ser feita através das chaves SSH de maneira segura e sem a necessidade de informar uma senha.
Apenas para efeito de teste, vamos clonar nosso repositório no servidor. Copie a url do repositório que pode ser obtida no próprio repositório, e dentro do diretório /home/deploy (no servidor) cole a url do repositório e dê enter:
git clone [email protected]:username/deployer-laravel.git
Irá aparecer uma mensagem para que confirme o host e que seja adicionado na lista de hosts confiáveis, informe yes para continuar.
Sucesso. Seu repositório foi clonado.
Ufa, chegamos no deploy!
Bom, vamos ver como ficou o nosso arquivo de deploy? Após nossas configurações o arquivo deve estar parecido com esse:
set('application', 'My APP');
task('npm_run', function () {
// Descomente esse if após o primeiro deploy
//if (has('previous_release')) {
//    run('cp -R {{previous_release}}/node_modules {{release_path}}/node_modules');
run('cd {{release_path}} && npm run prod');
// Descomente essa linha após o primeiro deploy
// before('deploy:symlink', 'artisan:migrate');
Um detalhe muito importante para fazermos antes do primeiro deploy é comentar a última linha, ela é responsável em executar a migrate, se fizermos o deploy com a migrate sem antes configurar o arquivo .env no servidor, irá dar erro de conexão com o banco de dados e isso é fato.
Mais um teste rápido antes de iniciar, dentro do seu projeto local, digite no terminal o comando dep ssh:
Viu que bacana? O deployer identificou que foi configurado dois hosts e ele te deu a opção de escolher em qual host deseja conectar via SSH. Informei o host de homologação e ele realizou o login no servidor.
A mensagem de erro dizendo que o diretório current não existe é normal, pois ainda não realizamos o deploy e a estrutura de diretórios que a ferramenta de deploy cria, não existe no momento.
Chega de enrolação, bora fazer esse deploy. Se ainda continua logado no servidor, digite exit para sair e voltar para sua máquina. Dentro do diretório do seu projeto digite o comando dep deploy. Veja que não passamos nenhum parâmetro, nesse caso o deploy será realizado no host de homologação.
Agora precisamos configurar o arquivo .env, se tentar acessar o endereço IP na porta 81 irá receber um erro 500.
Logando no servidor através do comando dep ssh, dentro do diretório current de homologação (diretório atual quando se faz login usando o dep ssh), se abrirmos o arquivo .env verá que está em branco. Copie o conteúdo do arquivo .env.example para .env:
Agora abra o .env e adicione as informações de acesso ao Mysql que criamos no início do tutorial. Salve as alterações e saia do arquivo.
DB_USERNAME=deployer
DB_PASSWORD=senhaforteaqui
É necessário gerar a chave de segurança do artisan para que a aplicação funcione corretamente, execute os comandos:
Nesse momento sua aplicação deve estar funcionando, acesse seu endereço IP na porta 81 e verifique se a página inicial do Laravel irá aparecer. Se não deu certo, verifique o log do Laravel para identificar o problema.
Vamos continuar pois ainda não acabou. Agora que configuramos nosso arquivo .env com as informações de acesso ao Mysql, vamos executar o deploy novamente agora com a opção de executar a migrate. Lembra que comentamos a linha responsável em executar a migrate, vamos descomentar esse linha e aproveite para descomentar a linha da tarefa do npm_run, ficando assim:
// Descomente o if da tarefa npm_run
// Descomente o artisan migrate
Ou seja, após a tarefa symlink, será executado as migrations. Vamos executar o deploy novamente:
Veja que lindo que foi o resultado. Foi executada uma tarefa nova agora, a tarefa responsável em criar as migrations, veja a linha artisan:migrate no log acima.
Bom, agora se você acessar sua aplicação e realizar o cadastro de um usuário verá que funcionará lindamente.
Configuramos o deployer para que seja feito em dois ambientes, em homologação e produção. Ao executar o comando dep deploy é feito o deploy em homologação. Para que seja feito em produção é necessário informar um parâmetro a mais no comando, veja:
O prod na frente do comando vem do stage definido no arquivo deploy.php. Agora que você já sabe como fazer o deploy em homologação que tal fazer a mesma coisa para produção?
Execute os mesmos passos que você fez para homolog, crie um banco de dados para produção e após o primeiro deploy configure seu .env com os dados de acesso ao Mysql.
A implantação de uma ferramenta de deploy apesar de parecer simples, se torna um pouco complicado se o seu ambiente não está preparado ainda, por exemplo, as configurações essenciais do servidor como o Mysql, Nginx, PHP, etc...