Installing Karakeep on Your Server: Your Own Bookmark Manager with Docker

Install Karakeep, the bookmark manager for everything, on your own server using Docker and Docker Compose. Includes a reverse proxy with Caddy and optional AI integration.

Installing Karakeep on Your Server: Your Own Bookmark Manager with Docker hero image

In this blog post, we’ll take a closer look at Karakeep. Karakeep is a promising bookmark app that aims to enable bookmarking for everything. Whether it’s websites, notes, images, or even RSS feeds – Karakeep aims to become your central hub.

We will install Karakeep together on a server, secure it for external access, and even explore some of its optional AI features.

What is Karakeep?

Karakeep is an open-source bookmark manager designed to store more than just URLs. You can:

  • Save and archive websites (Full Page Archive).
  • Add notes and images.
  • Have tags automatically assigned by AI.
  • Have content summarized by AI.
  • Subscribe to and read RSS feeds.
  • Import bookmarks from browsers or other services.
  • Quickly add content via browser extensions and mobile apps.

Since it’s a self-hosted application, you retain full control over your data.

Glossary: Important Terms and Technologies

TermDescription
KarakeepThe open-source bookmark management software we are installing.
ServerA computer that provides services. Can be a home server (e.g., a Raspberry Pi or old PC) or a Virtual Private Server (VPS).
VPSVirtual Private Server; a rented virtual server from a hosting provider.
DockerA platform for creating, deploying, and running applications in containers.
Docker ComposeA tool for defining and running multi-container Docker applications. Configuration is done via a compose.yaml file.
ImageA template with instructions for creating a Docker container.
ContainerA running instance of a Docker image.
Bind MountLinks a directory on the host system with a directory in the container to store persistent data.
.env FileA file for storing environment variables.
Reverse ProxyA server that receives requests from the internet and forwards them to the appropriate internal service (here, Karakeep).
CaddyA modern, easy-to-configure web server and reverse proxy that automatically manages HTTPS certificates.
API KeyA unique code used for authentication and authorization when accessing an API (Application Programming Interface).
OCROptical Character Recognition; text recognition in images.
OpenRouterA service that provides access to various AI models via a unified API.

Prerequisites

Before we start, make sure you have the following:

  1. A Server: This can be a home server or a public VPS. For this guide, I’m using a VPS from Hetzner (Affiliate link: As a new customer, you’ll receive a €20 starting credit with this link). The server should be running a Linux operating system (e.g., Ubuntu).
  2. (Optional, but recommended) A Domain: If you want to access Karakeep securely and easily over the internet, a domain pointing to your server’s IP address is very useful.

Installing Karakeep with Docker Compose

Installing Karakeep is relatively straightforward thanks to Docker Compose. Since Karakeep is still under development (beta status), it’s advisable to always keep an eye on the official Karakeep documentation, as details may change.

0. Install Docker and Docker Compose

First, we connect to our server via SSH and ensure Docker is installed. If not, Docker and Docker Compose need to be installed. It’s best to follow the official documentation.

For Ubuntu, execute the following:

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

And then:

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

1. Create a Directory and compose.yaml File

We create a directory for Karakeep.

mkdir karakeep
cd karakeep

Next, we create the compose.yaml file. This file describes how our Karakeep application should be started with Docker.

nano compose.yaml

Copy the following content into the file. Make sure to adjust the image version!

services:
  web:
    image: ghcr.io/karakeep-app/karakeep:0.24.1 # Check the current version on GitHub!
    container_name: karakeep_web # Needed later for the reverse proxy
    restart: unless-stopped
    ports:
      - "3005:3000" # Host-Port:Container-Port (can be adjusted)
    env_file:
      - .env
    volumes:
      - ./data:/data # Bind mount for Karakeep data
    depends_on:
      - chrome
      - meilisearch
    networks: # Needed later for the reverse proxy
      - internal 
      # - proxy # Commented out for now, add later

  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
    networks:
      - internal

  meilisearch:
    image: getmeili/meilisearch:v1.13.3
    restart: unless-stopped
    env_file:
      - .env
    environment:
      MEILI_NO_ANALYTICS: "true"
    volumes:
      - ./meilisearch_data:/meili_data

networks:
  internal:
    external: false
  # proxy: # Commented out for now
  #   external: true # Commented out for now

Important notes on compose.yaml:

  • Image Version: I used 0.24.1. Go to Karakeep GitHub Packages and find the latest stable version (avoid latest, as this can lead to unexpected updates). Adjust the version for web and chrome if necessary.
  • Volumes: I’m using bind mounts here (./data and ./meilisearch_data). This means the data will be stored in subdirectories relative to your compose.yaml. Create these folders:
    mkdir data
    mkdir meilisearch_data
  • Ports: 3005:3000 means Karakeep will be accessible on port 3005 of your server and will forward requests to port 3000 in the container. If port 3005 is busy, choose another one (e.g., 3006:3000).
  • Networks: The proxy network definitions are commented out for now. We will activate them later for the reverse proxy.

Save the file (in nano with Ctrl+X, then Y and Enter).

2. Create the .env File

The .env file contains configuration variables.

nano .env

Add the following content and adjust the values:

MEILI_MASTER_KEY=YOUR_SUPER_SECRET_KEY_1
NEXTAUTH_SECRET=YOUR_SUPER_SECRET_KEY_2
NEXTAUTH_URL=http://localhost:3000

Important: Replace YOUR_SUPER_SECRET_KEY_1 and _2 with long, random strings. You can generate them, for example, like this:

openssl rand -base64 36

Run the command twice and copy the results into the .env file.

Save the file.

3. Start Karakeep Containers

Now we can start Karakeep:

sudo docker compose up -d

Docker will now download the images and start the containers in the background (-d). This might take a while the first time.

You can check the status of the containers:

sudo docker compose ps
# Or view the logs:
sudo docker compose logs -f
# Or check resource usage:
sudo docker compose stats

Normally, the containers should be running after a short time. The logs can be very helpful in case of problems. On the first start, Meilisearch might need some time for indexing.

4. First Access and Create Admin Account

Open your web browser and enter the IP address with the port from your compose.yaml.

You should see the Karakeep login screen.

  1. Click on “Sign up”.
  2. Create your user account. The first user automatically becomes the administrator.

Log in and explore the interface! You can change the language in the user settings (gear icon top right -> User Settings -> Interface).

Basic Configuration and First Steps

After successful installation and the first login, I recommend making a few basic settings.

Disable Signups (DISABLE_SIGNUPS)

Once you’ve created your admin account, it’s advisable to disable public registration unless you want anyone to be able to sign up.

  1. Open the .env file:
    nano .env
  2. Add the following line:
    DISABLE_SIGNUPS=true
  3. Save the file and restart Karakeep for the changes to take effect:
    sudo docker compose down
    sudo docker compose up -d

If you now log out and try to register again (“Sign up”), you should see a message that registrations are disabled.

Set OCR Languages (OCR_LANGS)

If you want Karakeep to recognize text in images (OCR), you can set the languages for it.

  1. Open the .env file.
  2. Add (e.g., for English and German):
    OCR_LANGS=eng,deu
  3. Save and restart Karakeep:
    sudo docker compose down
    sudo docker compose up -d

(Optional) Advanced Features with AI

Karakeep offers optional AI features like automatic tagging and summaries. This is not active by default. If you want to use your own API key (e.g., from OpenAI or OpenRouter):

I like to use OpenRouter as it gives me access to various models.

  1. Get an API Key: Create an account at OpenRouter.ai and generate an API key. Top up your balance if necessary.
  2. Adjust the .env file:
    nano .env
    Add/change the following variables:
    OPENAI_API_KEY=YOUR_OPENROUTER_API_KEY # Your key from OpenRouter
    OPENAI_BASE_URL=https://openrouter.ai/api/v1
    INFERENCE_TEXT_MODEL=google/gemini-2.5-flash-preview
    INFERENCE_IMAGE_MODEL=google/gemini-2.5-flash-preview
    You can find a list of available models on the OpenRouter website.
  3. Restart Karakeep:
    sudo docker compose down
    sudo docker compose up -d

Now, when you add bookmarks, tags should be generated automatically. You can also try to have articles summarized. Using the API costs money, but with moderate use and inexpensive models (like Gemini Flash), the costs are manageable (often less than a cent per request). Free models are also available, but they are less reliable (not in terms of results, but regarding rate limits, etc.).

Integrate RSS Feeds

Under “User Settings” -> “RSS”, you can add RSS feeds (e.g., from your favorite blog https://deployn.de/rss.xml). Karakeep will then import the articles, and you can read and manage them directly in the app – optionally, have them automatically tagged too!

Set up a Reverse Proxy with Caddy (HTTPS and Domain)

To securely access Karakeep via a domain with HTTPS (e.g., https://karakeep.yourdomain.com), we’ll set up a reverse proxy with Caddy. Caddy automatically handles SSL certificates from Let’s Encrypt.

1. Prepare Karakeep

a) Adjust Container Name and Networks in Karakeep’s compose.yaml:

We have already defined container_name: karakeep_web in Karakeep’s compose.yaml. Now, we’ll adjust the network settings. Open Karakeep’s compose.yaml:

cd ~/karakeep # Make sure you are in the Karakeep directory
nano compose.yaml

Remove the port mapping and activate the proxy network for the web service:

services:
  web:
    image: ghcr.io/karabot/karakeep/web:0.24.1
    container_name: karakeep_web # Important for Caddy
    restart: unless-stopped
    # ports: # Comment out or delete this line
    #   - "3005:3000" # Comment out or delete this line
    env_file:
      - .env
    volumes:
      - ./data:/data
    depends_on:
      - chrome
      - meilisearch
    networks: # Adjust networks
      - internal
      - proxy # Add this network

  chrome:
    image: ghcr.io/karabot/karakeep/chrome:0.24.1
    restart: unless-stopped
    shm_size: '1gb'
    cap_add:
      - SYS_ADMIN
    networks: # Only internal
      - internal

  meilisearch:
    image: getmeili/meilisearch:v1.7
    restart: unless-stopped
    environment:
      - MEILI_ENV=production
      - MEILI_MASTER_KEY=${MEILISEARCH_MASTER_KEY}
    volumes:
      - ./meilisearch_data:/meili_data
    networks: # Only internal
      - internal

networks:
  internal:
    driver: bridge
  proxy: # Activate this section
    external: true # Means the network is managed outside this Compose file

Save the changes.

b) Adjust NEXTAUTH_URL in .env:

Open Karakeep’s .env file:

nano .env

Change NEXTAUTH_URL to your future HTTPS domain:

NEXTAUTH_URL=https://karakeep.yourdomain.com

Save the file.

2. Create Docker Network for the Proxy

This network will be shared by Caddy and Karakeep.

sudo docker network create proxy

(If it already exists, that’s okay.)

3. Set up Caddy

We will create a separate directory for Caddy.

cd ~ # Go to home directory
mkdir caddy
cd caddy
mkdir data config # Subdirectories for Caddy data and configuration

a) Create Caddy compose.yaml:

nano compose.yaml

Content:

services:
  caddy:
    image: caddy:latest
    container_name: caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile # Configuration file
      - ./data:/data # For certificates and other data
      - ./config:/config # For Caddy configuration
    networks:
      - proxy # Assign Caddy to the proxy network

networks:
  proxy:
    external: true

Save the file.

b) Create Caddyfile:

This is the configuration file for Caddy.

nano Caddyfile

Content (replace karakeep.yourdomain.com with your domain and provide your email address for Let’s Encrypt notifications):

karakeep.yourdomain.com {
    encode gzip

    # Forward to the Karakeep web container via the Docker network
    # karakeep_web is the container_name from the Karakeep compose.yaml
    # 3000 is the internal port of Karakeep in the container
    reverse_proxy karakeep_web:3000
}

Save the file. Make sure your domain (e.g., karakeep.yourdomain.com) points to your server’s IP address via a DNS A-record!

4. Restart Caddy and Karakeep

First, we start Caddy:

cd ~/caddy # Change to the Caddy directory
sudo docker compose up -d

Then, we restart Karakeep so it picks up the network changes:

cd ~/karakeep # Change to the Karakeep directory
sudo docker compose down # Stops and removes the old containers
sudo docker compose up -d # Starts Karakeep with the new configuration

5. Access via HTTPS Domain

Wait a moment for Caddy to issue the SSL certificate. You should now be able to reach Karakeep at https://karakeep.yourdomain.com.

Updating Karakeep

To update Karakeep:

  1. Check Karakeep GitHub Packages for a new version.
  2. Stop the running Karakeep containers:
    cd ~/karakeep
    sudo docker compose down
  3. Edit your compose.yaml and change the image tags for web and chrome to the new version.
  4. Pull the new images:
    sudo docker compose pull
  5. Restart Karakeep:
    sudo docker compose up -d

Always read the release notes in case there are breaking changes!

Conclusion

Karakeep is a powerful and flexible bookmark manager that can be self-hosted relatively easily thanks to Docker and Docker Compose. With a reverse proxy like Caddy, access becomes secure and user-friendly. The optional AI features and RSS integration complete the package, making Karakeep a central hub.

I hope this guide has helped you! Are you already using a self-hosted bookmark manager? Which features are most important to you? Feel free to write it in the comments!

FAQ

FAQs

What is Karakeep?

Karakeep is an open-source application for managing bookmarks, notes, images, and RSS feeds. It can be hosted on your own server.

Why should I use Docker Compose for the installation?

Docker Compose simplifies the definition and execution of applications consisting of multiple containers (like Karakeep with its web service, Chrome service, and Meilisearch database). The entire configuration is bundled in a `compose.yaml` file.

Can I use the 'latest' tag for Docker images?

It is generally recommended to use specific version tags (e.g., `0.24.1`) instead of `latest`. The `latest` tag can change unexpectedly and lead to incompatibilities or errors, especially with beta software.

What is a bind mount and why is it used here?

A bind mount links a directory on your host system (the server) directly with a directory in the Docker container. This ensures that Karakeep's data (bookmarks, configuration, etc.) and Meilisearch's data (search index) are stored persistently, even if the containers are stopped or recreated.

Do I absolutely need a reverse proxy like Caddy?

Not strictly necessary for pure functionality, but highly recommended. A reverse proxy allows access via an easy-to-remember domain, provides HTTPS (encrypted connection), and can enhance security. Caddy also automates the procurement and renewal of SSL certificates.

How do I update Karakeep to a newer version?

Stop the containers (`sudo docker compose down`), change the image version in your `compose.yaml` file, pull the new images (`sudo docker compose pull`), and restart the containers (`sudo docker compose up -d`).

What should I do if something doesn't work after starting?

Check the container logs with `sudo docker compose logs -f web` (or `chrome`, `meilisearch`). Error messages indicating the problem are often found there. Also, ensure that all paths and environment variables are set correctly.

Share this post:

This website uses cookies. These are necessary for the functionality of the website. You can find more information in the privacy policy