Como Programador WordPress, provavelmente passa muito tempo num cliente FTP (FileZilla). Isso é um erro. O que leva 15 minutos no FTP (ex: apagar uma pasta cache com 100.000 ficheiros), leva 2 segundos no terminal SSH.
Neste guia, vou mostrar um conjunto de comandos sem os quais os programadores sénior não conseguem imaginar o trabalho.
Antes dos dez comandos: entrar com chave, não com palavra-passe
Tudo o que se segue parte do princípio de que já está dentro do servidor, e a forma como lá chega decide se vai mesmo usar isto. Um pedido de palavra-passe em cada ligação é exatamente o atrito que o manda de volta para o cliente de FTP. Gere um par com ssh-keygen -t ed25519, envie a parte pública com ssh-copy-id user@servidor, e a autenticação passa a ser uma palavra. Muitos painéis de alojamento têm um campo próprio para colar a chave pública, e é aí que a maioria das tentativas falha: o conteúdo de id_ed25519.pub é uma única linha, e basta uma quebra de linha introduzida pelo editor para o servidor deixar de a reconhecer. Se o acesso continuar a pedir palavra-passe, ligue com ssh -v e leia as linhas que mencionam publickey, porque é aí que o cliente diz qual chave ofereceu e o que o servidor respondeu. Repare também na porta: há fornecedores que não usam a 22, e nesse caso a ligação nem chega ao ponto de discutir chaves.
1. Análise de disco: O que está a ocupar espaço?
Quando o alojamento grita “Quota Exceeded”, o FileZilla não ajuda. Use isto:
Du (disk usage)
## Mostrar pastas no diretório atual, ordenadas por tamanho
du -h --max-depth=1 | sort -hrNcdu (ncurses disk usage)
Se puder, execute ncdu. É um gestor interativo. Em servidores ruidosos, ver o que está a comer disco vale mais do que uma limpeza à cega. Use du quando precisa de um número para colar num pedido de suporte, e ncdu quando ainda não sabe o que procura. Os dois percorrem a árvore inteira e isso não é gratuito: numa pasta uploads grande ocupam o disco durante um minuto, e em alojamento partilhado isso aparece como páginas mais lentas enquanto correm. Aponte-os a uma subpasta em vez da raiz da conta se o site tiver visitas. Nenhum deles lhe diz o que pode apagar, e numa instalação WordPress o suspeito mais frequente nem sequer são imagens: são os ficheiros error_log que o servidor vai deixando pasta a pasta, cada um pequeno, todos juntos capazes de ocupar mais do que a biblioteca de media.
2. Logs: Debugging em tempo real
Em vez de descarregar o debug.log, abri-lo e procurar o erro… veja-o ao vivo!
Tail -f
## Seguir as últimas linhas do ficheiro em tempo real
tail -f wp-content/debug.logAgora atualizé a página no navegador, e os erros aparecerão no ecrã. Saia com Ctrl+C. Ler o log ao vivo faz sentido enquanto conseguir provocar o erro à ordem. Quando não consegue, a linha que interessa já passou, por isso comece antes com tail -n 200 wp-content/debug.log e leia para trás. Ao comparar horas, confirme o fuso do servidor com date, porque o carimbo do debug.log segue a configuração do PHP e não o relógio do seu portátil. É por causa dessa diferença que se passa meia hora a procurar um erro na altura errada do ficheiro. Duas armadilhas comuns: o ficheiro só existe quando WP_DEBUG_LOG está ativo no wp-config.php, portanto um terminal vazio costuma significar que o registo está desligado e não que o site está saudável, e nada roda esse ficheiro sozinho, pelo que um site que emite um aviso em cada pedido acaba por ser ele próprio o que enche a quota.
3. Pesquisar ficheiros: Onde está aquele código?!
À procura de onde add_image_size foi usado? Não descarregué o projeto todo.
Grep
## Pesquisar a frase "add_image_size" em todos os ficheiros PHP recursivamente
grep -r "add_image_size" .A forma completa serve para ler o código à volta do resultado, a versão com -l serve quando só quer saber que plugin é responsável por um comportamento. Num tema o custo é irrelevante, em wp-content/plugins já não é, porque a recursão entra em cada pasta vendor que encontrar. --include='*.php' e --exclude-dir=node_modules são os dois acrescentos que compensam de imediato. Confirme um resultado abrindo o ficheiro nessa linha em vez de confiar na contagem: o mesmo nome de função aparece no código do plugin, no bloco de documentação por cima dele e no ficheiro de tradução, e só um desses três sítios é a definição.
4. Permissões: Corrigir “403 forbidden”
Muitas vezes após migração, os ficheiros têm permissões erradas. Lembre-se da regra:
- Diretórios: 755
- Ficheiros: 644
Find + chmod
Não faça manualmente. Automatize:
## Definir 755 para todos os diretórios
find . -type d -exec chmod 755 {} \;
## Definir 644 para todos os ficheiros
find . -type f -exec chmod 644 {} \;Corra isto quando tem um sintoma, um 403 ou um carregamento que falha, e não como manutenção de rotina. Um chmod aplicado a tudo apaga todas as exceções deliberadas da instalação, e a mais importante é o wp-config.php: guarda as credenciais da base de dados e devia ficar em 640 ou mais restrito, não nos 644 que o ciclo acabou de lhe dar. O ciclo também só toca no que pertence ao seu utilizador, por isso num alojamento onde o servidor web corre noutra conta pode não corrigir nada e não dar erro nenhum. Verifique com ls -l wp-config.php e abrindo a página que estava a falhar, nunca repetindo o mesmo comando.
5. Backups: Arquivo rápido
Quer um backup rápido antes de atualizar? Não copie via FTP. Zipe no servidor.
Tar
## Criar ficheiro backup.tar.gz do diretório atual
tar -czf backup.tar.gz .Descompactar:
tar -xzf backup.tar.gzArquivar no servidor é o passo certo antes de atualizar um plugin, porque o ficheiro nunca atravessa a sua ligação. Não é uma estratégia de backup: o arquivo fica no mesmo disco que o site, logo sobrevive a uma atualização falhada mas não a uma avaria do disco. Acrescente --exclude='wp-content/cache' a menos que queira arquivar exatamente aquilo que vai apagar a seguir. E espreite lá dentro com tar -tzf backup.tar.gz | head antes de confiar nele, porque um arquivo cortado a meio por falta de espaço aparece na listagem como um ficheiro perfeitamente normal.
6. Base de dados (WP-CLI)
Se tiver WP-CLI no servidor, e deve ter, o phpMyAdmin deixa de fazer falta. Sem exportações que morrem por tempo limite no navegador, sem limite de upload na importação.
## Exportar a base de dados
wp db export backup.sql
## Importar a base de dados
wp db import backup.sql
## Limpar a base de dados (cuidado!)
wp db resetO dump é escrito no disco do servidor, não passa pela sua ligação. Numa loja WooCommerce com alguns anos de histórico, é a diferença entre uma exportação em segundos e um navegador que desiste a meio da tabela wp_postmeta. O WP-CLI corre como o seu utilizador de shell e não através do servidor web, por isso os limites de upload e o max_execution_time deixam de se aplicar. O que ele não pode ignorar é o site estar no ar: wp db import apaga e recria as tabelas enquanto alguém está a finalizar uma encomenda, logo a janela de manutenção faz parte do comando e não é um extra. O resultado confirma-se com um simples wp option get siteurl, que falha de imediato e de forma visível se a importação só entrou a meio.
7. Apagar ficheiros em massa
Apagar por FTP a pasta cache de um plugin com um milhão de ficheiros pequenos pode levar uma hora, porque o FTP confirma ficheiro a ficheiro.
Rm
## Apagar a pasta e tudo o que está lá dentro (sem volta atrás!)
rm -rf wp-content/cache/Duração: meio segundo. Não existe reciclagem. Não escreva o caminho de cabeça, complete-o com a tecla de tabulação, para que wp-content/cache/ não se transforme em wp-content/. É a ferramenta certa para uma pasta de cache e quase nunca a certa para outra coisa, porque não pergunta antes nem permite recuperar depois. O hábito que o salva é correr ls sobre exatamente o mesmo caminho primeiro e apagar só quando a listagem coincide com o que tinha em mente. Repare sobretudo no fim do caminho, porque um espaço a mais transforma um alvo em dois, e o segundo costuma ser a pasta acima. Num site com visitas o plugin reconstrói a cache no pedido seguinte, portanto o que paga é um carregamento lento e não indisponibilidade.
8. Sincronizar ficheiros entre máquinas
O FTP volta a enviar tudo de cada vez. O rsync compara primeiro os dois lados e envia apenas a diferença.
Rsync
## Primeiro em seco: mostrar o que seria copiado, sem alterar nada
rsync -avzn --exclude 'cache/' ./wp-content/uploads/ user@servidor:/var/www/exemplo.pt/wp-content/uploads/Quando a lista de ficheiros fizer sentido, retire o n de -avzn. Dois pormenores decidem o resultado. A barra no fim do caminho de origem significa “o conteúdo desta pasta”; sem ela fica com uploads/uploads. E --delete espelha também as remoções, ou seja, apaga no destino tudo o que já não existe localmente. Executado a partir de uma cópia local desatualizada, esse parâmetro limpa a biblioteca de media em vez de a sincronizar. O rsync também tem de estar instalado nas duas pontas, senão o comando falha logo no arranque.
9. Encaminhamento de portas: chegar à base de dados atrás da firewall
Os alojamentos geridos fecham o MySQL ao exterior. A porta 3306 só responde em localhost, o cliente de secretária fica em tempo limite e no painel sobra o phpMyAdmin. Não precisa de uma porta aberta, precisa de um túnel.
Ssh -L
## Ligar a porta local 3307 ao MySQL do servidor, sem abrir shell remota
ssh -N -L 3307:127.0.0.1:3306 user@servidorDeixe esse terminal aberto e aponte o TablePlus, o DBeaver ou o cliente mysql para 127.0.0.1:3307. O -N significa “nenhum comando remoto”, a sessão apenas encaminha. O mesmo truque chega a tudo o que só escuta localmente no servidor: Redis na 6379, uma aplicação de staging na 8080, um endpoint que nunca devia ser público. Escolha uma porta local que esteja mesmo livre, porque o ssh comunica que a associação falhou e mantém a sessão aberta à mesma. Parece um túnel a funcionar até a primeira consulta ficar pendurada.
10. Troca de domínio: ensaio em seco antes de escrever na base de dados
Depois de uma migração a base de dados continua com o domínio antigo, e boa parte dele está dentro de arrays PHP serializados, onde cada string guarda o seu próprio comprimento. Um UPDATE ... REPLACE simples troca o texto e deixa o comprimento errado, e a seguir os widgets, as opções do tema e os layouts do page builder aparecem vazios. O WP-CLI percebe a serialização e mostra o que tenciona mexer antes de mexer.
Wp search-replace --dry-run
## Contar o que mudaria, sem escrever nada
wp search-replace 'https://staging.exemplo.pt' 'https://exemplo.pt' --dry-run --all-tables-with-prefix --report-changed-onlyRecebe uma tabela com o número de ocorrências por coluna. Quando os números baterem certo com o que espera, repita o comando sem --dry-run. Acrescente --precise se o site tiver serialização aninhada, porque força o caminho mais lento pelo PHP em vez do atalho por SQL, e --recurse-objects quando estão envolvidos objetos serializados. Em qualquer dos casos faça primeiro wp db export: o search-replace não tem forma de desfazer.
Quando o alojamento só dá SFTP
Há planos partilhados que anunciam SSH e entregam SFTP, ou seja, transferência de ficheiros pelo mesmo protocolo sem qualquer shell do outro lado. Percebe-se no momento em que ssh user@host 'ls' responde exec request failed on channel 0. Nada neste guia que se execute no servidor sobrevive a isso: nem du, nem tar, nem WP-CLI, porque não existe processo onde possam correr. A camada de transferência continua a funcionar, por isso sftp e rsync por cima dela movem ficheiros melhor do que qualquer cliente com janela, e o trabalho sobre a base de dados regressa ao navegador, ao phpMyAdmin e a um plugin de cópias. Antes de aceitar a limitação, verifique se o fornecedor disponibiliza shell noutra porta ou se a ativa mediante pedido, porque em vários casos isto é uma definição e não uma fronteira do produto. Se de facto não existir naquele plano, tem um argumento concreto para orçamentar uma mudança, já que todos os fluxos de trabalho acima lhe estão fechados.
Resumo
O terminal SSH não morde. Permite trabalhar à velocidade do disco do servidor, não à velocidade da sua internet. Comece com ncdu e tail -f.






