Como instalar o FreshRSS em um VPS Ubuntu
Instale o FreshRSS 1.29.1 no Ubuntu 24.04 com Apache, PHP 8.3 e MariaDB, incluindo tarball, virtual host, cron de atualização e API para celular.
O que você vai criar
Um leitor RSS autoalojado é um leitor de feeds executado num servidor que você controla. Assim, ninguém pode desligá-lo nem alterar o conteúdo apresentado. Este guia instala o FreshRSS num VPS com Ubuntu 24.04: Apache na frente, PHP por trás, MariaDB para armazenamento e um cron job que obtém novos artigos. RSS (really simple syndication) é o formato de ficheiro que um site publica para que o software possa ler os seus artigos. FreshRSS é a aplicação PHP que recolhe esses ficheiros, guarda os artigos e disponibiliza uma interface Web, além de uma API (application programming interface) usada pelas aplicações móveis.
A instalação é simples: descompactar uma versão, criar uma base de dados, escrever um virtual host e executar um instalador na linha de comandos. A maior parte do trabalho abaixo trata dos problemas que surgem depois, sobretudo a tarefa de atualização, as barras codificadas para a API móvel e a propriedade dos ficheiros.
FreshRSS 1.29.1 é a versão atual em julho de 2026 e requer PHP 8.1 ou posterior. Ubuntu 24.04 fornece PHP 8.3, por isso os pacotes da distribuição são suficientes e não é necessário um repositório PHP de terceiros.
Comece por uma stack LAMP funcional
O FreshRSS é uma aplicação PHP comum, por isso precisa da mesma base que qualquer outra aplicação. Se ainda não preparou essa base, siga primeiro a configuração da stack LAMP para Ubuntu 24.04 e depois volte aqui. A versão resumida:
sudo apt update
sudo apt install -y apache2 mariadb-server php libapache2-mod-php
sudo systemctl enable --now apache2 mariadbsystemctl status apache2 deve apresentar active (running). Se o Apache não arrancar, a causa habitual é outro processo já estar a usar a porta 80; 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. Também requer mbstring, iconv, Zlib e ZipArchive, além de GMP num sistema de 32 bits. No Ubuntu, estas extensões 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 carregou efetivamente com php -m. Uma extensão em falta não impede o instalador de iniciar. O instalador só falha no ecrã de requisitos, com uma linha vermelha que identifica a extensão. Esse é um local confuso para descobrir o problema, por isso confirme agora. Reiniciar o Apache é importante porque libapache2-mod-php mantém o PHP dentro do processo do Apache. Por isso, uma extensão instalada recentemente não fica disponível para o servidor Web até este ser reiniciado.
Baixe a versão
Instale o FreshRSS fora da raiz web padrão e aponte o Apache para esse diretório. Manter o diretório da aplicação separado da raiz de documentos significa que apenas 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. A documentação do FreshRSS é rigorosa neste ponto: o utilizador do servidor web é o proprietário de toda a árvore, o grupo pode ler todos os ficheiros e o grupo pode escrever 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 ignorar este passo, o instalador falha ao escrever a configuração, porque o PHP é executado como www-data e www-data não pode escrever num diretório pertencente a root.
Criar a base de dados
O FreshRSS suporta SQLite, MariaDB, MySQL e PostgreSQL. O SQLite não requer configuração e é adequado para uma pessoa com algumas centenas de feeds. O MariaDB é a melhor opção quando várias pessoas partilham a instância, porque as escritas concorrentes do trabalho de atualização e da interface Web deixam de competir pelo bloqueio de um único ficheiro.
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 e 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 caráter de quatro bytes.
O host virtual do Apache
O diretório público é p/, não o nível superior da árvore. Tudo o resto, incluindo o ficheiro de configuração que contém a palavra-passe da base de dados, fica acima da raiz dos documentos, onde o Apache nunca o irá 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>Guarde esse conteúdo como /etc/apache2/sites-available/freshrss.conf e ative-o:
sudo a2enmod rewrite
sudo a2ensite freshrss
sudo a2dissite 000-default
sudo apache2ctl configtest
sudo systemctl reload apache2configtest deve apresentar Syntax OK. AllowEncodedSlashes On parece opcional, mas não é: a API do Google Reader envia identificadores de feeds que contêm %2F e, sem esta diretiva, o Apache rejeita-os. Por isso, as aplicações móveis não conseguem sincronizar, embora a interface web funcione corretamente.
Adicione HTTPS antes de iniciar sessão
Está prestes a introduzir uma palavra-passe neste site, por isso obtenha primeiro um certificado. Aponte um registo 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 devolver um 200 ou um redirecionamento para a página de início de sessão.
Execute o instalador na linha de comandos
O FreshRSS tem um instalador no navegador, mas a versão da linha de comandos pode ser repetida e deixa um registo exato das 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 ficheiros de configuração pertencentes a root, e a interface web deixa de conseguir guardar definições posteriormente. --environment production também é importante, porque a definição de desenvolvimento apresenta avisos do PHP na página.
Carregue https://rss.example.com/ e inicie sessão como admin.
Por que os feeds não são atualizados automaticamente
Nada consulta os seus feeds até que o configure. O FreshRSS atualiza os feeds enquanto há um navegador aberto na aplicação. Isso significa que uma instância que visita duas vezes por dia mostra artigos com até doze horas de atraso. A correção é o script que o projeto fornece para este fim, 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 recusa atualizar qualquer feed individual mais de uma vez a cada vinte minutos. Um intervalo menor apenas consome CPU. Execute-o manualmente uma vez primeiro:
sudo -u www-data php /srv/freshrss/app/actualize_script.phpUma saída normal identifica cada feed que foi obtido e termina sem um erro de PHP. Se não apresentar qualquer saída, o utilizador do cron está incorreto. Um erro de permissões em data/ significa que o passo chmod -R g+w foi ignorado.
Adicione os 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 deteta a ligação do feed. A maioria dos sites continua a publicar um, mesmo quando não o anuncia, normalmente em /feed, /rss ou /atom.xml. As categorias são pastas, e mover um feed entre elas é uma operação de arrastar.
Se vier de outro leitor, exporte um ficheiro OPML nesse leitor e importe-o na página de gestão das subscrições. OPML (outline processor markup language) é o formato padrão para listas de feeds, e todos os leitores que vale a pena deixar suportam-no. Uma importação grande é lenta na primeira atualização porque cada feed é obtido uma vez. Por isso, aguarde a primeira execução do cron antes de avaliar a velocidade.
Leia no seu telemóvel
O FreshRSS é compatível com a API do Google Reader, que é suportada por quase todas as aplicações de RSS. É necessário cumprir duas condições. Nas definições de autenticação, a opção "Permitir acesso à API" tem de estar ativada; o marcador --api-enabled acima já a ativou. No seu perfil, o campo da palavra-passe da API tem de conter um valor. Esta palavra-passe é deliberadamente separada da palavra-passe de início de sessão, porque é mais fácil perder um telemóvel.
Aceda a https://rss.example.com/api/ e selecione "Verificar a configuração completa do servidor". Uma configuração funcional devolve PASS. Uma falha nesta etapa deve-se quase sempre à ausência da linha AllowEncodedSlashes On. Na aplicação, indique o endereço do servidor como https://rss.example.com/api/greader.php, o seu utilizador do FreshRSS como nome de utilizador e a palavra-passe da API como palavra-passe.
A alternativa com Docker
Se preferir não manter o PHP e o Apache manualmente, o projeto disponibiliza uma imagem freshrss/freshrss oficial, e um ficheiro Compose fornece a aplicação e a respetiva base de dados em conjunto. A contrapartida é a habitual: menos componentes para gerir no host, mais uma camada para diagnosticar quando algo falha e, ainda assim, a necessidade de um reverse proxy para TLS (transport layer security). Se esta opção for mais adequada, os conceitos básicos do Docker Compose para um VPS explicam o formato do ficheiro, e a linha do cron passa a ser docker exec --user www-data freshrss php ./app/actualize_script.php.
Backups e atualizações
O seu estado depende de duas coisas: a base de dados e /srv/freshrss/data/. Faça o dump da primeira com sudo mysqldump freshrss > freshrss.sql, copie a segunda e mantenha ambas noutro local que não seja este servidor. A sua lista de subscrições também merece uma exportação ocasional em formato OPML, porque esse ficheiro permite reconstruir a sua configuração de leitura em qualquer software RSS.
Para atualizar, descompacte uma versão mais recente sobre o mesmo diretório e execute novamente os comandos de propriedade. O FreshRSS aplica as próprias migrações da base de dados no carregamento da página seguinte. Faça primeiro uma cópia de segurança, porque uma migração falhada numa base de dados que não pode restaurar deixa o sistema num estado irrecuperável. Um leitor RSS é um serviço de baixo risco e um bom primeiro candidato se estiver a avaliar uma lista do que vale a pena alojar autonomamente.
FAQ
Por que os meus feeds só são atualizados quando abro o FreshRSS?
Porque não existe nenhum agendador até criar um. O FreshRSS atualiza os feeds enquanto há uma sessão do navegador aberta e não faz nada quando o separador é fechado. Adicione a linha de cron que chama app/actualize_script.php com o utilizador www-data. Depois, execute o script manualmente uma vez e leia o resultado. A ausência de saída normalmente significa que o cron está a executá-lo com o utilizador errado, pelo que o PHP não consegue escrever em data/.
A minha aplicação móvel não consegue ligar-se, mas o site funciona. Porquê?
A Google Reader API coloca barras codificadas (%2F) nos caminhos dos pedidos, e o Apache rejeita-as por predefiniçã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 deverá indicar PASS. Verifique também se a palavra-passe da API está definida no seu perfil, pois é separada da palavra-passe de início de sessão.
Devo usar SQLite ou MariaDB?
SQLite para um único utilizador, porque não há nada para instalar nem nenhuma palavra-passe para gerir. Use MariaDB quando mais de uma pessoa ler na instância ou quando ultrapassar algumas centenas de feeds, porque o trabalho de atualização e a interface Web escrevem ao mesmo tempo, e um único bloqueio de ficheiro passa a ser o limite. Mais tarde, é possível mudar entre ambos através dos comandos de exportação e importação. Portanto, esta não é uma decisão permanente.
O instalador falha ao escrever a configuração. Qual é o problema?
O PHP é executado como www-data no Apache, e esse utilizador não consegue escrever num diretório pertencente a root. Execute novamente sudo chown -R www-data:www-data /srv/freshrss e sudo chmod -R g+w /srv/freshrss/data. Depois, inicie novamente o instalador. Se já executou o instalador de linha de comandos como root, elimine os ficheiros que este criou em data/ antes de tentar novamente, porque o proprietário desses ficheiros é o problema efetivo.
De que recursos de servidor precisa um leitor RSS alojado localmente?
Muito poucos. Algumas centenas de feeds num plano pequeno funcionam sem problemas, porque a carga consiste em breves picos de pedidos HTTP a cada vinte minutos e a base de dados mantém-se pequena quando os artigos antigos são eliminados. O espaço em disco cresce com o período de retenção. Por isso, defina uma política de eliminação de artigos nas definições de arquivo em vez de guardar tudo para sempre.