Karakeep Self-Hosted: The Archive Is Off by Default
Self-hosting Karakeep: the three-container stack, why full page archiving ships switched off, and what the headless Chrome exposes to anyone who can sign up.

⚡ The short version
Karakeep is three containers, and the one thing people install it for is switched off. Full page archiving — a local copy of the page so your bookmark survives the link dying — ships disabled, because it costs disk. Without it you keep the readable text and a screenshot, which is a different promise. One environment variable changes that, and it is worth changing before you import ten years of links.
There are seven guides to this on the first page of results and every one is a setup walkthrough. None mentions that the archive is off, which means a lot of people are running a link-rot insurance policy that is not insuring anything.
Everything below about self-hosting Karakeep was read on 1 October 2026 from the project’s own repository at tag v0.33.2: the compose file it ships, its documented environment variables, and the crawler source that acts on them.
What Does the Karakeep Stack Actually Look Like?
Three services, and the project publishes the file itself:
services:
web:
image: ghcr.io/karakeep-app/karakeep:0.33.2
restart: unless-stopped
volumes:
- data:/data
ports:
- 3000:3000
env_file:
- .env
environment:
MEILI_ADDR: http://meilisearch:7700
BROWSER_WEB_URL: http://chrome:9222
DATA_DIR: /data
chrome:
image: ghcr.io/karakeep-app/karakeep-chrome:release
restart: unless-stopped
init: true
command:
- --disable-gpu
- --disable-dev-shm-usage
- --hide-scrollbars
- --disable-blink-features=AutomationControlled
- --window-size=1440,900
meilisearch:
image: getmeili/meilisearch:v1.41.0
restart: unless-stopped
env_file:
- .env
environment:
MEILI_NO_ANALYTICS: "true"
volumes:
- meilisearch:/meili_data
volumes:
meilisearch:
data:
Each extra service is there for a reason you can name, which is the test in the count of how many containers a self-hosted app needs. Meilisearch indexes the contents of what you saved rather than just the titles, which is the difference between a bookmark list and something searchable. Chrome is there because a growing share of the web does not exist until JavaScript runs, and a plain fetch of such a page returns a shell. If reading a file like this is new, the Docker workflow for self-hosting covers what each block does.
Two details are worth more than they look. The search engine is pinned at v1.41.0 and the project’s troubleshooting page says not to upgrade it without a reason: a newer Meilisearch refuses an older database, and getting out means rebuilding the index. And the Chrome image is the project’s own, which is new — it replaced an unmaintained third-party Alpine Chrome image. The migration note is specific about what breaks if you copy an old compose file forward: the new image forwards port 9222 itself, so the --remote-debugging-port arguments every older guide carries now conflict with its entrypoint and must come out.
I pinned the app at 0.33.2 where the project’s file reads ${KARAKEEP_VERSION:-release}, and the tag has a trap in it: the git tag is v0.33.2, the registry serves 0.33.2. Asked for both on 1 October 2026, the v form returned 404 and the bare form 200.
All three images publish linux/amd64 and linux/arm64 and nothing else, measured against the registries the same day. A 64-bit Pi 4 or 5 will run this; a 32-bit Raspberry Pi OS install will not pull it at all, worth knowing before planning a Raspberry Pi self-hosting build around it. The project publishes no memory figure, so the idle and active numbers in those setup guides are somebody else’s hardware.
Three Containers or One? The Minimal Install
Only the app is required, and the project documents a single-container compose file for exactly this case.
It is an honest trade rather than a hidden one. Drop Meilisearch and search stops entirely, not degrades. Drop Chrome and crawling still happens, but you lose screenshots and any page that renders itself client-side comes back wrong or empty. The project’s warning on that page says you sacrifice a lot of functionality, and it is right.
✅ Run all three when
- You want to search inside saved pages rather than through their titles
- You save from sites that are mostly JavaScript, which is most of them now
- The box has the headroom and you would rather not revisit the decision
❌ Run the one container when
- The server is small and already busy with something that matters more
- You are evaluating it and want the smallest thing that proves the idea
- Your bookmarks are static pages and documentation, where a text fetch is enough
You can start minimal and add the other two later by editing the compose file; nothing in the data directory changes. It is a first step rather than a corner.
Why Is the Full Page Archive Switched Off?
Because it costs disk, and the project chose the cheaper default.
Four crawler settings decide what each saved link leaves behind. These are their defaults, read from the project’s configuration source on 1 October 2026:
| Setting | Default | What it does |
|---|---|---|
| Store screenshot | on | Keeps a picture of the visible part of the page |
| Full page screenshot | off | Extends that picture to the whole scroll length |
| Store PDF | off | Keeps a PDF of the crawled page as well |
| Full page archive | off | Keeps a self-contained local copy of the page |
So out of the box a bookmark gets its title, its description, its readable text and a screenshot of the top of the page. That is a good bookmark. It is not an archive, and the documentation says so in one clause: with the setting off, only the readable text of the page is archived.
Turn it on and the crawler shells out to monolith, which flattens a page and everything it references into one HTML file. Karakeep runs it with JavaScript excluded and the document isolated — the right call for an archive, and the limit in the same breath: what comes back is a static snapshot, so an interactive map archives as the frame around it. For an article about to vanish, it is exactly what you wanted.
The archive timeout is five seconds, and that is not monolith's own default. Monolith itself waits 120 seconds. On a slow site the archive step gives up and leaves you the text copy, with nothing on the bookmark saying it was attempted. If archives fail on particular domains, that timeout is the first thing to raise.
Already imported everything? Each bookmark has an archive action in its own menu, and a bulk re-crawl archives a whole selection, so the fix is a click rather than a re-import.
Is Karakeep the Same App as Hoarder?
Yes, and that matters mainly because of what you will find when you search.
Hoarder was renamed Karakeep, and the rename kept the repository rather than forking it: asking GitHub for the branches of both the old and the new address on 1 October 2026 returned identical commit hashes, which is what a rename looks like from outside.
What did move is the image. It is now published under the Karakeep name, and the project’s migration note says the old one may stop getting updates — so a compose file still pulling the Hoarder image quietly stops receiving releases. The variable in that migration example is still called HOARDER_VERSION, which will confuse you for five minutes if nobody says it first.
The practical consequence is about sources rather than software. Much of the writing about this app still uses the old name, so a guide that says Hoarder is not necessarily out of date — but a guide that says Hoarder and shows the Alpine Chrome image is.
What Does the Headless Chrome Expose?
Your server’s network and your real IP address, to anyone who can add a bookmark.
The project states this itself rather than leaving it to be discovered. The crawler fetches whatever URL it is handed, from inside your network, and shows the result to whoever submitted it. Requests leave from your IP, so a page designed to log them learns where your server is even when the web interface sits behind a proxy. And a URL aimed at an internal address is a way to ask your own network questions from outside it.
Karakeep has partial protection against the second of those: it blocks worker requests resolving to private, loopback, link-local or Tailscale ranges unless you allowlist the hostname. Its documentation is honest that this covers only some of the risk.
New signups are allowed by default. The setting that disables them ships as false, and the first account created becomes the administrator. Put a fresh instance on a public hostname and walk away, and the next person to find it can sign up and start pointing your crawler at things. Set that flag before the DNS record exists, not after.
If you are exposing it, expose it properly — the guide to securing a self-hosted server covers the layer underneath. Karakeep also supports OIDC sign-in and can disable password logins entirely, which pairs with an identity provider like Authentik. One constraint to know first: it supports OIDC-compliant providers only, so a plain OAuth2 provider will not work.
What Do You Actually Back Up?
One directory, which is where the three-container stack gets easier than it sounds.
The app keeps everything you own under its data directory: a SQLite database file and the crawled assets beside it. Assets can be moved by setting, or pushed to S3-compatible storage, but by default they sit in that one place. So the backup is one volume — the simple half of the Docker volume backup guide rather than the database-dump half.
The Meilisearch volume is the interesting case, because you do not need it. The project’s own instructions for upgrading the search engine are to stop it, delete its data folder, restart it and press Reindex All Bookmarks in the admin settings. Something the application rebuilds from your database is not data, and backing it up buys you a faster first search and nothing else.
Stop the app before you copy the database. SQLite is a file, and a file copied mid-write restores as a file that will not open. A short docker compose stop web, copy, start avoids the whole class of problem on a personal instance.
The project’s command-line tool also has a server-to-server migration that moves bookmarks, lists, tags and rules over the API. Useful for changing hosts, not a backup: it needs a running instance at both ends.
Should You Turn On the AI Tagging?
Only if you have somewhere to run the model, and the default configuration will mislead you about that.
Automatic tagging is listed as enabled by default, and it does nothing until you supply a provider: the documentation is explicit that either an OpenAI key or an Ollama address has to be set, and without one the step is skipped. The switch being on is not the same as the feature being on.
Two things follow if you point it at a paid API. This site cannot tell you what it costs — token prices are not checkable from here and will not be printed as a guess. And the amount of each page sent to the model defaults to 2,048 tokens; the project’s own note says that is quite small, and that raising it improves the tags and raises the bill. That is the dial.
The local route is Ollama, which keeps the content on your hardware and turns the cost into electricity. One warning from the documentation is worth repeating: change the text model as well, because leaving the OpenAI default pointed at Ollama fails rather than falling back.
For most people the honest answer is that you do not need this. Full-text search across everything you saved is already what makes a bookmark pile useful. Tags are a nicer index on top of it.
Frequently Asked Questions About Self-Hosting Karakeep
How many containers does Karakeep need?
Three in the compose file the project publishes: the app itself, a headless Chrome that renders pages for it, and Meilisearch for full-text search. Only the app is mandatory. The project also documents a one-container minimal install, and what you give up for it is search, screenshots, and correct crawling of any page that builds itself with JavaScript.
Does Karakeep archive a page so it survives the link dying?
It can, and it does not do it until you ask. Read from the project’s own source on 1 October 2026, the full page archive setting is false by default, and with it off Karakeep keeps the readable text, the metadata and a screenshot rather than a copy of the page. Turning it on makes every new crawl store a self-contained file, and there is a per-bookmark archive action for the ones you already saved.
Is Karakeep just Hoarder with a new name?
Yes. Hoarder was renamed Karakeep and the project kept its history, so the old repository address still resolves to the new one and the two share every commit. What did move is the container image, which is now published under the karakeep name, and the project’s migration note says the old image may stop receiving updates. Half the guides you will find still say Hoarder.
Can Karakeep run on a Raspberry Pi?
On a 64-bit one, yes. Asking the registry directly on 1 October 2026, all three images publish linux/amd64 and linux/arm64 and nothing else, so a 64-bit Pi running a 64-bit operating system is fine and a 32-bit install is not. The project publishes no memory requirement, so treat any figure you see in a setup guide as that author’s own box rather than a spec.
What do you back up on a Karakeep server?
One directory. The app keeps a SQLite database and the crawled assets under its data directory, and that pair is the whole of your library. The Meilisearch volume is a rebuildable index rather than data: the project’s own troubleshooting guide tells you to delete its folder and press Reindex All Bookmarks, which means it does not need to be in the backup at all.
Product links on this site are plain links. We earn nothing from them — see our disclosure policy.