Why Self-Hosted Bookmarking Makes Sense
Cloud bookmarking services come with a quiet catch: your saved links live on someone else’s server, subject to pricing changes, shutdowns, or privacy policies that evolve without much notice. Pinboard, Raindrop.io, and similar tools have loyal followings, but the history of bookmarking services is littered with shutdowns and feature stripping. Hoarder – a self-hosted, open-source bookmarking server – puts that data back under your control, running on your own hardware or a VPS you manage.
Hoarder is built for people who save a lot and want to do something useful with it later. It supports automatic link previews, full-text search, AI-powered tagging using a local or remote language model, and a clean web UI paired with browser extensions and a mobile app. Setup takes under 30 minutes with Docker, and once it’s running, it behaves like a polished commercial product. This guide walks through the full installation process on a Linux server.

What You Need Before Starting
Hoarder runs entirely in Docker, so the prerequisites are minimal. You need a Linux server – a VPS, home server, or even a Raspberry Pi 4 with at least 2GB of RAM – with Docker and Docker Compose installed. A domain name pointed at the server is optional but strongly recommended if you plan to access Hoarder from outside your local network. Port 3000 is the default, and you’ll expose that through a reverse proxy like Nginx or Caddy if you’re going public-facing. Make sure your firewall allows traffic on whichever port you decide to use.
You’ll also want to decide upfront whether you’re using AI tagging. Hoarder integrates with OpenAI’s API or a local Ollama instance to auto-tag bookmarks on save. Neither is required – Hoarder works perfectly well with manual tags – but if you want automatic categorization, have your OpenAI API key ready or have Ollama installed and running before you start. The rest of the configuration is handled through a single .env file.
Installing Hoarder with Docker Compose
Start by creating a directory for the project and pulling the official Docker Compose file. Run mkdir hoarder && cd hoarder, then create a docker-compose.yml file. Hoarder’s official documentation provides the full compose spec, which includes three services: the main web app, a MeiliSearch container for full-text search, and a Chrome-based service that handles link screenshots and metadata extraction. Copy that compose file directly rather than writing it from scratch – the service dependencies and health checks are already configured correctly.
Next, create your .env file in the same directory. The minimum required variables are HOARDER_VERSION (set to release for the latest stable build), NEXTAUTH_SECRET, and MEILI_MASTER_KEY. Both secret values should be randomly generated strings – run openssl rand -base64 36 twice and paste the outputs in. Set NEXTAUTH_URL to the full URL you’ll use to access Hoarder, including the protocol: for example, https://bookmarks.yourdomain.com or http://192.168.1.100:3000 for local-only access. Without a correct NEXTAUTH_URL, authentication will fail silently.
If you’re adding AI tagging at this stage, add OPENAI_API_KEY to the .env file and set OPENAI_BASE_URL if you’re routing through a local Ollama instance instead of OpenAI directly. For Ollama, the base URL typically looks like http://host-ip:11434/v1, and you’ll set the model name with OPENAI_MODEL. Llama 3 and Mistral both work reasonably well for tagging tasks, though response speed depends on your hardware. A GPU-equipped machine will process tags nearly instantly; CPU-only inference on a budget VPS will lag noticeably on longer articles.
With the compose file and .env in place, run docker compose up -d. Docker will pull all three images – expect a few minutes on the first run. Once the containers are up, check logs with docker compose logs -f web to confirm the app started cleanly. Navigate to your configured URL and you’ll be greeted by the Hoarder registration page. The first account you create becomes the admin account. There is no separate admin panel setup required.

Configuring a Reverse Proxy
Running Hoarder on port 3000 without TLS is fine for local network use, but if you’re exposing it to the internet, a reverse proxy with HTTPS is non-negotiable. Caddy is the fastest path – it handles certificate provisioning automatically via Let’s Encrypt. Create a Caddyfile with a single block: your domain name as the site address, and reverse_proxy localhost:3000 as the directive. Run Caddy and it provisions and renews the certificate with no additional configuration.
Nginx requires slightly more setup. Create a server block that listens on port 443 with SSL, points your certificate paths at the files Certbot generated, and proxies traffic to http://localhost:3000. Include proxy_set_header Host $host, proxy_set_header X-Real-IP $remote_addr, and proxy_set_header X-Forwarded-Proto https in the location block. That last header matters – without it, Hoarder may generate redirect URLs with the wrong protocol. After reloading Nginx, re-check the app to confirm login and bookmark saving both work correctly over HTTPS.
Browser Extensions, Mobile App, and Daily Use
Hoarder ships a browser extension for Chrome and Firefox that adds a toolbar button for one-click saving. After installing it, open the extension settings and point it at your server URL with your credentials. From that point on, saving a page takes a single click – no copying URLs, no switching tabs. The extension also supports saving with a note attached, which gets stored alongside the link and becomes searchable through MeiliSearch.
The mobile app is available for both iOS and Android and connects the same way – server URL, email, and password. It supports share-sheet integration, meaning you can send any link from Safari, Chrome, or any other app directly to Hoarder without opening the app first. That share-sheet workflow is where the self-hosted setup starts to feel genuinely useful rather than just technically interesting. Saved links show up in the web UI within seconds, with screenshots and metadata already populated by the headless Chrome service running in the background.
Full-text search works across the extracted page content, not just titles and URLs. MeiliSearch indexes each page after Hoarder crawls it, so searching for a term you remember reading – even if you can’t recall the article title – returns the right result. Bookmarks can be organized into lists, tagged manually or automatically, and filtered by domain. If you save dozens of links a week, the combination of AI tagging and full-text search means you can actually find things again, which is the part most bookmarking habits break down on.

One area worth watching: the headless Chrome container is the heaviest component in the stack, and on low-memory servers it will occasionally crash under load or fail to generate screenshots for certain pages. Restarting the container with docker compose restart chrome resolves it, but if you’re running on a 1GB VPS, you may want to disable the screenshot service entirely and rely on favicons and text-only previews instead. That trade-off is configurable in the .env file with a single variable, and the rest of Hoarder continues working normally without it.
Frequently Asked Questions
Does Hoarder work without an AI API key?
Yes. AI tagging is optional. Hoarder functions fully without an OpenAI key or Ollama instance – you can tag bookmarks manually and still get full-text search.
Can I access Hoarder from outside my home network?
Yes, by placing it behind a reverse proxy with HTTPS and exposing the correct port. You can also access it privately over a VPN like Tailscale without opening any public ports.





