Why Self-Hosted Bookmarking Is Worth the Setup
Most read-it-later apps work fine until they don’t – until the company pivots, raises prices, or simply shuts down and takes your archive with it. Karakeep (formerly known as Hoarder) is an open-source, self-hosted alternative that stores everything on your own server: articles, links, screenshots, and full-text search. You own the database, you control the exports, and nothing disappears because a startup ran out of runway.
The appeal goes beyond data ownership. Karakeep supports AI-powered tagging using a local or remote language model, automatic link archiving with screenshots, and a clean web interface that works on mobile without a dedicated app. For anyone already running a home server or VPS, adding Karakeep to a Docker Compose stack takes under an hour – and the result is a bookmarking setup that actually improves with use rather than degrading behind a paywall.

What You Need Before Starting
Karakeep runs entirely inside Docker, which keeps the installation clean and portable. Before touching any config files, make sure you have Docker and Docker Compose installed on the host machine – whether that is a Raspberry Pi 4, a home server running Ubuntu, or a VPS. The minimum comfortable spec is 1GB of RAM for basic use, though if you plan to enable the AI tagging feature with a local model via Ollama, 4GB or more is realistic. A VPS with at least 2GB RAM works well for the AI features without saturating the host.
You will also need a domain or subdomain pointed at your server if you want HTTPS access from outside your home network. A reverse proxy like Caddy or Nginx Proxy Manager handles the SSL certificate automatically using Let’s Encrypt. If you are only accessing Karakeep from inside your home network, a local IP address works without any domain configuration at all. For anyone already running a private file storage setup like Nextcloud on a VPS, the reverse proxy is likely already in place and Karakeep slots in as another upstream service.
Installing Karakeep with Docker Compose
Start by creating a project directory – something like /opt/karakeep or ~/docker/karakeep depending on your preference. Inside that directory, create a file named docker-compose.yml. Karakeep’s official repository provides a reference compose file, and using it as a base is the fastest path to a working install. The stack includes three main services: the Karakeep web application, a MeiliSearch container for full-text search indexing, and a Chrome/Chromium service used to generate screenshots and fetch full article content from paywalled or JavaScript-heavy pages.
The core compose block looks roughly like this. The karakeep service pulls from ghcr.io/karakeep-app/karakeep:release and mounts a local volume for persistent data. You expose port 3000 (or whatever local port you prefer) and pass environment variables for the secret key, MeiliSearch address, and the Chrome WebSocket URL. The meilisearch service uses the official MeiliSearch image and mounts its own data volume. The chrome service runs gcr.io/zenika-hub/alpine-chrome with the –no-sandbox flag and exposes port 9222 for the remote debugging protocol that Karakeep uses to control headless browsing.
Environment variables are where most configuration happens. Set NEXTAUTH_SECRET to a long random string – use openssl rand -base64 32 to generate one. Set NEXTAUTH_URL to the full URL you plan to use, including the protocol. MEILI_ADDR points to the MeiliSearch container’s internal address, typically http://meilisearch:7700. BROWSER_WEB_URL points to the Chrome service at http://chrome:9222. Store sensitive values in a .env file alongside the compose file and reference them with the standard ${VARIABLE_NAME} syntax rather than hardcoding secrets directly into the YAML.
Once the compose file is ready, run docker compose up -d from the project directory. Docker pulls the images on first run, which can take a few minutes depending on connection speed. After the containers start, open a browser and navigate to your server’s IP on port 3000. The first-time setup screen asks you to create an admin account – use a strong password since this instance is publicly accessible if you have pointed a domain at it. Karakeep is running at this point, and links added through the web interface will immediately begin archiving with full screenshots.

Configuring AI Tagging and the Browser Extension
Karakeep’s AI tagging feature automatically assigns relevant tags to saved links by analyzing the article content. Out of the box, it connects to OpenAI’s API – you provide an API key in the environment variables via OPENAI_API_KEY and set OPENAI_BASE_URL if you want to redirect to a compatible local model. Running Ollama on the same host lets you use a model like llama3 or mistral without sending content to any external service. The tradeoff is that local inference on modest hardware is noticeably slower than the API route, sometimes taking 10-20 seconds per link depending on article length and model size.
For the browser extension, Karakeep publishes extensions for Chrome and Firefox. After installing the extension, open its settings and enter your instance URL and your API key, which you generate from the Karakeep web interface under account settings. Once connected, saving a page takes a single click, and the extension captures the URL, title, and optionally the full page content. There is also a mobile bookmarklet for iOS and Android Safari that works through the share sheet – not as smooth as a native app, but functional for on-the-go saving.
Full-text search deserves some attention during setup. MeiliSearch indexes article content as links are archived, which means search across your entire library works even when the original URL has gone offline. The index lives in the MeiliSearch data volume and grows gradually. On a 1GB RAM machine, the MeiliSearch container itself uses roughly 150-200MB at idle, which is acceptable, but watch memory usage if you are on a tight VPS plan and archiving aggressively. You can set MEILISEARCH_NO_ANALYTICS to true in the MeiliSearch environment block to disable its telemetry reporting.
One configuration detail that catches people off guard: Karakeep stores archived page assets – screenshots, favicons, and cached article HTML – inside the application data volume. On a busy saving schedule, this grows quickly. If your Docker data directory is on a small root partition, redirect the volume mount to a larger disk by adjusting the volume path in the compose file before you start accumulating thousands of articles. Moving the data volume after the fact requires stopping the stack, copying the volume contents to the new location, updating the compose file path, and restarting – doable, but easier to plan ahead.

Karakeep also supports importing from Pocket and Instapaper through a simple JSON/HTML import flow in the settings panel, which means migrating an existing archive does not require starting from scratch. The import process queues each link for archiving, so the background worker processes them gradually rather than hammering your server all at once – a sensible design choice that keeps the system stable during bulk ingestion. Whether the AI tagging catches up accurately with a large imported backlog depends heavily on how much compute you allocate to the worker, and that is the one variable still worth monitoring after your first few hundred imports.





