Como instalar o FreshRSS em um VPS Ubuntu 24.04
Instale o FreshRSS 1.29.1 no Ubuntu 24.04 com Apache, PHP 8.3 e MariaDB. Configure o cron de atualização, o virtual host e a API do app móvel.
O que você está instalando
Um leitor RSS auto-hospedado é um leitor de feeds executado em um servidor que você controla. Assim, ninguém pode desligá-lo nem alterar o conteúdo exibido. Este guia instala o FreshRSS em um VPS com Ubuntu 24.04: Apache na frente, PHP no backend, MariaDB para armazenamento e um cron que busca novos artigos. RSS (really simple syndication) é o formato de arquivo que um site publica para que os softwares possam ler seus artigos. FreshRSS é a aplicação PHP que coleta esses arquivos, armazena os artigos e fornece uma interface web e uma API (application programming interface) usada por aplicativos de celular.
A instalação é simples: descompactar uma versão, criar um banco de dados, gravar um virtual host e executar um instalador de linha de comando. A maior parte do trabalho abaixo trata dos problemas que as pessoas costumam ter depois: o job de atualização, as barras codificadas para a API móvel e a propriedade dos arquivos.
FreshRSS 1.29.1 é a versão atual em julho de 2026 e requer PHP 8.1 ou mais recente. O Ubuntu 24.04 inclui o PHP 8.3, portanto os pacotes da distribuição são suficientes. Você não precisa de um repositório PHP de terceiros.
Comece com uma pilha LAMP funcional
O FreshRSS é uma aplicação PHP comum, portanto precisa da mesma base que qualquer outra. Se você ainda não configurou essa base, siga primeiro a configuração da pilha LAMP para Ubuntu 24.04 e volte aqui. Resumindo:
sudo apt update
sudo apt install -y apache2 mariadb-server php libapache2-mod-php
sudo systemctl enable --now apache2 mariadbsystemctl status apache2 deve informar active (running). Se o Apache não iniciar, a causa mais comum é outro processo já ocupando a porta 80, e sudo ss -ltnp | grep :80 identifica esse processo.
As extensões PHP necessárias ao FreshRSS
O FreshRSS considera libxml, cURL, JSON, PDO_MySQL, PCRE e ctype obrigatórias. Ele também requer mbstring, iconv, Zlib e ZipArchive, além de GMP em um sistema de 32 bits. No Ubuntu, elas são instaladas como pacotes da distribuição:
sudo apt install -y php-curl php-mbstring php-xml php-zip php-mysql php-intl php-gmp
sudo systemctl restart apache2Verifique o que o PHP realmente carregou com php -m. A ausência de uma extensão não impede o instalador de iniciar. Ela faz o instalador parar na tela de requisitos, com uma linha vermelha que identifica a extensão. Descobrir o problema somente nesse ponto é confuso, portanto confirme agora. Reiniciar o Apache é importante porque libapache2-mod-php mantém o PHP dentro do processo do Apache. Por isso, uma extensão recém-instalada não fica visível para o servidor web até que ele seja reiniciado.
Baixe a versão
Instale o FreshRSS fora da raiz da web padrão e aponte o Apache para ele. Manter o diretório da aplicação separado da raiz de documentos significa que somente a pasta pública ficará acessível por HTTP.
cd /tmp
curl -fsSLO https://github.com/FreshRSS/FreshRSS/archive/refs/tags/1.29.1.tar.gz
tar xzf 1.29.1.tar.gz
sudo mv FreshRSS-1.29.1 /srv/freshrssAgora, as permissões, que a documentação do FreshRSS define de forma rigorosa: o usuário do servidor web é proprietário da árvore, o grupo pode ler todos os arquivos e o grupo pode gravar em ./data/.
sudo chown -R www-data:www-data /srv/freshrss
sudo chmod -R g+r /srv/freshrss
sudo chmod -R g+w /srv/freshrss/dataSe você ignorar isso, o instalador falhará ao gravar a configuração, porque o PHP é executado como www-data e www-data não pode gravar em um diretório pertencente a root.
Criar o banco de dados
O FreshRSS oferece suporte a SQLite, MariaDB, MySQL e PostgreSQL. O SQLite não exige configuração e é adequado para uma pessoa com algumas centenas de feeds. O MariaDB é a melhor opção quando várias pessoas compartilham a instância, porque as gravações simultâneas do trabalho de atualização e da interface web deixam de disputar um único bloqueio de arquivo.
sudo mariadb -e "CREATE DATABASE freshrss CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
sudo mariadb -e "CREATE USER 'freshrss'@'localhost' IDENTIFIED BY 'ReplaceThisPassword';"
sudo mariadb -e "GRANT ALL PRIVILEGES ON freshrss.* TO 'freshrss'@'localhost';"
sudo mariadb -e "FLUSH PRIVILEGES;"Use utf8mb4, não utf8. Os feeds podem conter emoji e scripts não latinos, e a codificação antiga de três bytes utf8 trunca o título de um artigo no primeiro caractere de quatro bytes.
O host virtual do Apache
O diretório público é p/, não o nível superior da árvore. Todo o restante, incluindo o arquivo de configuração que contém a senha do banco de dados, fica acima da raiz de documentos, onde o Apache nunca o servirá.
<VirtualHost *:80>
ServerName rss.example.com
DocumentRoot /srv/freshrss/p/
<Directory /srv/freshrss/p>
AllowOverride AuthConfig FileInfo Indexes Limit
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/freshrss_error.log
CustomLog ${APACHE_LOG_DIR}/freshrss_access.log combined
AllowEncodedSlashes On
</VirtualHost>Salve isso como /etc/apache2/sites-available/freshrss.conf e habilite-o:
sudo a2enmod rewrite
sudo a2ensite freshrss
sudo a2dissite 000-default
sudo apache2ctl configtest
sudo systemctl reload apache2configtest deve exibir Syntax OK. AllowEncodedSlashes On parece opcional, mas não é: a Google Reader API envia identificadores de feeds que contêm %2F e, sem essa diretiva, o Apache os rejeita. Por isso, os aplicativos móveis não conseguem sincronizar, enquanto a interface web funciona perfeitamente.
Adicione HTTPS antes de fazer login
Você está prestes a digitar uma senha neste site, portanto obtenha um certificado primeiro. Aponte um registro A para o servidor, siga a configuração do Certbot para Apache no Ubuntu e execute sudo certbot --apache -d rss.example.com. O Certbot reescreve o virtual host da porta 443 e adiciona o redirecionamento. Confirme com curl -I https://rss.example.com/, que deve retornar um 200 ou redirecionar para a página de login.
Execute o instalador pela linha de comando
O FreshRSS tem um instalador no navegador, mas a versão da linha de comando pode ser repetida e registra exatamente as opções escolhidas.
sudo -u www-data php /srv/freshrss/cli/do-install.php \
--default-user admin --auth-type form --environment production \
--base-url https://rss.example.com --language en --api-enabled \
--db-type mysql --db-host localhost --db-user freshrss \
--db-password 'ReplaceThisPassword' --db-base freshrss
sudo -u www-data php /srv/freshrss/cli/create-user.php \
--user admin --password 'a-long-passphrase' --api-password 'a-different-passphrase'Execute ambos como www-data. Executá-los como root cria arquivos de configuração pertencentes a root, e a interface web não consegue salvar nenhuma configuração posteriormente. --environment production também é importante, porque a configuração de desenvolvimento exibe avisos do PHP na página.
Carregue https://rss.example.com/ e faça login como admin.
Por que os feeds não são atualizados automaticamente
Nada consulta seus feeds até que você configure isso. O FreshRSS é atualizado enquanto houver um navegador aberto nele. Isso significa que uma instância que você acessa duas vezes por dia mostra artigos com doze horas de atraso. A solução é o script fornecido pelo projeto para essa finalidade, app/actualize_script.php, executado pelo cron.
sudo crontab -u www-data -eAdicione uma linha:
*/20 * * * * php /srv/freshrss/app/actualize_script.php > /tmp/FreshRSS.log 2>&1Vinte minutos é o intervalo mínimo recomendado. O script se recusa a atualizar um feed individual com frequência maior que uma vez a cada vinte minutos. Um intervalo menor apenas consome CPU. Execute-o manualmente uma vez antes:
sudo -u www-data php /srv/freshrss/app/actualize_script.phpUma saída normal lista cada feed buscado e termina sem um erro do PHP. Se não imprimir nada, o usuário do cron está incorreto. Um erro de permissão em data/ significa que a etapa chmod -R g+w foi ignorada.
Adicione seus primeiros feeds
Use o botão de adição no canto superior esquerdo da interface, cole o endereço de um site, e o FreshRSS descobrirá o link do feed para você. A maioria dos sites ainda publica um, mesmo quando não o divulga, geralmente em /feed, /rss ou /atom.xml. As categorias são pastas, e mover um feed entre elas é uma operação de arrastar.
Se você está migrando de outro leitor, exporte um arquivo OPML nele e importe-o na página de gerenciamento de assinaturas. OPML (outline processor markup language) é o formato padrão para listas de feeds, e todo leitor que vale a pena usar oferece suporte a ele. Uma importação grande é lenta na primeira atualização porque cada feed é obtido uma vez. Portanto, aguarde a primeira execução do cron antes de avaliar a velocidade.
Leia no celular
O FreshRSS oferece suporte à Google Reader API, compatível com quase todos os aplicativos de RSS. Duas condições precisam ser atendidas. Nas configurações de autenticação, "Allow API access" precisa estar ativado; o flag --api-enabled acima já fez isso. No seu perfil, o campo de senha da API precisa conter um valor. Essa senha é separada intencionalmente da senha de login porque é mais fácil perder um celular.
Acesse https://rss.example.com/api/ e selecione "Check full server configuration". Uma configuração funcional retorna PASS. Uma falha nessa etapa quase sempre é causada pela ausência da linha AllowEncodedSlashes On. No aplicativo, informe o endereço do servidor como https://rss.example.com/api/greader.php, o nome de usuário como seu usuário do FreshRSS e a senha da API como senha.
A alternativa com Docker
Se você preferir não manter o PHP e o Apache manualmente, o projeto publica uma imagem oficial freshrss/freshrss, e um arquivo compose fornece a aplicação e o banco de dados juntos. A troca é a habitual: menos componentes no host, mais uma camada para depurar quando algo falhar, e ainda será necessário um proxy reverso para TLS (segurança da camada de transporte). Se essa opção for mais adequada, os conceitos básicos do Docker Compose para uma VPS explicam o formato do arquivo, e a linha do cron passa a ser docker exec --user www-data freshrss php ./app/actualize_script.php.
Backups e upgrades
Duas coisas preservam seu estado: o banco de dados e /srv/freshrss/data/. Gere um dump do primeiro com sudo mysqldump freshrss > freshrss.sql, copie o segundo e mantenha ambos em outro local que não seja este servidor. Sua lista de assinaturas também merece uma exportação OPML ocasional, pois esse arquivo recria sua configuração de leitura em qualquer software RSS.
Para fazer upgrade, descompacte uma versão mais recente sobre o mesmo diretório e execute novamente os comandos de propriedade. O FreshRSS aplica suas próprias migrações de banco de dados no próximo carregamento da página. Faça um backup primeiro, pois uma migração com falha em um banco de dados que você não consegue restaurar deixa o sistema irrecuperável. Um leitor é um serviço de baixo risco para executar e um bom primeiro candidato se você estiver analisando uma lista do que vale a pena hospedar por conta própria.
FAQ
Por que meus feeds só são atualizados quando abro o FreshRSS?
Porque não existe nenhum agendador até que você crie um. O FreshRSS atualiza os feeds enquanto há uma sessão do navegador aberta e não faz nada quando a aba é fechada. Adicione a linha do cron que chama app/actualize_script.php usando o usuário www-data. Depois, execute o script manualmente uma vez e leia a saída. O silêncio geralmente significa que o cron está executando o script com o usuário errado, portanto o PHP não consegue gravar em data/.
Meu aplicativo móvel não consegue se conectar, mas o site funciona. Por quê?
A Google Reader API coloca barras codificadas (%2F) nos caminhos das solicitações, e o Apache as rejeita por padrão. Adicione AllowEncodedSlashes On dentro do virtual host e recarregue o Apache. Confirme a correção abrindo https://rss.example.com/api/ e executando "Check full server configuration", que deve informar PASS. Verifique também se a senha da API está definida no seu perfil, pois ela é separada da senha de login.
Devo usar SQLite ou MariaDB?
Use SQLite para um único usuário, porque não há nada para instalar nem senha para gerenciar. Use MariaDB quando mais de uma pessoa ler na instância ou quando você ultrapassar algumas centenas de feeds, porque o job de atualização e a interface web gravam ao mesmo tempo, e um único bloqueio de arquivo se torna o limite. É possível migrar entre eles posteriormente por meio dos comandos de exportação e importação. Portanto, essa não é uma decisão permanente.
O instalador falha ao gravar a configuração. Qual é o problema?
O PHP é executado como www-data pelo Apache, e esse usuário não pode gravar em um diretório pertencente a root. Execute sudo chown -R www-data:www-data /srv/freshrss e sudo chmod -R g+w /srv/freshrss/data novamente e depois inicie o instalador outra vez. Se você já executou o instalador de linha de comando como root, exclua os arquivos que ele criou em data/ antes de tentar novamente, porque o problema real é a propriedade desses arquivos.
De quantos recursos de servidor um leitor RSS auto-hospedado precisa?
Muito poucos. Algumas centenas de feeds em um plano pequeno funcionam bem, porque a carga consiste em breves picos de solicitações HTTP a cada vinte minutos e o banco de dados permanece pequeno depois que os artigos antigos são removidos. O uso de disco cresce conforme o período de retenção. Portanto, defina uma política de remoção de artigos nas configurações de arquivamento em vez de manter tudo indefinidamente.