Arquivo Anual: 2014

Usando o Git para Deployment de Websites

Há uns tempos atrás, depois de vários anos a usar SVN, e de uma breve passagem pelo Mercurial, decidi converter os meus repositórios de código para Git. Ao longo dos últimos meses tenho aprendido a usar este sistema cada vez melhor, muito com a ajuda do Google.

No meio das muitas pesquisas que efectuei, encontrei alguns artigos sobre a utilização do Git para efectuar o deployment de aplicações web. Decidi então investigar um pouco mais este assunto, e ver até que ponto podia tirar partido de um sistema do género. O resultado foi um sistema que me permite fazer o deployment de uma aplicação web através de um comando git push para um determinado repositório no servidor de produção. O Git do servidor encarrega-se de colocar as alterações enviadas online, num website de testes ou de produção, dependendo do branch em causa. A solução é bastante simples, e passa pela utilização de hooks, que são basicamente scripts executadas automaticamente em conjunto com outras acções do Git.

O primeiro passo para colocar o sistema a funcionar passa por criar um repositório Git no servidor remoto.  Neste artigo vamos chamar-lhe repo, e vamos colocá-lo em /var/git. Isto pode ser feito através dos comandos:

mkdir -p /var/git/repo
cd /var/git/repo/
git init --bare

(De referir que caso use a pasta /var/git irá precisar de permissões de administrador para executar os comandos.)

De seguida passamos à criação do hook. Neste caso concreto, vamos usar um post-receive hook, que é executado no servidor no final de uma acção push. Assim, para definir o hook criamos o ficheiro hooks/post-receive, onde colocamos uma script com as acções a executar depois de um push. Na primeira linha da script vamos colocar #!/bin/bash, para indicar quem vai executar a script. Na linha seguinte colocamos read oldrev newrev refname. O objectivo desta linha é permitir saber qual o branch que foi usado no push, de modo a permitir efectuar acções diferentes em função do branch, que ficará associado à variável $refname.

Agora passamos à parte de especificar as acções a realizar. Vamos assumir que existem dois branchs, o dev e o master, e que sempre que se fizer push do dev se pretende actualizar os ficheiros na pasta /var/www/dev/ e sempre que se fizer push do master se pretende actualizar os ficheiros na pasta /var/www/main/. Para tal, vamos usar o seguinte código:

case "$refname" in
	refs/heads/master)
		echo 'Deploying files to production website...'
		GIT_WORK_TREE=/var/www/main git checkout -f master
		echo 'Fixing file permissions...'
		# chmod ...
		echo 'Done.'
		;;
	refs/heads/dev)
		echo 'Deploying files to development website...'
		GIT_WORK_TREE=/var/www/dev git checkout -f dev
		echo 'Fixing file permissions...'
		# chmod ...
		echo 'Done.'
		;;
	*)
		echo "No deployment action (unknown refname: $refname)."
		;;
esac

O comando case trata de escolher a acção apropriada. Por exemplo, no caso do branch master, usamos o comando GIT_WORK_TREE=/var/www/main git checkout -f master para actualizar os ficheiros, indicando a pasta onde os mesmos são colocados através da variável GIT_WORK_TREE. Por vezes temos também que corrigir as permissões e/ou proprietários dos ficheiros, pelo que devem ser adicionados os comandos apropriados. Também podemos imprimir algumas mensagens de feedback, que serão mais tarde mostradas no cliente que está a fazer push.

Um pormenor a ter em conta é que o utilizador usado na operação de push terá que ter permissões para realizar as referidas operações (entre outras, precisará de permissões de escrita em /var/git/repo, /var/www/main e /var/www/dev).

Depois disto podemos então adicionar o repositório remoto do servidor de produção ao nosso repositório local através do comando git remote add <id> ssh://<utilizador>@<dominio>:/var/git/repo. E pronto, agora sempre que quisermos fazer deployment das actualizações feitas na nossa cópia local basta usar o comando git push <id> master, por exemplo.

Referências

  1. http://sebduggan.com/blog/deploy-your-website-changes-using-git/
  2. https://halfthetruth.de/2011/09/13/using-git-to-deploy-a-website/
  3. http://thekeesh.com/2012/01/lightweight-deployment-with-git/
  4. http://www.janosgyerik.com/deploying-new-releases-using-git-and-the-post-receive-hook/

Linux: Evolução?

A minha experiência com Linux começou há um pouco mais de 10 anos atrás.  Primeiro com a utilização do Red Hat nos PCs da universidade, e algum tempo depois em casa, usando o Fedora, que tinha acabado de ser lançado.

Lembro-me que na altura a instalação do Fedora era incrivelmente simples, apesar de todos os mitos existentes na época, quanto à dificuldade do Linux.  Na verdade, considero que a instalação do Linux era até bem mais simples do que a do Windows.  É claro que havia alguns problemas de compatibilidade com hardware, mas havia suporte razoável para praticamente tudo (quando substituí o Fedora pelo SuSE, penso que passei mesmo a ter suporte para tudo).

Depois de passagens por várias distribuições, acabei por assentar no Debian, pela sua estabilidade fora de série.  Desde 2007 a 2011, consegui manter um sistema praticamente sem qualquer falhas/crashes, e mais uma vez com todo o hardware a funcionar.

Mais recentemente, depois de trocar de desktop, a gráfica ainda não era suportada pelo kernel da última versão do Debian, pelo acabei por decidir experimentar o Ubuntu 12.04 LTS, uma versão já com mais de um ano na altura da instalação.  Esperava um nível de estabilidade semelhante ao Debian, mas enganei-me redondamente…

Logo nos primeiros dias, durante a instalação e configuração da máquina tive mais crashes que em todos os anos em que usei Debian juntos.  Depois, os problemas com o hardware também estão de volta.  Foram precisos vários dias para conseguir afinar o SO, em que tive que lidar com problemas de formatação de disco (alinhamento de sectores, que não estava a ser bem efectuado para o meu disco), problemas com o esquema de partições (GPT), problemas com o UEFI e gestor de arranque, etc.

Em cima disto tudo, temos ainda os ambientes gráficos.  Seja com o GNOME 3, o KDE, ou o Unity, a experiência de utilização pareceu-me bastante inferior à que obtinha com o GNOME 2, que disponibilizava um ambiente gráfico muito simples e fácil de usar.  A solução passou por perder uma horas a configurar um ambiente GNOME Classic (depois de experimentar o LXDE e o XFCE).

Moral da história: às vezes parece que o Linux em vez de evoluir, está a regredir.