
- Você sempre esquece de upar um arquivo para o servidor de produção?
- Acha um saco ter que upar os arquivos um a um?
- Acha o FTP lento?
- Se sente inseguro tendo que compartilhar a senha do server com outros?
Então…
Seus problemas se acabaram-se
O rsync é uma ferramenta para sincronização de arquivos/pastas que se encaixa como uma luva para a tarefa de deploy (enviar os arquivos modificados para uma outra máquina).
Caso você esteja usando uma máquina Unix-like (Mac, Linux, BSD, …) você provavelmente já possui o rsync instalado. Caso esteja utilizando o Windows, você pode baixar um port do projeto para sua plataforma aqui.
Este post é o primeiro do Loop Infinito a ser upado com o rsync. Vamos então dar uma estudada em como o processo é feito por aqui para aprendermos um pouco mais sobre a ferramenta.
Ligando agora você recebe…
O rsync é uma ferramenta que roda no terminal. Nós apenas definimos a pasta/arquivo origem e a pasta/arquivo destino que deve ser sincronizado com a origem. Ele então verifica quais arquivos foram modificados entre a origem e o destino e envia apenas o delta (a diferença) entre as diferentes versões do mesmo arquivo, o que torna o processo bem mais rápido se comparado ao FTP.
O uso mais básico para o rsync seria o de deixarmos duas pastas na mesma máquina sincronizadas. Basta executarmos o rsync pela linha de comando, passando a pasta origem como primeiro argumento e a pasta destino como segundo argumento.
$ rsync ~/uma/pasta/origem/qualquer ~/outra/pasta/destino
Mas no nosso caso queremos sincronizar uma pasta em nossa máquina com uma outra em uma máquina remota (o servidor do nosso blog). Então o comando usado foi:
$ rsync -avz -e ssh ./site loopinfinito@bugsy.dreamhost.com:~/loopinfinito.com.br
Calma! Não se apavore (ainda).
O nosso comando de deploy segue o mesmo princípio do exemplo mais básico que demos logo acima: o de deixar duas pasta sincronizadas. A diferença aqui é que estamos deixando duas pastas sincronizadas em diferentes máquinas. Parece complicado, mas vamos quebrar o comando acima e entendê-lo por completo.
-a
archive mode. esta flag habilita o modo recursivo e preserva links simbólicos, permissões e timestamps-v
verbose. nos dá mais feedback sobre o que está acontecendo-z
habilita compressão de dados durante o envio-e ssh
especifica o shell remoto, no caso estamos usando SSH./site
pasta origemloopinfinito@bugsy.dreamhost.com:~/loopinfinito.com.br
destino que queremos deixar sincronizado com a origem
Vamos quebrar o último comando para entendermos como estamos nos conectando no servidor.
loopinfinito
nome de usuário na máquina que estamos nos conectandobugsy.dreamhost.com
endereço do server~/loopinfinito.com.br
pasta dentro do server que queremos deixar sincronizada com a pasta local
Com apenas este comando nós estamos:
- Atualizando o nosso server com todos os arquivos novos, sem a necessidade de escolher arquivos manualmente
- Conexão segura, já que estamos usando SSH
- Mais rápido que FTP, já que usamos apenas uma conexão e enviamos apenas o delta de cada arquivo
Perceberam também que não estamos utilizando senha para nos conectarmos? Isso porque com o SSH nós apenas upamos as nossas chaves públicas para o servidor. Para quem quisermos dar acesso ao server, basta colar a chave pública no arquivo ~/.ssh/authorized_keys
no servidor (no nosso caso específico) e a conexão para esta pessoa com esta chave é liberada. E para revogar o acesso também é muito fácil, é só retirar a chave pública do mesmo arquivo, sem a necessidade de mudar de senha e reenviar a senha para todas as pessoas do projeto.
E não é só isso
Seria um saco termos que sempre digitar esse comando gigante quando fossemos dar um deploy. Para isso nós criamos uma tarefa com o cake
, um sistema de build do CoffeeScript (nós amamos CoffeeScript) parecido com o rake (de Ruby) e make (de C).
É só criar um arquivo chamado Cakefile na raiz do projeto e por este trecho de código:
# módulos
{spawn, exec} = require('child_process')
# task 'deploy'
task 'deploy', 'Envia o diff do blog para o server', () ->
# configurações de deploy do rsync
# para poder dar o deploy com sucesso, é necessário que sua chave pública
# esteja no arquivo ~/.ssh/authorized_keys do servidor
user = "caiogondim"
remote_root = "~/tmp.caiogondim.com"
local_root = "site/"
# executa o deploy
rsync = spawn "rsync", [
"-avz"
"-e"
"ssh"
"#{__dirname}/#{local_root}"
"#{user}@bugsy.dreamhost.com:#{remote_root}"
]
# evento disparado quando a tarefa imprime algo no stdout
rsync.stdout.on 'data', (data) ->
console.log data.toString().trim()
# evento disparado caso ocorra um erro na tarefa
rsync.stderr.on 'data', (data) ->
console.log "Erro no deploy: #{data}"
# evento disparado quando a tarefa é terminada
rsync.on 'exit', (code) ->
# console.log "exit code #{code}"
Agora aquele nosso comando gigantesco para deploy está encapsulado em um muito mais simples e fácil de modificar. É só entrarmos na pasta do projeto e digitarmos o comando abaixo e BOOM, o deploy acontece como mágica.
# muito mais simples, hein? =)
$ cake deploy
Rápido quanto?
Aqui nós tentamos fazer ciência, e como cientistas nós sabemos que não se pode melhorar o que não se pode medir. Então vamos deixar a fé de lado e ver na prática o quanto o rsync é mais rápido.
Para simular diferentes velocidades em minha conexão com a internet utilizei o Network Link Conditioner para OS X (que será assunto para outro post).
Upando o site inteiro
Upando o site inteiro em diferentes conexões, obtivemos os seguintes números.
1 Mbps DSL
- FTP 165 segundos
- rsync 97 segundos
3G, average case
- FTP 193 segundos
- rsync 112 segundos
EDGE, average case
- FTP 350 segundos
- rsync 162 segundos
Um gráfico com os dados que obtive
Neste cenário o rsync foi bem mais rápido.
Adicionando 1 caractere em 10 arquivos diferentes
Neste teste eu adicionei um caractere ao final de 10 diferentes arquivos e os upei.
1 Mbps DSL
- FTP 10 segundos
- rsync 7 segundos
3G, average case
- FTP 20 segundos
- rsync 11 segundos
EDGE, average case
- FTP 29 segundos
- rsync 21 segundos
Em relação ao FTP eu apenas cronometrei o tempo gasto para upar os arquivos. Num cenário real nos ainda iríamos ter que escolher um a um os arquivos a serem enviados, o que resulta em mais tempo gasto. No caso do rsync, não precisamos escolher quais arquivos mandar. Ele mesmo verifica quais os arquivos que devem ser upados e faz todo o trabalho chato.
Então não há mais motivos para upar arquivos como se ainda vivéssemos na década de 80. Automatize seu processo de deploy com o rsync e nunca mais esqueça de enviar aquele arquivo novamente.