Fazendo backup simples de arquivos para o Google Drive

Vinícius Campitelli
5 min readNov 26, 2019

--

Estou subindo um serviço novo do Curseduca e queria a solução mais rápida possível para fazer backup de arquivos para um servidor externo… e de graça!

Já usei várias soluções (pagas ou não), tanto um rsync básico quanto o Percona XtraBackup para o MySQL, mas a primeira opção exige um outro servidor (que eu gastaria para comprar ou usar alguma solução gratuita de terceiros) e a última precisa de um setup mínimo para funcionar — e me parecia um certo overkill, devido à simplicidade do serviço.

Como já temos uma conta no G Suite para nossos emails, acabei utilizando a biblioteca gdrive-org/gdrive para fazer upload para o Google Drive.

Como instalar a biblioteca

A página de releases do gdrive possui vários binários já prontos para Linux, BSD, OSX e até Windows! Basta baixar a versão correta para seu OS e a arquitetura de seu sistema.

Se quiser compilar manualmente, basta seguir as instruções do README.

Mova o binário para uma pasta dentro do PATH do seu sistema (ex: /usr/local/bin) e libere permissões de execução (ex: chmod +x /usr/local/bin/gdrive).

Como preparar sua conta no Google

Para garantir que o gdrive rode sem interação do usuário, você precisa criar uma Service Account no Google. Eu usei o tutorial Using OAuth 2.0 for Server to Server Applications para fazer isso, foi bem simples. No final do processo, você irá baixar um arquivo JSON com as credenciais de acesso. Salve-o no seu servidor, iremos usá-la em breve. Lembre-se de mantê-lo seguro, esse arquivo é quem dá acesso à sua Service Account!

Você precisará também ativar a API do Google Drive para essa conta. Basta seguir esse outro tutorial: Enable the Google Drive API (viu que eu basicamente fiquei seguindo os artigos do Google para fazer isso, né?).

Para facilitar a visualização do Google Drive pela interface, eu criei uma pasta chamada Backup e compartilhei com o email do usuário gerado no Service Account criado anteriormente (algo como: xxxxxx@projeto-data.iam.gserviceaccount.com).

Uso da biblioteca

Executando gdrive help você verá todas as opções da biblioteca (deixei apenas os dois comandos que usaremos: list e upload):

$ gdrive help
gdrive usage:
gdrive [global] list [options] List files
...
gdrive [global] upload [options] <path> Upload file or directory
...
gdrive help Print help
gdrive help <command> Print command help
gdrive help <command> <subcommand> Print subcommand help

Para saber mais sobre um comando, basta executar gdrive help <comando>, como por exemplo (novamente removi algumas linhas para facilitar a leitura):

$ gdrive help list
List files
gdrive [global] list [options]
global:
-c, --config <configDir> Application path, default: /path/to/home/.gdrive
...
--service-account <serviceAccount> Oauth service account filename, used for server to server communication without user interaction (filename path is relative to config dir)
options:
-m, --max <maxFiles> Max files to list, default: 30
-q, --query <query> Default query: “trashed = false and ‘me’ in owners”. See https://developers.google.com/drive/search-parameters
...

Fazendo um upload manual

Antes de automatizarmos, vamos testar o script rodando-o manualmente.

Primeiro, precisamos garantir a autenticação com a API: lembra do JSON que você baixou ao criar sua Service Account? Mova-o para a pasta . gdrive da home do seu usuário (/home/username, /root, etc) — esse caminho é explicitado no texto de ajuda do parâmetro -c de diversos comandos, como mostrado no gdrive help list acima.

Iremos utilizar o parâmetro --service-acount para informar o nome do arquivo JSON (apenas o nome, pois a biblioteca já irá procurar em ~/.gdrive). Executando o comando mais simples que temos:

$ gdrive --service-account arquivo-credenciais.json list
Id Name Type Size Created
xxxxxxxxxxx myfile.tar.gz bin 2.3 MB 2019-11-26 12:00:46
yyyyyyyyyyy myfolder dir 2019-11-26 12:00:07

PS: se você recebeu algum erro sobre a API do Google Drive, garanta que habilitou-a anteriormente ou espere um pouco para a propagação da permissão funcionar!

Agora vamos fazer um upload! O help nos diz:

$ gdrive help upload
Upload file or directory
gdrive [global] upload [options] <path>
global:
...
--service-account <serviceAccount> Oauth service account filename, used for server to server communication without user interaction (filename path is relative to config dir)
options:
-r, --recursive Upload directory recursively
-p, --parent <parent> Parent id, used to upload file to a specific directory, can be specified multiple times to give many parents
...
--delete Delete local file when upload is successful
...

Crie um arquivo qualquer e vamos testar:

$ touch teste.txt
$ gdrive --service-account arquivo-credenciais.json upload teste.txt
Uploading teste.txt
Uploaded xxxxxxxxxxx at /s, total

Feito! Agora iremos utilizar o parâmetro --parent para fazer o upload dentro da pasta que criamos anteriormente. Para isso, precisamos utilizar o ID da pasta que foi retornada ao executarmos o gdrive list anteriormente!

$ gdrive --service-account arquivo-credenciais.json upload --parent yyyyyyyyyyy teste.txt
Uploading teste.txt
Uploaded xxxxxxxxxxx at /s, total

Agora sim, vamos automatizar o processo!

Automatizando

Criei um shell script bem simples que cria um .tar.gz a partir de uma pasta e usa o mysqldump para fazer o dump de todas as bases do banco de dados — com cada base em um arquivo diferente — e depois novamente criando um .tar.gz desse diretório. Você poderia colocar tudo em um mesmo .tar.gz, mas decidi separar para facilitar eventuais processos de restauração.

https://gist.github.com/vcampitelli/1b2ecf2131193625e46243df2c04c5c9

Você precisará trocar algumas informações no script, como as variáveis JSON_CREDENTIALS_FILE e PARENT_FOLDER_ID nas linhas 5 e 6, respectivamente. Também precisará trocar o caminho que será compactado na linha 15 (ou apagar as linhas 13–16 caso não precise dessa funcionalidade).

Para evitar deixar credenciais de acesso ao MySQL hardcoded no script, você pode criar um arquivo .my.cnf ou informar o socket de conexão com o parâmetro -S nas linhas 22 e 25, por exemplo

Criei uma entrada no crontab (com o comando crontab -e) para executar o script somente à meia-noite:

# m h  dom mon dow   command
0 0 * * * sh /srv/backup.sh > /dev/null

Para quem não conhece a sintaxe do cron, existem alguns sites para facilitar a criação, como o crontab-generator.org e crontab.guru

Se sua base de dados for muito grande, aconselho o uso do mydumper, um utilitário que consegue fazer dumps em paralelo através de threads — já usei em projetos maiores e recomendo!

E pronto! Em menos de 10 minutos, consegui fazer toda a rotina de backup de um simples sistema 😃

O próximo passo que recomendo é encriptar os arquivos .tar.gz gerados (com, por exemplo, gpg) antes de enviar para o Google Drive!

--

--