GPT Researcher
Overview
GPT Researcher is an open-source autonomous research agent. You give it a topic or a question. It plans its own research questions, searches the web, reads and summarises what it finds across many sources, and writes a long-form report with inline citations and a reference list. Reports export as Markdown, PDF or Word, and you can keep asking follow-up questions against a finished report.
A single run aggregates and cross-checks many sources rather than answering from one page. That is what makes the output a research report rather than a search result.
GPT Researcher calls an AI provider. It does not host a model. That makes it cheap to run: no GPU and one small VM. You bring your own provider key, so you control which model you use and what it costs.
This SecureAnyCloud image runs GPT Researcher 3.5.1, installed from upstream source pinned to an exact commit. It is served by uvicorn behind nginx on port 80, with a private SearXNG instance for web search bound to the VM's loopback interface.
GPT Researcher upstream has no sign-in of any kind. SecureAnyCloud therefore locks the whole instance behind a credential that every VM generates for itself on first boot, so an instance is never left open to strangers.
What you get:
- GPT Researcher 3.5.1 (
assafelovic/gpt-researcher, Apache-2.0), installed from upstream source pinned to commit409b8b60b477d50f2f844bc9598d1bcb7b056eeeso the shipped version never drifts - A private SearXNG search engine on the VM, so web search works out of the box with no search API key at all
- nginx on
:80enforcing HTTP Basic authentication against a per-VM credential, with response buffering disabled so the agent's progress streams live - A fail-closed authentication gate: nginx refuses to start if the credential file is ever missing
- An unauthenticated
/healthzendpoint for load balancer and uptime checks - No AI provider key baked into the image. You add exactly one after launch.
docker.service,nginx.service,gpt-researcher-search.service,gpt-researcher.serviceandgpt-researcher-firstboot.serviceas enabled, active systemd units- 24/7 SecureAnyCloud support
How this image is secured
GPT Researcher upstream is designed for local, single-user use and ships no authentication whatsoever. Deployed as upstream ships it, a VM on a public IP with a working provider key would let anyone who finds it spend your AI credits. One report means many model calls plus many page fetches, so that is an expensive door to leave open. This image closes it in four ways:
- nginx requires a credential on every path except the static
/healthzprobe. The username is randomised per VM and the password is 24 random characters. Both are generated on the VM at first boot and written to a root-only file. There is no default, shared or documented credential at any point. - Port 80 stays shut until the credential exists.
nginx.servicecarries a condition on a marker file. First boot creates the file only after it has minted the credential and confirmed that an unauthenticated request is refused. A VM cannot serve a single request before it is locked down. - The gate fails closed, not open.
nginx.servicealso runs a pre-start assertion that re-checks the authentication directives and the credential file. If either is missing, nginx will not start at all rather than serve openly. Step 12 demonstrates this on your own VM. - The application does not start until it is configured.
gpt-researcher.servicecarries a condition on the per-VM environment file, which is absent from the image. The enabled unit does nothing until first boot writes the file.
Prerequisites
You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.
The recommended size is Standard_B2ms (2 vCPU / 8 GiB RAM). The idle stack is modest, but a running report fans out concurrent workers that fetch and parse HTML and PDF sources in parallel. The LangChain runtime also holds its models and embeddings in memory. 8 GiB gives that real headroom without a swap file. Choose Standard_B4ms for a busy shared instance or for deep research runs.
Configure the network security group to allow inbound 22/tcp from your management network and 80/tcp from wherever you will use GPT Researcher. The image serves plain HTTP on port 80. For anything reachable from the internet, terminate TLS in front of it and use a real hostname. You can use an Azure Application Gateway or Front Door, or your own certificate on the VM's nginx.
Nothing else needs opening. The application itself (8000) and SearXNG (8080) are both bound to the loopback interface and are unreachable from outside the VM.
You also need an API key from one AI provider. OpenAI is the default. Anthropic, Google Gemini, Azure OpenAI, Groq, Mistral, Cohere, Together, any LiteLLM target and a local Ollama endpoint also work. You do not need a search provider key, because this image runs its own search engine.
Step 1 - Deploy from the Azure Marketplace
In the Azure portal, choose Create a resource. Search for GPT Researcher on Ubuntu 24.04 LTS by SecureAnyCloud and select Create.
Pick your subscription, resource group and region, and set the size to Standard_B2ms. Choose SSH public key authentication with the username azureuser. Allow inbound ports 22 and 80.
Step 2 - Deploy from the Azure CLI
Accept the Marketplace terms, create the VM and open port 80:
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:gpt-researcher-ubuntu-24-04:default:latest
az vm create \
--resource-group my-gptr-rg \
--name my-gptr \
--image sac1647283583153:gpt-researcher-ubuntu-24-04:default:latest \
--size Standard_B2ms \
--storage-sku StandardSSD_LRS \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard
az vm open-port --resource-group my-gptr-rg --name my-gptr --port 80 --priority 1010Step 3 - Connect to your VM
Connect over SSH as azureuser:
ssh azureuser@<vm-ip>First boot generates this VM's credentials and locks the instance down before port 80 opens. It normally completes within a minute of the VM becoming reachable.
Step 4 - Confirm first boot completed and the services are running
Check that the first-boot service finished:
sudo systemctl is-active gpt-researcher-firstboot.serviceactiveThen check the four runtime services:
systemctl is-active docker.service nginx.service gpt-researcher-search.service gpt-researcher.serviceactive active active activeAll four report active. If gpt-researcher.service is not yet active, first boot is still running. Wait a few seconds and repeat.
To see what first boot did, read its log:
sudo journalctl -u gpt-researcher-firstboot.service --no-pager | tail -20The log shows the order that matters. First boot writes the per-VM search secret and web credential first. It then starts the application and confirms it is healthy. Only after that does it create the marker that lets nginx open port 80.
gpt-researcher-firstboot: Writing the per-VM SearXNG secret gpt-researcher-firstboot: Starting the private web search stack gpt-researcher-firstboot: VM address resolved to 10.0.0.13 gpt-researcher-firstboot: Minting the per-VM web credential into /etc/nginx/gpt-researcher.htpasswd gpt-researcher-firstboot: Writing /etc/gpt-researcher/gpt-researcher.env (NO provider API key - the customer supplies exactly one) gpt-researcher-firstboot: Starting gpt-researcher.service with the per-VM environment gpt-researcher-firstboot: GPT Researcher is serving on the host loopback gpt-researcher-firstboot: Creating the bootstrap-ready marker /var/lib/sac/data/gpt-researcher-bootstrap-ready (this is what un-gates nginx) gpt-researcher-firstboot: Starting nginx (:80 opens only now, already authenticated) gpt-researcher-firstboot: Proving this VM refuses an UNAUTHENTICATED request with exactly 401 gpt-researcher-firstboot: Proving a one character mutated password is refused with exactly 401 gpt-researcher-firstboot: Proving the per-VM credential reaches GPT Researcher with exactly 200 gpt-researcher-firstboot: First boot complete; GPT Researcher is serving behind an authenticated nginx with per-VM secrets.Step 5 - Confirm only port 80 is exposed
The application and the search engine must be reachable only from the VM itself. nginx is the single external surface. List the listening sockets:
sudo ss -lntp | grep -E ':(80|8000|8080)\s'LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=8169,fd=5),...) LISTEN 0 2048 127.0.0.1:8000 0.0.0.0:* users:(("uvicorn",pid=7997,fd=7)) LISTEN 0 4096 127.0.0.1:8080 0.0.0.0:* users:(("docker-proxy",pid=7053,fd=8)) LISTEN 0 511 [::]:80 [::]:* users:(("nginx",pid=8169,fd=6),...)Ports 8000 (GPT Researcher) and 8080 (SearXNG) are bound to 127.0.0.1 only. Port 80 is the only one bound to a routable address.
Step 6 - Retrieve your per-VM sign-in credential
Read the credentials file as root:
sudo cat /root/gpt-researcher-credentials.txtThe file is 0600 root:root. It contains the instance URL, the randomised username and the 24-character password generated for this VM. Store them in your password manager.
Step 7 - Confirm the instance refuses anonymous access
Run this check on every deployment. An unauthenticated request must be refused:
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1/401The health probe stays open so load balancers work without a credential:
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1/healthz200Your own credential is accepted. Replace the values in angle brackets with those from Step 6:
curl -s -o /dev/null -w '%{http_code}\n' -u '<GPTR_WEB_USERNAME>:<GPTR_WEB_PASSWORD>' http://127.0.0.1/200Step 8 - Add your AI provider key
No key ships in the image, and GPT Researcher cannot run any research until you add one.
In the environment file, uncomment the OPENAI_API_KEY= <set-at-first-boot> line and paste your own key. The same key covers both the language model and the embeddings that GPT Researcher uses to rank sources. Edit the file with sudo nano /etc/gpt-researcher/gpt-researcher.env, or make the change in one step:
sudo sed -i 's|^# OPENAI_API_KEY=.*|OPENAI_API_KEY=<your-token>|' /etc/gpt-researcher/gpt-researcher.env
sudo systemctl restart gpt-researcherThe file is 0600 root:root, so your key is readable only by root.
To use a provider other than OpenAI, also set the model selectors in the same file. The commented examples show the pattern for Anthropic. Every provider LangChain supports is available, and the selector format is provider:model-name.
Step 9 - Check web search, with no search API key
Upstream GPT Researcher defaults to the paid Tavily search API. This image instead runs a private SearXNG instance on the VM and pins RETRIEVER=searx. Web search therefore works with no second key and no external search subscription. Confirm that it returns live results:
curl -s 'http://127.0.0.1:8080/search?q=azure+virtual+machine&format=json' -o /tmp/searx.json head -c 300 /tmp/searx.json; echo{"query": "azure virtual machine", "results": [{"template": "default.html", "title": "Azure Virtual Machines", "content": "Create Linux and Windows virtual machines (VMs) in seconds and reduce costs. Build, deploy, and run your applications on resilient and scalable infrastructure.", "img_src": "",Your only running cost is your own AI provider usage.
Step 10 - Sign in to the web interface
Open http://<vm-public-ip>/ in a browser. The instance asks for the username and password from Step 6. This prompt is the appliance refusing anonymous access, and it stops a stranger from running reports on your provider account.
After you sign in, the GPT Researcher interface opens. It has a research box, a report type selector, a tone selector, and controls for the number of sources and results.
Step 11 - Run your first report
Enter a research question, choose a report type and select the research button. The agent streams its progress live: the questions it planned, the sources it is reading, and then the report as it is written. A standard research report typically takes two to five minutes, depending on the model and the breadth of the topic.
The progress panel shows the research context the agent assembled from the web, the running cost of the run, and the point at which it starts writing the report.
When the report finishes, you can copy it or download it as Markdown, PDF or Word.
Step 12 - Confirm the fail-closed gate
The authentication gate is enforced at start-up, not just configured. If the credential file is missing, nginx refuses to start rather than serve an open instance.
The commands below hide the credential file, prove that nginx will not start without it, and put everything back:
sudo systemctl stop nginx
sudo mv /etc/nginx/gpt-researcher.htpasswd /tmp/htpasswd.check
sudo systemctl start nginx 2>/dev/null && echo "UNEXPECTED: nginx started ungated" || echo "nginx REFUSED to start without a credential file"
sudo mv /tmp/htpasswd.check /etc/nginx/gpt-researcher.htpasswd
sudo chown root:www-data /etc/nginx/gpt-researcher.htpasswd
sudo chmod 0640 /etc/nginx/gpt-researcher.htpasswd
sudo systemctl reset-failed nginx
sudo systemctl start nginx
sudo systemctl is-active nginxnginx REFUSED to start without a credential file activeStep 13 - Confirm the shipped versions are the pinned ones
Read the provenance record:
sudo cat /opt/gpt-researcher/.sac-provenanceproduct.name=GPT Researcher product.version=3.5.1 product.upstream=https://github.com/assafelovic/gpt-researcher.git product.tag=v3.5.1 product.commit=409b8b60b477d50f2f844bc9598d1bcb7b056eee product.licence=Apache-2.0 product.licence.sha256=c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4 search.image=searxng/searxng@sha256:854f239d5c181db9c4282cd0ffc1737a61232dd6ad0ea964028b96df17d7758a search.image.tag_at_pin=2026.7.22-ef8f6470e search.licence=AGPL-3.0-or-later search.upstream=https://github.com/searxng/searxngThe record shows the exact upstream commit the application was built from, the sha256 of its Apache-2.0 licence file, and the immutable digest of the SearXNG image. The bundled component licences and their source locations are listed here:
cat /usr/share/doc/sac/THIRD-PARTY-NOTICESChanging the sign-in credential
To change the password for the existing user, run:
sudo htpasswd -bB /etc/nginx/gpt-researcher.htpasswd '<GPTR_WEB_USERNAME>' '<new-password>'
sudo systemctl reload nginxOmit the final argument to be prompted for the password instead of passing it on the command line.
To replace the user entirely, use htpasswd -cB with a new username. Keep exactly one entry in the file unless you want to share access.
Sharing the instance
This is a single-tenant appliance, so everyone who signs in shares one report library. Add a second htpasswd entry only if you want that.
Serving GPT Researcher on your own domain
Point a DNS record at the VM's public IP. Then either terminate TLS on an Azure Application Gateway or Front Door in front of the VM, or add your own certificate to nginx at /etc/nginx/sites-available/sac-gpt-researcher and open port 443.
Maintenance
To see where your data lives, list the data directory:
sudo ls -la /var/lib/gpt-researcherReports, uploaded documents and logs are all under that directory. Back it up if the report history matters to you.
unattended-upgrades applies security updates automatically. To check the services after a reboot, run:
systemctl is-active gpt-researcher gpt-researcher-search nginxTo view the application logs, run:
sudo journalctl -u gpt-researcher --no-pager | tail -20Support
Every SecureAnyCloud image includes 24/7 support. Contact sales@secureanycloud.com with your Azure subscription ID and the VM name.
Deploy on Azure
Launch GPT Researcher on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com