Fully verified30,144

Bookmarks and archiving

Karakeep

Karakeep saves links, readable pages, screenshots, images, PDFs, and text notes. Organize a private library with lists, tags, and full-text search. This recipe includes SQLite, Meilisearch, and a headless browser; AI tagging is optional and is not configured.

Alternative to Raindrop.ioAGPL-3.0-onlyVersion 0.34.1

Overview

Karakeep collects links, text notes, images, and PDFs in a private library. Lists, tags, favourites, and full-text search make it useful for research, household references, and reading later. Official Android and iOS apps and browser extensions can send items to the server; a standalone desktop client is not bundled.

Compared with Linkwarden, evaluate how each handles lists, saved formats, sharing, and search. Karakeep also keeps plain text notes alongside links. Saving a URL is not a guarantee that a paywall, login page, or bot-protected site can be archived.

This recipe runs the official app with SQLite, Meilisearch 1.41.0, and a separate headless browser. Allow two cores, 2 GB RAM minimum (4 GB recommended), and 10 GB disk plus saved content. Browser jobs can exceed those estimates; monitor disk and memory. The reliable deployment level is unsupported: this single-server recipe has no external database, monitoring, or resource limits.

Password login and native OIDC are available upstream; this recipe configures password login only. It does not configure SAML, a second factor, trusted-header login, SMTP, or an AI provider. AI tagging is optional, and bookmark capture and search work without an API key. Backups are not end-to-end encrypted.

The application is AGPL-3.0 licensed; the deployment recipe is MIT licensed. See the upstream licence before modifying and serving the software. This entry is experimental until wider deployment evidence exists.

Sources: features and clients, configuration, security considerations, release, licence.

Security assessment

The reviewed configuration keeps registration closed and internal service ports private. Basic SSRF checks and container isolation do not make hostile crawled content safe. Use trusted accounts and an independent egress policy. This review is not a security audit.

Update tracking

These are stored results of separate checks, not real-time data. An unknown status means the check has not been performed yet.

New releases

Recipe version compared with the latest known upstream release. A version number, not a reading of what changed.

Current version 0.34.1Oct 29, 2026, 2:25 PM UTC

Breaking updates

A new major version is found by comparing version numbers. A compatibility verdict is entered by hand after reading the release notes and the migration steps.

Not checkedNot checked

compose.yaml

Upstream Compose changes relative to the verified recipe.

Upstream Compose is not trackedNot checked

Outdated Docker images

Pinned image tags checked for newer versions.

Not checkedNot checked

From observation to action

Update plan

The recipe already pins the latest known release. The steps below show the evidence retained for that version.

0.34.10.34.1
  1. Open the release evidence

    Open this release on GitHub ↗ The link is evidence to review, not proof of compatibility.

  2. Review the version boundary

    The version numbers do not cross a major compatibility boundary. No compatibility verdict has been recorded.

  3. Prepare image-tag changes

    No image-tag change is currently planned.

  4. Follow the documented migration shape

    Manual steps after the pull. Release-specific migration steps still come from the release notes and installation guide.

  5. Protect the rollback point

    No version change is currently planned. The recipe includes a backup procedure. Restore has been tested.

  6. Verify the updated recipe

    An exact Fully verified check for this target was recorded on 2026-10-29.

Read the update procedure in the installation guide ↓

Specifications

Security and exposure

Installation levels

The status shows how fully the published recipe meets each level's requirements.

Ready

For home

A minimal setup for a local network or access through a VPN.

  • Single server
  • Local access
  • Minimum components

The recipe covers every requirement at this level.

Ready

For a VPS

A public deployment with protected access and backups.

  • Domain
  • HTTPS via reverse proxy
  • Off-server backup

The recipe covers every requirement at this level.

Not supported

Reliable

A setup designed for predictable operations and observability.

  • Separate database
  • Healthcheck
  • External monitoring
  • CPU and memory limits

You still need to add: separate database, external monitoring, cpu and memory limits.

Tailored to your server

Configuration generator

Answer five questions and download a ready-to-run Karakeep bundle.

Runs locally
01 Do you have a domain?
02 Which reverse proxy?
03 Server architecture
04 Where should data be stored?

Use an absolute path for a separate disk, such as /srv/karakeep.

05 Is VPN access required?

Your bundle is ready

The archive is created in your browser. Your answers are never sent anywhere.

The same files as one shell script, written in plain heredocs so you can read the whole thing before it runs. It checks Docker, the architecture, memory, disk and the ports it needs, and writes nothing until you add --apply.

Screenshots

Quick start

Read the full guide first: it explains external access, backups, and data locations.

Prepare settingscp .env.example .env
Launchdocker compose up -d
Check statusdocker compose ps

Step-by-step guide

Prepare the server

Use 64-bit Ubuntu 22.04+ or Debian 12+, Docker Engine, and Compose v2.24+. Allow two cores, 2 GB RAM minimum (4 GB recommended), and 10 GB disk plus saved content. These are planning estimates, not a capacity benchmark.

mkdir -p ~/services/karakeep
cd ~/services/karakeep
# Copy every recipe file, including proxy/ and the scripts, here.
cp .env.example .env
chmod 600 .env
openssl rand -hex 32
openssl rand -hex 32

Put the two different generated values in KARAKEEP_AUTH_SECRET and KARAKEEP_MEILI_KEY. The scripts source .env as trusted shell configuration. Use shell-safe values and protect it from other users.

Parameter Meaning
KARAKEEP_VERSION Exact application tag, initially 0.34.1, without v.
KARAKEEP_PORT Loopback host port, default 3000.
KARAKEEP_URL Exact browser origin, initially http://localhost:3000; use the public HTTPS origin behind a proxy. Also restricts trusted authentication origins.
KARAKEEP_AUTH_SECRET Random session/authentication secret; keep it with the backup.
KARAKEEP_MEILI_KEY Independent random key shared by the application and Meilisearch.
KARAKEEP_DISABLE_SIGNUPS true normally; temporarily set false to create the first account through the SSH tunnel.
TZ IANA time zone, default Etc/UTC.
KARAKEEP_BACKUP_DIR Optional absolute backup directory; empty uses backups/ beside the recipe.

The data named volume holds SQLite, uploaded files, saved pages, and queue state under /data. The search volume holds the Meilisearch index under /meili_data. Chrome state is disposable. Compose scopes both volumes to the project; keep the project name stable. Neither the search API nor Chrome’s DevTools port is published.

Start and create an account

Keep the reverse proxy disabled. Set KARAKEEP_DISABLE_SIGNUPS=false, then:

docker compose config --quiet
docker compose pull
docker compose up -d --wait --wait-timeout 600
curl --fail http://127.0.0.1:3000/api/health

From your computer run ssh -L 3000:127.0.0.1:3000 user@server. Open http://localhost:3000, sign up with a unique password, and verify login. Set KARAKEEP_DISABLE_SIGNUPS=true and recreate the app:

docker compose up -d --wait --wait-timeout 600 karakeep

Only publish the proxy after signup is closed. There are no committed account credentials. Additional accounts require another controlled registration window. AI, SMTP, and OIDC are not configured. Do not add an external AI key unless you accept its privacy and billing terms.

VPS

Complete the account setup through the tunnel first. Set KARAKEEP_URL=https://keep.example.com, configure DNS and an HTTPS proxy, and recreate Karakeep. Permit only SSH, HTTP, and HTTPS through the firewall. Keep port 3000 bound to loopback and store encrypted backups off-server.

Trusted local network

Use the SSH tunnel or an HTTPS proxy reachable from your trusted LAN/VPN. Keep the loopback binding when using a host proxy. If you deliberately bind a private interface, restrict it with a firewall and set KARAKEEP_URL to the exact origin people open. Do not expose a registration window to untrusted users.

Domain and HTTPS

Choose a sample in proxy/. Caddy obtains certificates; Nginx needs your certificate paths; Traefik needs the websecure entry point and letsencrypt resolver. These host-proxy samples forward to 127.0.0.1:3000. A container proxy must share a network with Karakeep and use karakeep:3000; its loopback is not the host loopback.

Replace the example hostname and keep KARAKEEP_URL identical to the external origin. Forward Host and X-Forwarded-Proto correctly; an HTTPS origin uses secure cookies. The Nginx sample permits 50 MB request bodies. Test login and an upload over the final URL. Do not publish ports 7700 or 9222.

Backup

./backup.sh

The script stops Karakeep and Meilisearch, archives both complete volumes plus active .env and Compose, and restarts only the services that were running. The private archive is backups/karakeep-<timestamp>.tar. SQLite and its WAL must be copied together while writers are stopped. Keep the search index with the matching engine version.

Encrypt and copy this archive off-server. It contains accounts, private notes, pages, files, keys, and secrets. A personal export or server-to-server CLI migration does not replace this backup.

Restore

Restore replaces both volumes. Use a trusted archive and the matching application and Meilisearch versions. On a fresh server, copy the recipe, inspect the archived compose.yaml and configuration.env, and recreate compatible active configuration first. Archived configuration is not activated automatically.

docker compose up -d --wait --wait-timeout 600
./restore.sh ./backups/karakeep-TIMESTAMP.tar
curl --fail http://127.0.0.1:3000/api/health

The script checks archive members, creates a safety backup, replaces both volumes, and waits for health. If replacement fails, keep the services stopped until you restore a verified archive. Sign in, read a private note, open a saved file, and search for known content. The smoke test verifies an account, private note, and a stored file after removal of both original volumes; it does not prove recovery across versions.

Update

  1. Read the release notes and create an off-server backup.
  2. Change KARAKEEP_VERSION to the reviewed exact version. Change the separately pinned Chrome image only after reviewing its release and compatibility.
  3. Run docker compose pull, then docker compose up -d --wait --wait-timeout 600. Check logs, login, a saved page, and search.
  4. Treat a Meilisearch version change as a separate migration. Follow the official index upgrade guide: take a complete backup, use the migration option documented for that exact engine version, then remove it. Do not start a new engine on old data without a migration or a deliberate index rebuild.

Application migrations run at startup. Never use latest or release as a deployment tag. A successful healthcheck alone does not prove that search and saved content survived.

Rollback

Do not run an older app on a migrated SQLite database or an older Meilisearch on a newer index.

  1. Keep the pre-update archive and the matching recipe/configuration.
  2. Stop writers: docker compose stop karakeep meilisearch.
  3. Restore the old exact application and sidecar versions in active Compose and .env; retain matching secrets. Pull those images.
  4. Run docker compose create without starting them on the new data.
  5. Run ./restore.sh ./backups/karakeep-BEFORE-UPDATE.tar, then verify login, notes, saved files, and search. The safety backup can archive stopped containers without running the old app on new state.

Stop and remove

docker compose down keeps the volumes. After verifying an encrypted off-server backup, docker compose down --volumes permanently removes the library and index. Deleting the recipe directory also deletes local configuration and backups. Do not use global Docker pruning commands.

Sources: Docker deployment, configuration, security, server migration limits.

Report a recipe problem

Tell us how it went on your server

Opens a prefilled GitHub issue. A GitHub account is required; submitting the issue makes it public.

Troubleshooting

Startup or healthcheck failure

Run docker compose ps --all and docker compose logs --tail=200 karakeep meilisearch chrome. Check free disk and RAM with df -h and free -m. Browser jobs need more memory than an idle instance. Confirm you replaced both secrets and retained the Meilisearch key between restarts. docker compose config --quiet checks interpolation; avoid sharing the full rendered configuration because it contains secrets.

Login fails or cookies disappear

Check that KARAKEEP_URL is the exact origin you opened, including scheme and nonstandard port. An HTTPS origin needs HTTPS and correct forwarded headers. For first setup use http://localhost:3000 through the SSH tunnel. Registration is deliberately disabled; temporarily enable it only in a trusted setup window, then disable it and recreate the app. OIDC and SMTP require additional upstream configuration and are not included.

A page will not archive

Check Chrome health and crawler logs. Paywalls, login pages, bot protection, large files, and unsupported sites may prevent capture. Private/internal targets are blocked by default; do not disable SSRF protections to fix an arbitrary bookmark. The app and browser need outbound access. Do not publish the Chrome debugging port as a workaround.

Search stopped after an engine update

Read the Meilisearch logs for an incompatible database-version message. Restore the old engine together with the matching full backup, or follow the official index migration/rebuild guide. Do not remove the whole library volume to rebuild a disposable search index.

Backup or restore failed

Use a trusted archive produced by this recipe, matching images, and the matching secrets from the archived configuration. The scripts require created containers to discover the exact named volumes. Review errors before restarting writers; a failed replacement must not be treated as successful recovery. Keep the source archive and the safety backup until login, private content, files, and search are verified.

Sources: configuration, security, Meilisearch upgrade.

Official sources

Latest release: 2026-10-22 · GitHub Stars: 30,144 · metadata checked Oct 29, 2026, 2:25 PM UTC

Disclaimer

Fossary is an independent informational catalog and is not affiliated with the developers of the listed applications. We collect information from public sources and verify published recipes, but we do not develop, distribute, or control these applications.

A listing or validation status is not a requirement, endorsement, or personal recommendation to use an application. You decide whether it is suitable and use it at your own risk. We do not warrant an application's security, availability, or fitness for purpose and, to the extent permitted by law, are not liable for resulting loss or damage. Review its license, security settings, data processing, and backup procedures before installation.