Quando o stack envolve HestiaCP, PHP codificado com ionCube e filesystem em WSL, os erros podem aparecer em cascata: aplicação acusando "arquivo corrompido", follow-up com 504 no frontend e logs pouco objetivos. Neste artigo, documento o runbook real que usei para estabilizar esse cenário sem retrabalho.
O objetivo não é apenas "fazer funcionar", mas garantir previsibilidade em produção: validação por SAPI correta, integridade de arquivo preservada e tempo de execução ajustado em todas as camadas.
1) Entendendo o falso positivo de "arquivo corrompido"
No contexto ionCube, "corrupted file" raramente significa dano físico no download. Na prática, os gatilhos mais frequentes foram:
- loader ativo no CLI e ausente no FPM;
- arquivo alterado por conversão de newline (CRLF);
- incompatibilidade entre versão do loader e versão do PHP do pool web;
- transferência em modo texto (FTP), alterando bytes esperados pelo loader.
Por isso, o diagnóstico começa por contexto de execução, não por suposição de arquivo quebrado.
2) Diagnóstico correto: CLI e FPM são ambientes diferentes
Testar só com php -v no terminal não fecha diagnóstico. O processo web usa PHP-FPM com php.ini e conf.d próprios.
2.1 Validar no CLI
php -v
php -m | grep -i ioncube || echo "ionCube nao carregado no CLI"
php --ini
2.2 Validar no FPM (via web)
Criei arquivo temporário de inspeção:
<?php
echo 'PHP_VERSION=' . PHP_VERSION . PHP_EOL;
echo 'SAPI=' . php_sapi_name() . PHP_EOL;
echo 'IONCUBE=' . (extension_loaded('ionCube Loader') ? 'yes' : 'no') . PHP_EOL;
phpinfo();
Se CLI = yes e FPM = no, o problema está no carregamento do módulo no pool web ativo, não no arquivo codificado.
3) Verificação do loader por versão PHP
No HestiaCP multi-PHP, cada versão tem caminho de módulo específico.
Checklist aplicado:
php -i | grep '^extension_dir'
ls -lah /usr/lib/php/ | head
ls -lah /usr/lib/php/*/ioncube_loader_lin_*.so 2>/dev/null
Depois validei o .ini correto para FPM:
grep -R "ioncube_loader" /etc/php/*/fpm/ -n
grep -R "ioncube_loader" /etc/php/*/cli/ -n
Se o domínio roda em PHP 8.1 e o loader apontar para 8.0/8.2, o erro de aplicação é esperado.
4) Armadilha crítica no WSL: CRLF em arquivo ionCube
Arquivos codificados ionCube não devem passar por transformação de newline. Quando editados em fluxo Windows (/mnt/c + editor com autocorreção), vi casos de CRLF line terminators, que inviabilizam execução.
4.1 Detectar formato de newline
file app/index.php
file caminho/arquivo_codificado.php
Se retornar CRLF line terminators, converti para LF:
dos2unix caminho/arquivo_codificado.php
Quando o problema era amplo no deploy:
find . -type f -name "*.php" -exec dos2unix {} \;
Em seguida, validei novamente:
file caminho/arquivo_codificado.php
5) 504 Gateway Timeout: diagnóstico por camada
O 504 não é erro do ionCube em si. Ele sinaliza que o NGINX (proxy) expirou espera de resposta do backend (PHP-FPM/Apache upstream).
5.1 Validar saúde de serviços
systemctl status nginx --no-pager
systemctl status php8.1-fpm --no-pager
journalctl -u php8.1-fpm -n 120 --no-pager
tail -n 120 /var/log/nginx/error.log
Se o PHP-FPM estiver saturado, o NGINX apenas reporta timeout.
5.2 Ajustar timeout no NGINX
No bloco de domínio (template/custom include), apliquei:
proxy_read_timeout 300;
fastcgi_read_timeout 300;
Depois:
nginx -t
systemctl reload nginx
5.3 Ajustar execução no PHP-FPM
No php.ini da versão ativa do pool:
max_execution_time = 300
max_input_time = 300
memory_limit = 512M
Opcionalmente, validar request_terminate_timeout no pool FPM para não matar o worker antes do prazo de aplicação.
Aplicação:
systemctl restart php8.1-fpm
6) Ajustes operacionais que eliminaram recorrência
- Mover código de execução para filesystem nativo Linux (
/home/usuario/...),
evitando operação direta em /mnt/c.
- Forçar transferência binária em FTP/SFTP quando houver artefato sensível.
- Desabilitar conversão automática de fim de linha no editor para diretórios de
deploy.
- Validar ionCube no contexto web sempre após troca de versão PHP.
- Executar smoke test com rota pesada para confirmar fim de 504.
7) Runbook de validação pós-correção
Usei esta sequência em homologação:
# 1) modulo no contexto correto
php -m | grep -i ioncube
# 2) serviços e logs
systemctl is-active nginx php8.1-fpm
tail -n 80 /var/log/nginx/error.log
# 3) sintaxe de configuracao
nginx -t
# 4) newline em arquivos sensiveis
find /home/usuario/web/app/public_html -type f -name "*.php" -exec file {} \; | grep -i crlf || echo "sem CRLF"
E no navegador:
- validar
info.phpcom ionCube = ativo em FPM; - abrir endpoint que antes gerava 504;
- confirmar latência dentro do timeout configurado.
8) Resultado técnico
Após os ajustes, os erros de "arquivo corrompido" cessaram e o 504 foi eliminado sob carga normal da aplicação. O principal ganho veio da separação estrita de diagnóstico por camada:
- integridade de arquivo (LF, transferência binária);
- carregamento de extensão por SAPI (CLI x FPM);
- capacidade/timeout no proxy e backend.
Esse padrão reduz MTTR e evita mudança reativa sem causa raiz.
Este post está licenciado sob CC BY-NC.
Comentários
Participe da discussão abaixo.
Comentários ainda não configurados. Adicione as opções do Cusdis em /assets/json/config/blog-comments-config.json.