Skip to main content

Command Palette

Search for a command to run...

Deploy de aplicações PHP e MySQL com Git e Github Actions

Published
6 min read
Deploy de aplicações PHP e MySQL com Git e Github Actions
P

Eu sou um programador apaixonado por aprender e ensinar. Nos últimos 16 anos tenho focado minhas atenções ao desenvolvimento web Fullstack, mas sou bastante entusiasta das plataformas mobile.

Pronto, agora que já aprendemos como Criar um Droplet na DigitalOcean e como Configurar a pilha LAMP (Linux, Apache, MySQL e PHP), vamos agora realizar o Deploy de nossa aplicação. Para esse exemplo vamos usar o Freddy Gestor. O Freddy Gestor é uma aplicação simples de exemplo construída por mim, utilizando diversas bibliotecas PHP populares, com o intuito de apresentar como construir uma aplicação PHP moderna sem precisar de um framework de mercado.

Criando um Fork e Clonando o projeto

A primeira coisa que precisamos é criar um FORK do projeto e cloná-lo para a nossa máquina local. Para clonar navegue até um diretório de sua escolhe e execute o comando:

git clone git@github.com:PHPauloReis/freddy-gestor.git

Importante!!! No comando acima, “PHPauloReis” é o meu usuário no GitHub. Como você criou um Fork do projeto para a sua conta, lembre-se de alterar “PHPauloReis” para o seu usuário do GitHub.

Analisando os arquivos

Uma vez que você tenha clonado o projeto, abra-o em seu editor preferido. Você percebera a existência de um arquivo no caminho: “.github/workflows/deploy.yml“. Esse ponto (“.”), no início do nome github, não é um erro, é proposital e faz parte do nome do diretório.

O conteúdo desse arquivo é:

name: "Deploy para DigitalOcean"
on:
  push:
    branches:
      - main
jobs:
  build_deploy:
    runs-on: ubuntu-latest

    steps:
      - name: "Baixar o código"
        uses: actions/checkout@v4

      - name: "Copiar arquivos para a Digital Ocean"
        uses: appleboy/scp-action@v0.1.7
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          source: "."
          target: "/var/www/freddy"

      - name: "Build da aplicação"
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /var/www/freddy
            composer install --no-dev --no-progress -a
            chown -R www-data:www-data .

As linhas que chamo a atenção nesse arquivo são:

on:
  push:
    branches:
      - main

Isso indica que essa action (tarefa no github actions) será executada toda vez que rolar um push para a branch main.

- name: "Copiar arquivos para a Digital Ocean"
  uses: appleboy/scp-action@v0.1.7
  with:
    host: ${{ secrets.HOST }}
    username: ${{ secrets.USERNAME }}
    key: ${{ secrets.SSH_PRIVATE_KEY }}
    source: "."
    target: "/var/www/freddy"

No Linux existe um comando chamado scp (secure copy). Esse comando permite que você copie de maneira segura, arquivos e diretórios de um computador para outro por meio do protocolo SSH.

No exemplo acima, o “appleboy/scp-action@v0.1.7” é uma action do github actions que executa uma copia usando o comando scp de maneira automatizada. Basicamente você precisa informar o host, o nome do usuário, sua chave privada (note que aqui não estamos falando da chave pública que configuramos no tutorial: Como criar uma máquina Virtual (Droplet) na DigitalOcean?), diretório a partir do qual a copia será feita, nesse caso o “.” indica o diretório atual e o diretório alvo no servidor, nesse caso "/var/www/freddy".

Perceba que, no bloco acima, existem algumas “variáveis”. Isso é proposital. A ideia aqui é que você entenda que o nome do host, o usuário e a chave privada dão poderes a qualquer pessoa que possua esses dados para acessar, deletar, modificar etc. qualquer informação no servidor.

Logo, esses dados são sensíveis e não devem ser expostos no código, muito menos em um repositório do GitHub, mesmo que seja um repositório privado.

Daqui a pouco, ainda nesse tutorial, vamos ver como usar essas variáveis, por hora apenas entenda que elas existem e são importantes para segurança.

Um pouco mais abaixo temos esse outro trecho

- name: "Build da aplicação"
  uses: appleboy/ssh-action@v1.0.3
  with:
    host: ${{ secrets.HOST }}
    username: ${{ secrets.USERNAME }}
    key: ${{ secrets.SSH_PRIVATE_KEY }}
    script: |
      cd /var/www/freddy
      composer install --no-dev --no-progress -a
      chown -R www-data:www-data public/uploads storage

Aqui temos “appleboy/ssh-action@v1.0.3”, uma outra action do Github Actions. Essa por sua vez se encarrega de acessar o nosso servidor, usando ssh, e executa alguns comandos pré-definidos.

cd /var/www/freddy
Acessa o diretório onde a nossa aplicação foi instalada

composer install --no-dev --no-progress -a
Executa a instalação das dependência usando o composer

  • O parâmetro --no-dev Indica ao composer para não instalar as dependências de desenvolvimento.

  • O parâmetro -a é um atalho para --optimize-autoloader, ele:

    • Gera um autoloader otimizado

    • Melhora a performance da aplicação em produção

    • Reduz tempo de carregamento das classes

  • chown -R www-data:www-data public/uploads storage Transfere para o usuário e grupo www-data a propriedade dos diretórios public/uploads e storage, bem como todos os seus arquivos e subdiretórios.

Configurando variáveis de ambiente no Github

Agora que já entendemos o conteúdo do arquivo “.github/workflows/deploy.yml“ vamos obter a chave privada de nossa máquina para enviar para o Github.

No terminal do seu computador execute o comando:

cat ~/.ssh/id_ed25519

A saída gerada por esse comando será similar a:

-----BEGIN PGP PUBLIC KEY BLOCK-----
nCTRaDdRWBYJKwYBBAHaRw8BAQdA+ZCUXsxC8OxAw+ky6NIhf2xu/nwEXn64LigZ
+5JgFcy0FW5qZyA8bmpnQGVkMjU1MTkucHViTirABBMWCgA7FiEEjnU9tiCIddCF
rTyv7VgRDe9T4iQFAmg3UVgFAwMFCwkIBwICIgIGFQoJCAsCBBYCAwECHgcCF4AA
CgkQ7VgRDe9T4iQw5QD/f8vLc7DmJHAVFU/OKOy7TqcyhlXoGaCCPCyktSi2v4QA
/RrUsqiJt9Kg/e6zFEG+dHTQe13M2x9EG+LdS385pQYJuDgEaDdRWBIKKwYBBAGX
VQEFAQEHQCkrr5tV9nW7RxjyFtYONqNC1rDuEnY2nbenAqlxpA4nAwEIB4h4BBgW
CgAgFiEEjnU9tiCIddCFrTyv7VgRDe9T4iQFAmg3UVgCGwwACgkQ7VgRDe9T4iSA
UgEAt2FjAhv4hq6W8/AjV4TZpSsS8KzdB/2rXg9FCpOH2PQBAK7g7TYj2UV4H5UX
BEARZX3bYK6DZJT28Kxx8zYm/BQP=1NdS
-----END PGP PUBLIC KEY BLOCK-----

Acesse o repositório que você “forkou” (em sua conta) e nele clique “Settings” (no menu superior). Uma nova página será aberta, nela clique no menu lateral esquerdo, na opção: “Secrets and variables“ e depois em “Actions

A seguinte tela será exibida:

Mantenha selecionada a aba “Secrets” e clique em “New repository secret

Observação!!!

  • Repository secrets: Valem para todo o repositório

  • Environment secrets: Associados a um environment específico (ex: staging, production)

Como não teremos vários servidores de homologação, teste, etc… vamos pegar a opção mais genérica.

Cadastre o seu HOST (Lembre-se que aqui é o IP do seu Droplet)

Cadastre o seu USERNAME: root

Cadastre sua SSH_PRIVATE_KEY: Chave privada obtida no terminal

No final você terá isso:

Prontinho. Para testarmos, vamos realizar um novo push para o nosso repositório. Nesse exemplo vou mudar um arquivo aleatório. Abra o arquivo .env.example e informe a senha DATABASE_PASSWORD=secret (Lembrando que isso é só um teste). Faça um commit e um push.

git add .
git commit -m "Troca a senha do banco de dados"
git push

Acesse o repositório do seu projeto no Github e clique Actions (no menu superior), você verá algo como:

Quando o JOB for concluído, esse ícone amarelo ficará verde.

Vamos agora acessar novamente o nosso Droplet via SSH e executar o comando:

ls /var/www/

Perceba que a resposta será algo como:

freddy  html

O que comprova que nossa aplicação foi copiada corretamente para o nosso Droplet 😊

Configurando um Virtual Host

Crie um novo arquivo de configuração com o nome freddy.conf.

sudo nano /etc/apache2/sites-available/freddy.conf

O conteúdo desse arquivo deve ser:

<VirtualHost *:80>
    ServerName 159.89.159.105
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/freddy/public

    <Directory /var/www/freddy/public>
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Após a alteração, tecle: CONTROL + O e na sequência pressione Enter, para salvar as alterações. E logo após tecle: CONTROL + X para sair do nano.

Execute o comando abaixo para habilitar o seu novo Virtual Host:

sudo a2ensite freddy

Para evitar conflitos, vamos desativar o nosso site default:

sudo a2dissite 000-default

Também para evitar problemas, vamos verificar a integridade e a sintaxe do nosso arquivo de configuração:

sudo apache2ctl configtest

E por fim vamos reiniciar o nosso Apache:

sudo systemctl reload apache2

Agora precisamos configurar o acesso ao banco de dados.

No diretório raiz de nossa aplicação temos um arquivo chamado .env.example, vamos criar um novo arquivo chamado .env, usando esse arquivo como base:

cp /var/www/freddy/.env.example /var/www/freddy/.env

Importando o banco de dados

Note que no diretório raiz do nosso projeto tem um arquivo chamado freddy.sql, vamos importá-lo para o nosso MySQL:

mysql -u seu_usuario_do_mysql -p < /var/www/freddy/freddy.sql

O comando acima solicitará a senha do seu usuário, informe-a e tecle Enter. Lembre-se que por segurança o Ubuntu não exibe a senha, nem asteriscos, nem nada do tipo.

Por fim, ative o mod_rewrite no Apache:

sudo a2enmod rewrite
sudo systemctl reload apache2

E tente acessar a aplicação no IP do seu Droplet, a saída deve ser:

O usuário e senha são:

  • Usuário: admin@freddy.com

  • Senha: password

More from this blog

Blog do Acampamento Dev - Cursos, Dicas e Artigos sobre programação

49 posts

A Área do Código é um repositório de conhecimento sobre desenvolvimento de softwares e TI em geral. Aqui você encontrará curso, artigos, dicas e muito mais sobre programação.