Come fare self-hosting di OpenSEO su Cloudflare
Guida completa, con i problemi reali che ho risolto — incluso un bug silenzioso su Google Search Console che sembrava un problema di token e non lo era.
Di Valerio Aloi · Pubblicato: 31 agosto 2026 · Aggiornato: 22 ottobre 2026
Aggiornamento del 15 ottobre 2026. OpenSEO è arrivato alla versione 0.1.13. Ho aggiunto le novità principali da settembre a oggi e una guida per aggiornare la tua installazione. Il bug di Search Console raccontato più sotto ora ha anche una correzione ufficiale.
I tool SEO seri costano cari. Semrush e Ahrefs partono da un centinaio di euro al mese e salgono in fretta se ti servono davvero rank tracking, keyword research e audit tecnici insieme. Se sei un freelancer che sta iniziando, quella cifra fissa ogni mese, prima ancora di aver fatturato qualcosa, è spesso il motivo per cui rinunci a tracciare i contenuti o fai keyword research a occhio.
Configurare OpenSEO su Cloudflare non è stato immediato. Alcune sezioni della documentazione ufficiale danno per scontate cose che, se non hai mai gestito un deploy su Cloudflare o un flusso OAuth con Google, non sono affatto ovvie: mi sono bloccato più di una volta su passaggi che con due righe di spiegazione in più si sarebbero risolti in cinque minuti invece che in ore. Scrivo questa guida soprattutto per chi si affaccia per la prima volta a strumenti del genere. Se hai già dimestichezza con Workers e OAuth, salta pure alle sezioni che ti servono.
Cos'è OpenSEO
OpenSEO è un tool SEO open source (codice su GitHub), pensato come alternativa a Semrush e Ahrefs. La differenza principale è nel modello di costo: non paghi un abbonamento mensile fisso, paghi solo i dati che consumi tramite una chiave API DataForSEO tua.

Le funzioni principali:
- Keyword research: trovi le parole chiave giuste per un argomento, con volumi di ricerca e difficoltà.
- Rank tracking: monitori le posizioni delle tue pagine su Google nel tempo.
- Competitor Insights: vedi cosa fanno i tuoi competitor, quali keyword li portano traffico, dove sono più forti di te.
- Backlinks: analizzi chi linka un sito e la qualità di quei link.
- Site Audits: scansioni un sito per errori tecnici SEO (link rotti, meta tag mancanti, problemi di indicizzazione).
- AI Visibility: controlli come e quanto un sito viene citato dai motori di ricerca AI e dai modelli linguistici, non solo da Google.
Il progetto è pensato anche per lavorare insieme agli agenti AI: espone un server MCP (il protocollo che permette a un assistente come Claude di usare direttamente i tuoi dati e le tue funzioni, senza passare dall'interfaccia web) e delle skill pronte, cioè procedure guidate che l'agente segue per portare a termine un compito SEO.
C'è un vantaggio meno ovvio nell'appoggiarsi a DataForSEO come fonte dati. Google ha iniziato a instradare i link dei risultati di ricerca attraverso redirect google.com/goto, che offuscano l'URL reale nella SERP proprio per rendere più difficile a scraper e tool di terze parti leggerla, una mossa che sembra puntare in particolare a servizi come SerpApi. DataForSEO ha già trovato il modo di bypassare questo redirect, quindi il rank tracking e l'analisi SERP di OpenSEO continuano a restituire URL reali invece di link opachi. Non c'è garanzia che resti così se Google stringe ulteriormente, ma oggi è un punto a favore di chi si appoggia a DataForSEO invece che ad altri fornitori di dati SERP.
C'è anche una versione hosted a 10€/mese se non vuoi gestire nulla tu, su openseo.so. Questa guida però parla dell'altra strada: prendere il codice e farlo girare sulla tua infrastruttura.
Uno sguardo rapido alla dashboard
Prima di entrare nel setup, ecco cosa significa concretamente ognuna delle funzioni elencate sopra, presa dalla mia istanza self-hosted (nome del progetto/dominio del cliente oscurato per riservatezza).








Le novità da settembre a ottobre 2026
Dalla pubblicazione di questa guida OpenSEO ha rilasciato sette nuove versioni, fino alla 0.1.13 del 14 ottobre 2026. Qui sotto trovi le aggiunte che contano di più per chi lo usa tutti i giorni; l'elenco completo, versione per versione, è nella pagina delle release su GitHub.
- AI Visibility (in beta). Ricerca e monitoraggio di come un brand compare nelle risposte di ChatGPT, Gemini e AI Overview di Google, e dalla 0.1.12 anche di Claude e Perplexity, che costano di più. Un controllo lanciato a mano restituisce le risposte in pochi minuti, e per ogni citazione vedi quali prompt l'hanno generata. Attenzione ai nomi di brand generici: possono produrre menzioni false.
- Monitoraggio del sito. Una dashboard dedicata al sito salvato nel progetto; salvare il sito avvia da solo un audit.
- Audit più affidabili. Rendering JavaScript per i siti costruiti lato client (React e simili). I blocchi anti-bot ora risultano come pagine bloccate invece che come contenuti mancanti, e i limiti temporanei di richieste non vengono più scambiati per blocchi. Gli orari degli audit sono nel tuo fuso orario, e c'è una firma del crawler per poter analizzare i siti Shopify.
- Keyword research. Volumi di ricerca per città e provincia, anche via MCP; le varianti quasi identiche restano fuori a meno di attivare «Group keywords»; risultati della SERP più profondi su richiesta.
- Rank tracking. Scegli giorno e ora dei controlli programmati, fissa le keyword più importanti in cima, apri direttamente il risultato su Google e mantieni le maiuscole con «Match case». Un controllo incompleto non sembra più una posizione persa.
- Report salvati. I report generati da Claude Code, Codex o altri client MCP si salvano dentro il progetto, si leggono nell'app e si esportano in PDF. Puoi creare modelli di report riutilizzabili per ogni progetto.
- Search Console, Analytics e MCP. Filtri per posizione e impressioni via MCP, ricerca delle proprietà Search Console e Analytics per nome, SERP da mobile nello strumento
get_serp_results. E messaggi chiari quando manca un permesso o l'API non è abilitata: proprio il problema raccontato nella sezione 6. Se non l'avevi ancora visto, dalla versione 0.1.6 c'è anche Google Analytics 4, con il traffico organico in dashboard. - Aspetto. Interfaccia rinnovata e modalità scura migliorata.
Io ho aggiornato la mia istanza il 15 ottobre: come farlo, con un backup prima, è spiegato più sotto in Come aggiornare OpenSEO.
Come scaricare OpenSEO
Il codice è su GitHub, repository every-app/open-seo. Lo clonerai nel passaggio 1 qui sotto. Se pensi di aggiornarlo spesso o di personalizzarlo, meglio partire da un tuo fork su GitHub e clonare quello, così hai un repository che controlli tu.
In entrambi i casi ti serve una chiave API DataForSEO, il servizio che fornisce i dati SEO veri e propri (volumi di ricerca, SERP, backlink). OpenSEO è l'interfaccia e la logica sopra quei dati, non la fonte dei dati. Questa guida dà per scontato che tu ne abbia già una: se non l'hai ancora creata, la guida ufficiale del progetto la copre in due minuti.
Due modi per fare self-hosting
Il self-hosting significa far girare il software sulla tua infrastruttura invece che pagare un servizio in abbonamento. OpenSEO supporta due percorsi, entrambi documentati nel repo:
- Docker, in locale. Gira sul tuo computer, nessuna esposizione su internet, autenticazione disattivata per design (
AUTH_MODE=local_noauth). È il punto di partenza più semplice se vuoi solo provarlo o usarlo da un unico dispositivo. - Cloudflare Workers, su internet. Un Worker è semplicemente un'applicazione che gira sui server di Cloudflare invece che sul tuo computer: resta raggiungibile da qualunque dispositivo, protetta da Cloudflare Access (il sistema di login che decide chi può entrare).
Io uso la strada Cloudflare, perché voglio avere OpenSEO a disposizione da telefono, da laptop, da qualunque posto io sia, non solo dal computer dove l'ho installato. È anche, va detto subito, la strada più complicata delle due: significa gestire un servizio esposto su internet, quindi autenticazione, secret, e un flusso OAuth per Google Search Console che ha più di un modo per rompersi in silenzio. Se vuoi solo iniziare a usarlo senza pensieri, parti da Docker.
Il resto di questa guida copre il percorso Cloudflare, passo per passo, incluso ogni punto dove mi sono bloccato.
Prerequisiti
- Node 22.6 o superiore e pnpm (
corepack enablelo attiva). - Un account Cloudflare con R2 abilitato. Attivare R2 richiede una carta di pagamento registrata, anche restando nel piano gratuito: se non hai mai usato R2, apri la sezione R2 nel dashboard Cloudflare una volta prima di procedere.
- Un account DataForSEO per la chiave API.
Quanto costa davvero
Il software è gratuito, ma l'uso ha costi: ecco quelli che ho registrato io a ottobre 2026 e quelli che trovi nei listini.
| Voce | Costo |
|---|---|
| OpenSEO self-hosted | gratuito (open source) |
| OpenSEO hosted su openseo.so | 10€ al mese |
| Cloudflare Workers, piano gratuito | 0€, ma al massimo 50 richieste in uscita per esecuzione |
| Cloudflare Workers, piano a pagamento | 5 dollari al mese, 10.000 richieste per esecuzione |
| Dati DataForSEO | a consumo, con ricarica minima di 50 dollari (listino) |
| Un controllo AI Visibility, 8 prompt su 4 motori | circa 0,42 dollari (la stima dello strumento prima di lanciarlo) |
| 80 risposte AI (20 prompt su 4 motori) con OpenSEO, 15 ottobre | 1,04 dollari, e solo 44 risposte arrivate: 36 sono andate in errore per i limiti del Worker |
| Le stesse 80 risposte chiamando DataForSEO direttamente | 0,36 dollari, 80 su 80 |
Cosa ne ho concluso: per la dashboard di tutti i giorni (Search Console, posizioni, audit) uso OpenSEO; per le raccolte grandi di risposte AI chiamo DataForSEO direttamente, che costa meno e non incontra i limiti del Worker. Come lavoro in quel caso lo racconto nella guida su Claude Code e DataForSEO.
1. Come clonare il repository
git clone https://github.com/every-app/open-seo.git
cd open-seo
corepack enable
pnpm installSe hai fatto un fork per averne il controllo, clona quello al posto dell'upstream.
2. Come fare login su Cloudflare
pnpm alchemy login # rispondi sì a "Customize OAuth scopes?" e abilita access:write
pnpm alchemy cloudflare bootstrap # deploya il Worker di stato di alchemy sul tuo accountOpenSEO usa Alchemy per il deploy: uno strumento che, con un comando solo, crea ("provisiona") tutte le risorse Cloudflare che servono (database, storage, Worker, login) al posto tuo, invece di doverle configurare una per una da dashboard.
Durante il login, Cloudflare ti chiede quali permessi ("scope") dare ad Alchemy sul tuo account: access:write è quello che gli serve per poter creare da solo l'applicazione Cloudflare Access più avanti. Se hai già fatto login in passato senza quello scope, un secondo login normale non te lo richiede di nuovo. Usa pnpm alchemy login --configure per forzarlo.
3. Come configurare .env.selfhost
cp .env.selfhost.example .env.selfhostApri il file e imposta almeno queste due variabili, obbligatorie:
- DATAFORSEO_API_KEY: non è la chiave grezza che vedi nella dashboard DataForSEO, ma le tue credenziali email:password codificate in base64. Su app.dataforseo.com/api-access, clicca "Send by email" e usa il valore etichettato "Base64" che ricevi, non quello in chiaro.
- ACCESS_ALLOWED_EMAILS: le email autorizzate a fare login, separate da virgola. È la lista di chi può entrare nel tuo OpenSEO.
4. Come fare il deploy
pnpm deploy:selfhost --yesQuesto comando fa tutto: crea il database D1, i namespace KV, il bucket R2, applica le migrazioni, deploya il Worker e crea l'applicazione Cloudflare Access che lo protegge, con accesso limitato esattamente a ACCESS_ALLOWED_EMAILS. Se il tuo account non ha ancora un team Zero Trust, ne crea uno.
Se preferisci gestire tu l'applicazione Access invece di farla creare in automatico, imposta TEAM_DOMAIN e POLICY_AUD in .env.selfhost prima del deploy: in quel caso il comando non tocca le risorse Access.
5. Come verificare che tutto funzioni
- Apri l'URL del Worker stampato alla fine del deploy.
- Fai login con Cloudflare Access.
- OpenSEO dovrebbe caricare dopo il login.
Se qualcosa non va, https://<il-tuo-worker>/api/health mostra lo stato di configurazione e del database, e pnpm exec wrangler tail mostra i log in tempo reale.
6. Come collegare Google Search Console
Prima di entrare nei passaggi, vale la pena capire come funziona Google Search Console dietro le quinte: non è OpenSEO a "avere" i tuoi dati, li legge in tempo reale dal tuo account Google tramite un'autorizzazione OAuth che tu concedi una volta sola. Il flusso completo è documentato passo per passo nella guida ufficiale a Search Console. Qui ti segnalo il passaggio che, se salti, non ti dà nessun errore subito, ma ti fa perdere tempo dopo.
Creare le credenziali OAuth
- Su console.cloud.google.com, crea o riusa un progetto.
- Abilita la Google Search Console API per quel progetto (API e servizi → Libreria, cerca "Google Search Console API", clicca Abilita). Questo è il primo passaggio della guida ufficiale, ed è quello più facile da trattare come una formalità e saltare mentalmente. Non lo è: creare le credenziali OAuth e abilitare l'API sono due impostazioni separate nello stesso progetto Google Cloud.
- Configura la schermata di consenso OAuth (External, e se resti in modalità Testing aggiungi il tuo account come test user).
- Crea un ID client OAuth di tipo "Applicazione web", con redirect URI:
https://<il-tuo-worker>.workers.dev/api/gsc/oauth/callback - Salva Client ID e Client secret.
Configurare il deploy
In .env.selfhost, decommenta e imposta:
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
BETTER_AUTH_SECRET=BETTER_AUTH_SECRET è una stringa casuale di almeno 32 caratteri, generabile con openssl rand -base64 32: serve solo per Search Console, per cifrare i token salvati. Rilancia pnpm deploy:selfhost --yes per applicare le nuove secret, poi vai su Integrations e collega l'account.
Cosa succede se salti il passaggio 2
Questo è il punto dove ho perso più tempo, e vale la pena raccontarlo perché il sintomo non ha niente a che vedere con la causa.
Se le credenziali OAuth sono corrette ma l'API non è abilitata, il login con Google funziona lo stesso: consenso completato, redirect corretto, token salvato nel database con scadenza a un'ora, refresh token presente. Tutto sembra andato a buon fine. Poi apri Integrations e vedi comunque "Connection expired. Reconnect to continue.", anche subito dopo aver ricollegato.
Il consenso OAuth (login, permessi, token) è un servizio Google separato dalla singola API. Solo quando OpenSEO prova a leggere i dati reali (sites.list), Google risponde con un 403, perché l'API non è attiva sul progetto. Il codice tratta quel 403 come "grant scaduto o revocato" e mostra il messaggio di reconnect, che è tecnicamente corretto ma ti manda a cercare nel posto sbagliato: sembra un problema di token, è un problema di configurazione del progetto Google Cloud.
Fix: console.cloud.google.com → API e servizi → Libreria → Google Search Console API → Abilita. Poi riprova il reconnect, senza bisogno di rigenerare nessuna credenziale.
Aggiornamento del 15 ottobre 2026: dalla versione 0.1.13 OpenSEO riconosce questo caso e, invece di «Connection expired», ti dice cosa correggere quando manca un permesso o l'API non è abilitata. Se usi una versione precedente, vale ancora tutto quello che c'è scritto sopra.
7. Come collegare i tool MCP (opzionale)
OpenSEO espone i suoi tool via MCP su /mcp, così puoi usarli direttamente da Claude, Claude Code o altri client MCP. Perché funzioni, l'applicazione Cloudflare Access che protegge il Worker deve avere il Managed OAuth attivo. Non lo è di default, nemmeno se l'hai creata in automatico col deploy.
- Zero Trust (one.dash.cloudflare.com) → Access controls → Applications.
- Apri l'app che protegge il tuo Worker, Edit.
- Additional settings → OAuth, attiva Managed OAuth.
- Nei redirect URI consentiti, aggiungi quelli dei client che userai: per CLI e desktop come Claude Code, i client locali che registrano
http://localhost:PORT/callback; per claude.ai, l'URL di callback che ti mostra la pagina di setup del connettore. - Salva.
Poi, da Claude Code:
claude mcp add --transport http --scope user openseo https://<il-tuo-worker>.workers.dev/mcpSe salti il passaggio Managed OAuth, il client riceve un errore di registrazione OAuth generico e non riesce a completare il collegamento.
Gestione ordinaria
Come aggiornare OpenSEO (aggiornato il 15 ottobre 2026)
OpenSEO esce con una nuova versione ogni una o due settimane. Prima di aggiornare leggi cosa cambia nelle note di rilascio su GitHub: è lì che trovi le eventuali nuove variabili da impostare.
1. Fai un backup. Due minuti, e se qualcosa va storto hai una copia dei tuoi progetti. Il nome del database lo trovi nel dashboard Cloudflare, alla voce D1:
pnpm exec wrangler d1 export <nome-db> --remote --output=openseo-backup-AAAA-MM-GG.sql2a. Se hai installato seguendo questa guida (Alchemy):
git pull # oppure, se hai un fork: git fetch upstream && git merge upstream/main
pnpm install
pnpm deploy:selfhost --yesIl deploy applica da solo le migrazioni del database. Le tue risorse Cloudflare restano identificate da .env.selfhost, non da valori dentro il repo, quindi non ci sono file di configurazione da salvare a parte.
2b. Se hai installato a mano con Wrangler, prima che esistesse il percorso Alchemy (è il caso della mia istanza): gli ID di database, KV e R2 stanno in wrangler.jsonc e wrangler.audit.jsonc, file del repo che hai modificato tu. Fanne una copia, mettili da parte mentre scarichi il codice nuovo e rimettili subito dopo:
cp wrangler.jsonc wrangler.jsonc.bak
git stash # mette da parte le tue modifiche ai file wrangler
git pull
git stash pop # le rimette sopra il codice nuovo
pnpm install
pnpm run deploy # migrazioni, Worker principale e Worker degli auditSe git stash pop segnala un conflitto sui file wrangler, tieni i tuoi ID e accetta il resto delle modifiche. pnpm run deploy pubblica anche un secondo Worker, open-seo-audit, che esegue gli audit dei siti: in wrangler.audit.jsonc servono gli stessi binding DB, KV e R2 di wrangler.jsonc, e la chiave DataForSEO va impostata una volta anche lì con pnpm exec wrangler secret put DATAFORSEO_API_KEY --name open-seo-audit. Se il tuo repo è nato dal vecchio pulsante «Deploy to Cloudflare», la procedura è diversa: segui la guida ufficiale per le installazioni precedenti.
3. Controlla che sia tutto a posto. Apri https://<il-tuo-worker>/api/health e prova una funzione che usi spesso. Alcune novità chiedono impostazioni in più:
- per analizzare siti Shopify con la firma del crawler servono
BETTER_AUTH_SECRETe, dalla 0.1.13,CRAWLER_ACCESS_SECRET(almeno 32 caratteri): in.env.selfhostcon Alchemy, come secret del Worker con Wrangler; - il rendering JavaScript negli audit richiede il piano Workers a pagamento;
- i suggerimenti di prompt dell'AI Visibility usano una chiave OpenRouter (
OPENROUTER_API_KEY).
Se aggiorni da una versione molto vecchia, la dashboard può mostrare una volta un avviso che propone di riunire in un unico spazio di lavoro i progetti di tutti gli utenti: è previsto.
Il piano gratuito di Cloudflare e gli audit
Una cosa che ho notato dopo l'aggiornamento: sul piano Workers gratuito, un audit del mio sito si è fermato a 37 pagine lette su 409, tutte le altre in errore. Il piano gratuito permette a un Worker al massimo 50 richieste in uscita per esecuzione (10.000 su quello a pagamento, da 5 dollari al mese), e 37 pagine più robots.txt e le sitemap fanno proprio circa 50. È la causa più probabile, anche se non l'ho ancora confermata nei log. Se i tuoi audit si fermano presto, guarda i log del Worker degli audit prima di cambiare altro: pnpm exec wrangler tail open-seo-selfhost-audit con Alchemy, open-seo-audit con un'installazione Wrangler manuale.
Come dare accesso ai colleghi
Aggiungi l'email in ACCESS_ALLOWED_EMAILS dentro .env.selfhost e rilancia pnpm deploy:selfhost --yes. Se modifichi la policy Access direttamente da dashboard invece che da qui, il prossimo deploy la sovrascrive: .env.selfhost resta l'unica fonte di verità.
Come disinstallare tutto
pnpm alchemy destroy --env-file .env.selfhost --stage selfhostCancella il Worker, il database D1, i namespace KV, il bucket R2 e l'applicazione Access, dati inclusi. Non c'è modo di tornare indietro dopo, quindi usalo solo se vuoi davvero ripartire da zero o abbandonare il progetto.
Come diagnosticare un problema senza modificare nulla
Un paio di comandi utili per capire cosa succede davvero, senza toccare codice o configurazione:
# Log in tempo reale del Worker, incluse le richieste che non generano eccezioni
pnpm exec wrangler tail
# Leggere una riga del database in produzione, in sola lettura
pnpm exec wrangler d1 execute <nome-db> --remote --command "SELECT * FROM account WHERE provider_id = 'google-search-console';"Il primo ti dice se una richiesta arriva davvero al Worker e se genera un'eccezione. Il secondo ti fa vedere lo stato reale dei dati salvati, invece di indovinare dal comportamento della UI.
Come farsi aiutare da Claude Code
Tutta la sezione precedente sulla Search Console, incluso il bug del 403 nascosto, l'ho diagnosticata insieme a Claude Code, dentro il repository di OpenSEO clonato in locale. Se non hai mai usato un agente AI per configurare qualcosa del genere, vale la pena provarci: a differenza di seguire una guida da solo, puoi fargli leggere il codice reale del progetto invece di fermarti a quello che dice la documentazione, e fargli eseguire comandi diagnostici al posto tuo.
Un punto di partenza concreto, dentro la cartella del repo clonato:
npx skills add every-app/open-seo --skill '*' --agent claude-codeInstalla le skill ufficiali del progetto (comprese quelle di setup e diagnostica) come comandi disponibili in Claude Code. Poi puoi semplicemente chiedere, in linguaggio naturale, cose come:
- "Aiutami a configurare .env.selfhost per il deploy su Cloudflare."
- "Ho questo errore durante il deploy, cosa significa?"
- "GSC dice 'Connection expired' anche dopo il reconnect, aiutami a capire perché."
Per la diagnostica, il pattern che ha funzionato con me è stato: fargli leggere il codice sorgente del punto che si rompe (non solo la documentazione, che può essere disallineata dal codice reale), controllare lo stato effettivo con comandi in sola lettura come wrangler tail o wrangler d1 execute --remote, e solo alla fine proporre una modifica. Se stai seguendo questa guida e qualcosa non torna, chiedi all'agente di verificare passo per passo prima di cambiare configurazione a caso: spesso la causa reale è due o tre passaggi più indietro di dove compare il sintomo.
FAQ self-hosting
Devo abilitare l’API di Google Search Console?
Sì, sempre, indipendentemente da come configuri le credenziali OAuth. È il passaggio 2 della sezione 6, ed è la causa più comune di connessioni che sembrano riuscite ma poi restano bloccate su "Connection expired". Dalla versione 0.1.13 è OpenSEO stesso a segnalartelo.
Come aggiorno OpenSEO senza perdere i dati?
Fai prima un backup del database con wrangler d1 export, poi scarica il codice nuovo e rifai il deploy: con Alchemy basta pnpm deploy:selfhost --yes, con un’installazione Wrangler manuale pnpm run deploy, dopo aver messo da parte i tuoi file wrangler. I passaggi completi sono nella sezione Gestione ordinaria.
Cloudflare Access è obbligatorio?
Sì, se scegli la strada Cloudflare. Il deploy lo crea automaticamente e limita l’accesso alle email in ACCESS_ALLOWED_EMAILS.
Posso evitare tutta questa complessità?
Sì: usa Docker in locale. Perdi la possibilità di accedere da qualunque dispositivo, ma salti autenticazione, secret e OAuth quasi del tutto.
Dove trovo altre risorse?
Il sito ufficiale è openseo.so, il codice e tutta la documentazione sono nel repository every-app/open-seo su GitHub.
Serve una mano con SEO o setup tecnico?
Un audit gratuito per capire da dove partire, senza impegno.