Self-Hosted Bookmark Manager with Hoarder on Docker: AI Summaries and Full-Text Search

HomeLab tutorial - IT technology blog
HomeLab tutorial - IT technology blog

The Bookmark Problem Nobody Talks About

I have a folder called “Read Later” with 847 links. At some point, “read later” became “never.” Sound familiar?

The real issue isn’t saving links — it’s finding them again. Pocket and browser bookmarks both fail at this. You remember an article was about Kubernetes networking, but you saved it eight months ago under a vague tag like “infra.” Good luck.

After Pocket shut down its free tier and Mozilla’s acquisition made things uncertain, I went looking for a self-hosted alternative that actually solved the retrieval problem, not just the saving problem. That’s how I found Hoarder — an open-source bookmark manager with built-in AI summarization and full-text search that runs cleanly on Docker.

Three months of daily use later: the folder is actually useful now. Here’s how to set it up.

What Hoarder Actually Does

Hoarder calls itself “AI-first,” and the feature list earns the label:

  • Automatic content scraping — saves a snapshot of each page at bookmark time, so dead links don’t lose you the content
  • AI-generated summaries — uses OpenAI or a local Ollama model to summarize each saved page
  • Full-text search — searches inside the scraped content, not just titles and URLs
  • Auto-tagging — AI suggests tags based on content
  • Browser extension — Chrome and Firefox extensions for one-click saving
  • Mobile-friendly UI — accessible from any device on your network

Under the hood: Next.js frontend, a background worker for crawling, Meilisearch for full-text indexing, and an optional AI layer. Everything containerized.

Prerequisites Before You Start

You’ll need:

  • A Linux server (bare metal or VM) with Docker and Docker Compose installed
  • At least 2GB RAM — Meilisearch is memory-hungry; 4GB+ is recommended if you enable AI
  • An OpenAI API key (optional but recommended for AI features), or a local Ollama setup
  • A domain or local DNS if you want HTTPS — works fine on a local IP too

Setting Up Hoarder with Docker Compose

Create a working directory and the compose file:

mkdir -p ~/homelab/hoarder && cd ~/homelab/hoarder
nano docker-compose.yml

Paste this configuration:

version: "3.8"

services:
  web:
    image: ghcr.io/hoarder-app/hoarder:release
    restart: unless-stopped
    ports:
      - "3000:3000"
    volumes:
      - hoarder_data:/data
    env_file:
      - .env
    depends_on:
      - meilisearch
      - chrome

  meilisearch:
    image: getmeili/meilisearch:v1.6
    restart: unless-stopped
    volumes:
      - meilisearch_data:/meili_data
    environment:
      - MEILI_NO_ANALYTICS=true
      - MEILI_MASTER_KEY=${MEILI_MASTER_KEY}

  chrome:
    image: gcr.io/zenika-hub/alpine-chrome:123
    restart: unless-stopped
    command:
      - --no-sandbox
      - --disable-gpu
      - --disable-dev-shm-usage
      - --remote-debugging-address=0.0.0.0
      - --remote-debugging-port=9222
      - --hide-scrollbars

volumes:
  hoarder_data:
  meilisearch_data:

Now generate the secrets and write the complete .env in one shot. This avoids duplicate keys and broken variable references:

NEXTAUTH_SECRET=$(openssl rand -base64 36)
MEILI_KEY=$(openssl rand -base64 36)

cat > .env << EOF
NEXTAUTH_SECRET=$NEXTAUTH_SECRET
MEILI_MASTER_KEY=$MEILI_KEY
NEXTAUTH_URL=http://YOUR_SERVER_IP:3000
HOARDER_LOG_LEVEL=info
BROWSER_WEB_URL=http://chrome:9222
MEILISEARCH_URL=http://meilisearch:7700
MEILISEARCH_MASTER_KEY=$MEILI_KEY
OPENAI_API_KEY=sk-your-openai-key-here
OPENAI_BASE_URL=https://api.openai.com/v1
# Optional: swap to local Ollama instead of OpenAI
# OLLAMA_BASE_URL=http://YOUR_SERVER_IP:11434
EOF

One thing to note: MEILI_MASTER_KEY and MEILISEARCH_MASTER_KEY must be identical. The first configures Meilisearch itself; the second tells the Hoarder web service how to authenticate with it. The script above handles this automatically.

Start everything:

docker compose up -d
docker compose logs -f web

Give it 30–60 seconds on first startup. Meilisearch takes a moment to initialize its index. Once the logs show Server running on port 3000, open http://YOUR_SERVER_IP:3000 in your browser.

First Login and Initial Configuration

On first run, Hoarder lets you create the admin account directly in the browser. Use a strong password — especially if you plan to expose this externally.

After login, head to Settings → AI to confirm your OpenAI key is recognized. Save a test bookmark and check that:

  1. The page content is scraped (check the “Cached” tab on the bookmark)
  2. A summary appears within a minute or two
  3. Tags are auto-suggested

If the summary doesn’t appear, check the worker logs:

docker compose logs web | grep -i "openai\|summary\|error"

Using Ollama Instead of OpenAI

Already running Ollama on your HomeLab? Swap the AI config in your .env:

# Comment out OpenAI
# OPENAI_API_KEY=...

# Add Ollama
OLLAMA_BASE_URL=http://YOUR_OLLAMA_HOST:11434
OLLAMA_MODEL=llama3.2

Restart the stack after changes:

docker compose restart web

Ollama handles summarization well. For auto-tagging accuracy, llama3.2 or mistral produce decent results. Not GPT-4 quality, but for a free, private setup it’s more than enough.

Installing the Browser Extension

The browser extension is what makes Hoarder actually usable day-to-day. Without it, you’re copying URLs manually — which defeats the purpose.

  1. Search “Hoarder” in the Chrome Web Store or Firefox Add-ons
  2. After installing, click the extension icon → Settings
  3. Set Server URL to your Hoarder address: http://YOUR_SERVER_IP:3000
  4. Generate an API key in Hoarder: Settings → API Keys → New Key
  5. Paste the API key in the extension settings

One-click saving from that point on. The extension also previews the AI summary once it’s generated.

Practical Tips From Daily Use

Search is the Killer Feature

Stop browsing your bookmark list. Just search. Hoarder indexes the full page content, so you can find a concept you remember reading about even if you forgot where you saved it. Type a few words from the article body — Meilisearch handles typos too.

Use Lists for Projects

Hoarder’s “Lists” feature beats folders for ongoing work. Create a list per active project, add relevant bookmarks to it, archive the list when the project wraps. Your global bookmark count stays manageable.

Set Up a Reverse Proxy for Remote Access

Want to reach Hoarder outside your home network? Put it behind Nginx Proxy Manager or Caddy with HTTPS. A minimal Caddy config:

hoarder.yourdomain.com {
    reverse_proxy localhost:3000
}

Don’t expose it without HTTPS — your API key and bookmarks travel in plaintext otherwise.

Backup the Data Volumes

Scraped content accumulates fast. My instance hit ~2GB after two months. Back up both volumes regularly:

# Backup script — add to cron
docker run --rm \
  -v hoarder_hoarder_data:/source:ro \
  -v /backup/hoarder:/backup \
  alpine tar czf /backup/hoarder_data_$(date +%Y%m%d).tar.gz -C /source .

docker run --rm \
  -v hoarder_meilisearch_data:/source:ro \
  -v /backup/hoarder:/backup \
  alpine tar czf /backup/meili_data_$(date +%Y%m%d).tar.gz -C /source .

Updating Hoarder

docker compose pull
docker compose up -d

Hoarder uses the release tag which tracks stable releases. Check the GitHub releases page before pulling if you want to know what changed.

Closing Thoughts

After three months of daily use, my “Read Later” folder is actually useful now. Full-text search combined with AI summaries changes how you interact with saved content — it stops being a link dump you ignore and becomes a knowledge base you actually query.

Setup takes about 20 minutes. My instance idles at ~400MB RAM without AI, ~900MB with Ollama running. Updates and backups follow the same patterns as every other service in your HomeLab stack — one docker compose pull and a cron-scheduled volume backup.

If you’re still relying on browser bookmarks or a dying cloud service, this is worth the afternoon.

Share: