Migração de Nextcloud de Ubuntu para CentOS Stream

Após a reconfiguração do Apache e PHP-FPM para hospedar múltiplos sites, uma das coisas que eu quis fazer foi migrar minha instância do Nextcloud do Ubuntu 24.04 para o CentOS Stream 10.

Para organizar, eu pensei em algo similar ao que fiz para o WordPress:

  • /var/www/exemplo.com/nextcloud – pasta do Nextcloud
  • /var/www/exemplo.com/data – pasta de dados do Nextcloud

Foi criado um disco virtual separado para o Nextcloud, criada a partição com cfdisk e formatada como XFS – sistema de arquivos padrão na linhagem de servidores RHEL/CentOS/Fedora. Então, os arquivos foram transferidos para o disco, que depois será montado em /var/www/exemplo.com:

# rsync -av /var/www/nextcloud /mnt/nextcloud
# rsync -av /var/nextcloud-data /mnt/data

Então, foi feito o dump do banco de dados:

# sudo -u postgres pg_dump nextcloud_db > nextcloud.sql
# mv nextcloud.sql /mnt

Montado o disco no CentOS, é necessário instalar os pacotes faltantes:

# dnf install php-pecl-zip php-pgsql postgresql-server

Um módulo adicional (em relação à instalação do Ubuntu) necessário para execução de alguns scripts é o php-process:

# dnf install php-process

Sem esse módulo, a tentativa de execução do cron.php dá o seguinte erro:

“The posix extensions are required – see https://www.php.net/manual/en/book.posix.php“.

Outros módulos do PHP já haviam sido instalados por causa do WordPress. Em uma instalação limpa:

# dnf install php-common php-xml php-gd php-mbstring php-pecl-zip php-pgsql php-process postgresql-server

Então, começando a configuração do banco de dados:

# postgresql-setup --initdb
# systemctl enable --now postgresql
# sudo -u postgres psql

Dentro do banco de dados:

postgres=# CREATE ROLE nextcloud_user WITH PASSWORD 'umaSenhaCriativa';
postgres=# CREATE DATABASE nextcloud_db WITH OWNER nextcloud_user TEMPLATE template0 ENCODING 'UTF8';

Então, podemos importar o dump do banco de dados da instalação antiga:

# sudo -u postgres psql nextcloud_db < /var/www/exemplo.com/nextcloud.sql

O PostgreSQL tem um arquivo com as configurações de autenticação. Para descobrir onde está esse arquivo:

# sudo -u postgres psql -c "SHOW hba_file;"

No caso do CentOS Stream: /var/lib/pgsql/data/pg_hba.conf

Curiosidade: HBA significa “host-based authentication”.

Então, podemos configurá-lo. Isso pode ser necessário porque, como você vai ver, a coluna de método de autenticação está toda como peer.

Isso significa que ele faz um mapeamento entre o nome do usuário do sistema operacional para o usuário existente no banco de dados, de forma que ambos precisam ter o mesmo nome e o servidor SQL não exige uma senha – por isso o psql é executado com a opção “-u postgres” no sudo.

Para o tipo de conexão local – isso é, através do socket unix – isso não é problema. Mas o Nextcloud, no momento do setup, explicitamente solicita endereço, porta e senha para a configuração do banco de dados – ou seja, a conexão ao servidor é através de TCP em vez de socket unix.

No arquivo de configuração, o tipo de conexão TCP é representado por host, enquanto que a conexão por socket unix é representada por local.

Para configurar o banco de dados para utilizar autenticação por senha em conexões TCP, basta substituir peer por scram-sha-256 nas linhas em que o tipo de conexão é host.

O motivo de eu estar aprofundando um pouco mais na questão do método de autenticação no servidor de banco de dados é devido a um problema que se apresentou no final de tudo:

Após configurar o pool dedicado do PHP-FPM e o site para o Apache, a página do Nextcloud estava retornando erro 500. Em algum momento eu lembro que fui testar os scripts cron.php e “occ upgrade” do Nextcloud e lembro que eles apresentavam uma exceção ao tentar conecta no banco de dados. Alterei a senha, porque imaginei que pudesse ser algum problema em como caracteres especiais foram interpretados, sem sucesso.

O problema era devido a uma boolean do SELinux: http_can_network_connect_db estava desativada. Isso pôde ser verificado com:

$ getsebool http_can_network_connect_db

Como a conexão é feita através de TCP no localhost na porta 5432, o SELinux identificava essa tentativa de conexão e bloqueava. O servidor passou a responder apropriadamente quando a conexão a bancos de dados foi permitida com:

# setsebool http_can_network_connect_db on

No entanto, eu não queria afrouxar as regras do SELinux e busquei uma alternativa. Encontrei em fóruns do Nextcloud que era possível conectá-lo ao banco de dados através do socket unix.

O socket unix é um ponto de comunicação entre processos que aparece representado por um arquivo na árvore de diretórios do sistema operacional.

Já que estaremos utilizando esse tipo de conexão, podemos seguir com o método padrão de autenticação tipo peer e dispensar o uso de senha para conexão ao banco de dados.

Para que isso funcione, é necessário:

  • Fazer com que pool do PHP-FPM seja executado por um usuário de mesmo nome que o usuário usado para acessar o banco de dados – ajustando também o proprietário dos arquivos do Nextcloud.
  • Ajustar o arquivo de configuração do Nextcloud.

Criando o usuário no sistema operacional e ajustando as permissões do Nextcloud:

# useradd -s /usr/sbin/nologin nextcloud_user
# chown -hR nextcloud_user:nextcloud_user /var/www/exemplo.com/{nextcloud,data}

Ajustando também o contexto no SELinux para esses arquivos:

# semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/exemplo.com/nextcloud(/.*)?"
# semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/exemplo.com/data(/.*)?"
# restorecon -Rv /var/www/exemplo.com

Para ajustar as configurações do Nextcloud, deve-se ajustar os parâmetros dbhost e… só. A linhas da senha, porta de conexão e até mesmo o usuário do banco de dados podem ser deletadas ou comentadas com //.

O dbhost deve ser a pasta em que o socket unix se encontra, e isso pode ser descoberto com:

# sudo -u postgres psql -c "SHOW unix_socket_directories;"

No arquivo de configuração do Nextcloud fica.

'dbhost' => '/var/run/postgresql',

Vale lembrar de ajustar também o caminho da pasta de dados:

'datadirectory' => '/var/www/exemplo.com/data',

A configuração do pool do PHP-FPM fica:

; /etc/php-fpm.d/exemplo.com.conf

[exemplo.com]
user = nextcloud_user
group = nextcloud_user

listen = /run/php-fpm/nextcloud.sock
listen.acl_users = apache,nginx
listen.allowed_clients = 127.0.0.1

pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35

slowlog = /var/log/php-fpm/exemplo.com/nextcloud-slow.log

php_admin_value[error_log] = /var/log/php-fpm/exemplo.com/nextcloud-error.log
php_admin_flag[log_errors] = on
php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/session
php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache

Criando a pasta de log do PHP-FPM:

# mkdir -m 700 /var/log/php-fpm/exemplo.com
# chown nextcloud_user:nextcloud_user /var/log/php-fpm/exemplo.com

A configuração do Apache:

# /etc/httpd/conf.d/exemplo.com.conf

<VirtualHost *:80>
    ServerName exemplo.com

    DocumentRoot /var/www/exemplo.com/nextcloud

    <Directory /var/www/exemplo.com/nextcloud>
        AllowOverride All
        Require all granted
    </Directory>

    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php-fpm/nextcloud.sock|fcgi://localhost/"
    </FilesMatch>

    ErrorLog /var/log/httpd/exemplo.com_error.log
    CustomLog /var/log/httpd/exemplo.com_access.log combined
</VirtualHost>

A permissão do SELinux para processos com rótulo httpd se conectarem a bancos de dados através da rede pode então ser desativada e tudo deve continuar funcionando:

# setsebool httpd_can_network_connect_db off

Mas então, outro problema apareceu ao tentar fazer login. Ao inserir o usuário e a senha e clicar no botão de login, a página apenas recarregava.

Nos logs do Nextcloud, em /var/www/exemplo.com/data/nextcloud.log, a seguinte linha apareceu:

{"reqId":"aoYPLBNDXYPyR-ZrzrzodwAAAE8","level":2,"time":"2026-08-19T20:16:44+00:00","remoteAddr":"177.192.15.123","user":"--","app":"PHP","method":"GET","url":"/index.php/apps/files/preview-service-worker.js","scriptName":"/index.php","message":"session_start(): Failed to read session data: files (path: /var/lib/php/session) at /var/www/exemplo.com/nextcloud/lib/private/Session/Internal.php#214","userAgent":"Mozilla/5.0 (X11; Linux x86_64; rv:153.0) Gecko/20100101 Firefox/153.0","version":"34.0.3.2","data":{"app":"PHP"}}

Atenção para a parte “Failed to read session data: files (path: /var/lib/php/session)”.

Esse caminho é configurado no pool do PHP-FPM como onde as sessões devem ser armazenadas. O problema era que o usuário do pool, nextcloud_user, não tem acesso a essa pasta. Então, novas pastas foram criadas com as permissões adequadas, atualizando o arquivo de configuração do pool com:

php_value[session.save_path] = /var/lib/php/exemplo.com/session
php_value[soap.wsdl_cache_dir] = /var/lib/php/exemplo.com/wsdlcache

Diretórios também foram criados separadamente para o WordPress e a configuração do pool foi ajustada, apesar de não ter tido nenhum problema ainda.

Por fim, foi feito um ajuste de memória que um script PHP pode consumir. O mínimo recomendado é 512 MB. Isso pode ser ajustado no arquivo /etc/php.ini, no parâmetro memory_limit.

Outros ajustes menores a serem feitos podem ser verificados no painel de administração do Nextcloud.

P.S. – Atenção a um detalhe especial na situação muito específica que eu acabei criando: se por algum acaso o Nextcloud for usado com o PHP-FPM com um usuário e depois for necessário fazer a mudança de proprietário dos arquivos das pastas do Nextcloud porque o usuário do PHP-FPM mudou para combinar com o nome do usuário do banco de dados e autenticar no método peer, atente-se para o fato de que o Nextcloud cria uma pasta temporária em /tmp e é necessário ajustar o proprietário dela também, caso contrário alguns scripts PHP falham.

Eu não sei porque alguém faria esse caminho com todas as informações que tem agora, mas foi o caminho que eu, sem essas informações, fiz e me custou cerca de 40 minutos para descobrir e quase me custou o frango que eu esqueci no forno enquanto eu não conseguia largar desse problema. Mas é isso, mais uma presepada concluída com sucesso.