Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
id: meta
run: |
set -euo pipefail
image_name="ghcr.io/${{ github.repository_owner }}/karakeep"
image_name="ghcr.io/${{ github.repository_owner }}/marka"
short_sha="$(git rev-parse --short=12 HEAD)"
{
echo "image_name=${image_name}"
Expand Down
8 changes: 4 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Marka assistant context

`absolutepraya/karakeep` is the Marka fork. The upstream Karakeep project is <https://github.com/karakeep-app/karakeep>.
`absolutepraya/marka` is the Marka fork. The upstream Karakeep project is <https://github.com/karakeep-app/karakeep>.

## Authoritative documentation map

Expand Down Expand Up @@ -63,7 +63,7 @@ Main stack:
The preferred portable setup for a new self-hosted instance is `scripts/install.sh`. The public one-line entry point is:

```bash
curl -fsSLo /tmp/karakeep-setup.sh https://raw.githubusercontent.com/absolutepraya/karakeep/main/scripts/install.sh && bash /tmp/karakeep-setup.sh
curl -fsSLo /tmp/karakeep-setup.sh https://raw.githubusercontent.com/absolutepraya/marka/main/scripts/install.sh && bash /tmp/karakeep-setup.sh
```

Important installer facts:
Expand All @@ -72,7 +72,7 @@ Important installer facts:
- the script never installs Docker, changes firewall rules, configures DNS, or provisions TLS/reverse-proxy infrastructure
- default configuration directory is `~/karakeep`; default persistent data directory is `~/karakeep/data`
- generated Compose project name is `karakeep`
- generated app images are the paired `ghcr.io/absolutepraya/karakeep:web-main` and `ghcr.io/absolutepraya/karakeep:workers-main` tags
- generated app images are the paired `ghcr.io/absolutepraya/marka:web-main` and `ghcr.io/absolutepraya/marka:workers-main` tags
- the default web listener is `127.0.0.1:3000`, intended to sit behind an operator-managed reverse proxy for Internet-facing installs
- search choices are managed Meilisearch, external Meilisearch, or disabled search
- renderer choices are managed private Chrome, external token-protected Browserless, or disabled browser rendering
Expand Down Expand Up @@ -177,7 +177,7 @@ This fork uses a **pull-based** personal VPS deploy flow that is separate from t

High-level flow:
- CI passes on `main`
- `.github/workflows/docker.yml` builds and pushes matching `ghcr.io/<owner>/karakeep:web-main` and `ghcr.io/<owner>/karakeep:workers-main` images from the same successful commit
- `.github/workflows/docker.yml` builds and pushes matching `ghcr.io/<owner>/marka:web-main` and `ghcr.io/<owner>/marka:workers-main` images from the same successful commit
- a Watchtower container on the VPS polls the paired GHCR tags and redeploys automatically

Important notes:
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div align="center">
<a href="https://github.com/absolutepraya/karakeep/actions/workflows/ci.yml">
<img alt="CI status" src="https://img.shields.io/github/actions/workflow/status/absolutepraya/karakeep/ci.yml?branch=main&label=ci" />
<a href="https://github.com/absolutepraya/marka/actions/workflows/ci.yml">
<img alt="CI status" src="https://img.shields.io/github/actions/workflow/status/absolutepraya/marka/ci.yml?branch=main&label=ci" />
</a>
<a href="https://github.com/karakeep-app/karakeep/releases">
<img alt="Upstream release" src="https://img.shields.io/github/v/release/karakeep-app/karakeep?label=upstream%20release" />
Expand All @@ -19,15 +19,15 @@

Marka is a self-hostable library for saving links, notes, images, PDFs, and web pages, then finding them again with fast search, lists, highlights, and optional AI tagging and summarization.

> [`absolutepraya/karakeep`](https://github.com/absolutepraya/karakeep) is the Marka fork. The upstream Karakeep project is <https://github.com/karakeep-app/karakeep>.
> [`absolutepraya/marka`](https://github.com/absolutepraya/marka) is the Marka fork. The upstream Karakeep project is <https://github.com/karakeep-app/karakeep>.

![Homepage screenshot](./screenshots/homepage.png)

## What this repository is

This fork keeps the upstream product intact in spirit, while presenting and operating it as Marka:

- **Marka fork:** `absolutepraya/karakeep`
- **Marka fork:** `absolutepraya/marka`
- **Upstream project:** <https://github.com/karakeep-app/karakeep>
- **Focus:** UX polish, quality-of-life improvements, and personal deployment ergonomics
- **Local dev:** one-command workflow via `pnpm dev:start`
Expand Down Expand Up @@ -75,7 +75,7 @@ Marka can:
For a Linux `amd64` host that already has Docker Engine, Docker Compose v2, and OpenSSL, run:

```bash
curl -fsSLo /tmp/karakeep-setup.sh https://raw.githubusercontent.com/absolutepraya/karakeep/main/scripts/install.sh && bash /tmp/karakeep-setup.sh
curl -fsSLo /tmp/karakeep-setup.sh https://raw.githubusercontent.com/absolutepraya/marka/main/scripts/install.sh && bash /tmp/karakeep-setup.sh
```

The command downloads the script to a file before executing it. The guided flow asks for the install/data directories, public URL, search mode, browser-rendering mode, AI setup, and whether an existing compatible data directory should be reused. It generates a Docker Compose stack using the fork's paired `web-main` and `workers-main` images, writes secrets to restricted env files, validates the Compose config, and then starts the deployment.
Expand All @@ -85,7 +85,7 @@ The default listener is `127.0.0.1:3000`, so an Internet-facing deployment shoul
For a reproducible setup, replace `main` with an immutable release tag or commit SHA after reviewing that revision:

```bash
REF=<tag-or-commit-sha>; curl -fsSLo /tmp/karakeep-setup.sh "https://raw.githubusercontent.com/absolutepraya/karakeep/${REF}/scripts/install.sh" && bash /tmp/karakeep-setup.sh
REF=<tag-or-commit-sha>; curl -fsSLo /tmp/karakeep-setup.sh "https://raw.githubusercontent.com/absolutepraya/marka/${REF}/scripts/install.sh" && bash /tmp/karakeep-setup.sh
```

After setup, the copied helper supports safe operations without deleting persistent data:
Expand Down
4 changes: 2 additions & 2 deletions apps/web/components/shared/sidebar/SidebarVersion.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ describe("SidebarVersion", () => {
it("shows the running app build and a ready deployed update", () => {
const { container } = render(<SidebarVersion />);

expect(container.textContent).toContain("absolutepraya/karakeep");
expect(container.textContent).toContain("absolutepraya/marka");
expect(container.textContent).toContain("Build aaaaaaa");
expect(container.textContent).toContain("Update ready · bbbbbbb");

const buildLink = container.querySelector(
'a[href="https://github.com/absolutepraya/karakeep/commit/aaaaaaa"]',
'a[href="https://github.com/absolutepraya/marka/commit/aaaaaaa"]',
);
expect(buildLink).not.toBeNull();
});
Expand Down
2 changes: 1 addition & 1 deletion apps/web/components/shared/sidebar/SidebarVersion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { usePwaLifecycle } from "@/components/pwa/ServiceWorkerRegistration";
import { useTranslation } from "@/lib/i18n/client";
import { GitBranch, Github } from "lucide-react";

const FORK_REPO = "absolutepraya/karakeep";
const FORK_REPO = "absolutepraya/marka";
const FORK_REPO_URL = `https://github.com/${FORK_REPO}`;

function isCommitSha(value?: string): value is string {
Expand Down
4 changes: 2 additions & 2 deletions deploy/docker-compose.prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# NEXTAUTH_SECRET, MEILI_MASTER_KEY, NEXTAUTH_URL, DISABLE_SIGNUPS, ...
services:
web:
image: ${KARAKEEP_WEB_IMAGE:-ghcr.io/absolutepraya/karakeep:web-main}
image: ${KARAKEEP_WEB_IMAGE:-ghcr.io/absolutepraya/marka:web-main}
restart: unless-stopped
mem_limit: 512m
depends_on:
Expand All @@ -28,7 +28,7 @@ services:
DATA_DIR: /data

workers:
image: ${KARAKEEP_WORKERS_IMAGE:-ghcr.io/absolutepraya/karakeep:workers-main}
image: ${KARAKEEP_WORKERS_IMAGE:-ghcr.io/absolutepraya/marka:workers-main}
restart: unless-stopped
mem_limit: 512m
depends_on:
Expand Down
86 changes: 86 additions & 0 deletions docs/adr/0001-marka-public-identity-cutover-boundary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# ADR 0001: Marka public identity cutover boundary

- Status: Accepted for implementation planning
- Date: 2026-08-15
- Issues: #10, #11, #27, #35

## Context

The fork is publicly branded as **Marka**, but its external operational identity still uses Karakeep-era names in several places, including the GitHub repository, GHCR package path, production hostname, installer/repository URLs, and operator documentation.

A single all-at-once rename of every `karakeep` identifier would mix public branding changes with compatibility-sensitive machine identifiers such as package scopes, environment variables, persisted paths, Compose services, Docker networks, export/protocol identifiers, and other internal names. That would substantially increase migration risk without being required to establish Marka as the public identity.

The active production deployment is owned by this fork and is operated as a personal deployment, so the public GitHub/GHCR/domain cutover does not need to preserve a general third-party migration window.

## Decision

Issue #27 owns only the **public identity cutover**.

The approved public targets are:

- GitHub repository: `absolutepraya/marka`
- Canonical application origin: `https://marka.abhipraya.dev`
- GHCR web image: `ghcr.io/absolutepraya/marka:web-main`
- GHCR workers image: `ghcr.io/absolutepraya/marka:workers-main`

The GHCR migration is a hard switch. CI stops publishing new fork images to `ghcr.io/absolutepraya/karakeep`; historical images may remain but are not a supported compatibility path.

After the new Marka origin is verified, `keep.abhipraya.dev` becomes a permanent path- and query-preserving redirect to `marka.abhipraya.dev`.

The GitHub repository is renamed rather than replaced. The old `absolutepraya/karakeep` repository name must not be recreated, so GitHub's rename redirects remain available for historical links.

Repository-controlled current references, raw GitHub URLs, installer entry points, active badges/links, GHCR references, operator documentation, and Git remotes under our control move to the Marka identity. Git history and historical issue/PR/comment content are not rewritten solely to erase the old name.

Before any production mutation, a fresh production backup is copied to the local MacBook used by the implementation agent and verified readable. A short controlled maintenance window is acceptable.

The GitHub rename is intentionally forward-only, but production service recovery remains viable until the cutover stabilizes. Before any mutation, retain the verified local backup, old image references, deployed Compose/environment files, and nginx configuration. If Marka fails before the legacy redirect is enabled, restore the previous Compose image references, `NEXTAUTH_URL`, and old-host application server block from that evidence; do not proceed to the redirect checkpoint. Do not attempt to recreate the old GitHub repository name, because that would break GitHub's rename redirect.

Database/schema changes and persisted-data rewriting solely for branding are forbidden in #27.

## Deferred work

Machine-facing/internal identifiers remain unchanged during #27, including, where applicable:

- `KARAKEEP_*` environment variables
- `@karakeep/*` package scopes and package names
- persisted data/config/cache paths
- Compose service/project naming
- Docker network names such as `karakeep-renderer`
- export/protocol identifiers and compatibility keys
- other internal constants that do not form the active public identity
- the VPS deployment directory under the operator's home directory
- the MacBook checkout directory under `Documents/Projects`

The VPS and MacBook directory renames are explicitly deferred to #35. They are machine-facing paths that can affect Compose project discovery, local backup tooling, worktree configuration, shell history, and operator automation. They require their own path-by-path migration and validation rather than an incidental `mv` during #27.

Their audit and deliberate migration are tracked separately by #35.

Browser-extension store identity, mobile-store identity, npm/SDK package publishing identity, and MCP distribution identity are also excluded from the #27 publishing cutover. They are audited only for accidental dependency on the GitHub/domain/GHCR values changed by #27; any actual distribution rename is separate follow-up work.

## Consequences

### Positive

- Marka becomes coherent across the actively operated public web, repository, image, and documentation surfaces.
- The production image path and repository name match the public product name.
- The cutover remains small enough to reason about and validate as one controlled operation.
- Compatibility-sensitive internal identifiers are not churned merely for aesthetics.

### Negative

- The codebase will temporarily contain intentional internal `karakeep` names after the public cutover.
- Historical GHCR images remain under the old package path.
- A later #35 migration may still be substantial because it must treat internal identifiers as compatibility-sensitive rather than performing blind string replacement.

## Verification requirement

The implementation plan for #27 must prove, before completion, that:

1. `absolutepraya/marka` is the canonical repository and fresh Git operations use it.
2. CI publishes paired Marka `web-main` and `workers-main` images and no longer publishes new fork images under the old package path.
3. Production actually runs the Marka images and Watchtower follows the new tags.
4. `https://marka.abhipraya.dev` works directly, including auth and core application/background-worker behavior.
5. New public/share/RSS URLs use the Marka origin.
6. `keep.abhipraya.dev` redirects to the equivalent Marka path/query once the new origin is proven healthy.
7. Current repository/docs/public metadata no longer use obsolete active identities except where intentionally historical/upstream/internal.
8. The pre-cutover production backup exists on the implementation MacBook and was verified before production mutation.
6 changes: 3 additions & 3 deletions docs/ai-code-review.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ A future reviewer must satisfy all of the following before it is approved for on

### Repository scope

- install only for `absolutepraya/karakeep`, not all repositories on the account;
- install only for `absolutepraya/marka`, not all repositories on the account;
- review non-draft pull requests targeting `main` where the service supports scope controls;
- avoid wasting review quota on generated output and pure dependency-bot PRs where controls exist.

Expand Down Expand Up @@ -184,7 +184,7 @@ Current accepted example:
For any future candidate:

1. Confirm current official pricing/free-tier terms.
2. Confirm the App can be scoped only to `absolutepraya/karakeep`.
2. Confirm the App can be scoped only to `absolutepraya/marka`.
3. Inspect the exact GitHub App permissions before treating the integration as accepted.
4. Reject contents-write, Actions/workflows-write, administration, secrets/environment, or equivalent mutation capability.
5. Enable review-only behavior only.
Expand All @@ -202,4 +202,4 @@ The complete decision history and evaluation are preserved in:
- `docs/superpowers/plans/2026-08-15-ai-reviewer-army.md`
- `docs/superpowers/plans/2026-08-15-ai-reviewer-army-live-rollout.md`

Vendor behavior changes over time. Re-check official vendor documentation before reconsidering a rejected integration.
Vendor behavior changes over time. Re-check official vendor documentation before reconsidering a rejected integration.
2 changes: 1 addition & 1 deletion docs/docs/01-getting-started/01-intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Karakeep is a self-hostable bookmark-everything app for saving links, notes, ima

> These docs primarily describe **Karakeep itself**. This repository is a personal fork of upstream Karakeep, so fork-specific development and deployment notes also live in the repo docs: `README.md`, `CONTRIBUTING.md`, and `docs/fork-setup.md`.

![Screenshot](https://raw.githubusercontent.com/absolutepraya/karakeep/main/screenshots/homepage.png)
![Screenshot](https://raw.githubusercontent.com/absolutepraya/marka/main/screenshots/homepage.png)

## What Karakeep can do

Expand Down
4 changes: 2 additions & 2 deletions docs/docs/02-installation/01-docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ mkdir karakeep-app

### 2. Download the compose file

Download the docker compose file provided [here](https://github.com/absolutepraya/karakeep/blob/main/docker/docker-compose.yml) directly into your new directory.
Download the [Docker Compose file](https://github.com/absolutepraya/marka/blob/main/docker/docker-compose.yml) directly into your new directory.

```
wget https://raw.githubusercontent.com/absolutepraya/karakeep/main/docker/docker-compose.yml
wget https://raw.githubusercontent.com/absolutepraya/marka/main/docker/docker-compose.yml
```

### 3. Populate the environment variables
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/02-installation/02-unraid.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Docker Compose Manager Plugin (Recommended)

You can use [Docker Compose Manager](https://forums.unraid.net/topic/114415-plugin-docker-compose-manager/) plugin to deploy Karakeep using the official docker compose file provided [here](https://github.com/absolutepraya/karakeep/blob/main/docker/docker-compose.yml). After creating the stack, you'll need to setup some env variables similar to that from the docker compose installation docs [here](/installation/docker#3-populate-the-environment-variables).
You can use [Docker Compose Manager](https://forums.unraid.net/topic/114415-plugin-docker-compose-manager/) plugin to deploy Karakeep using the official [Marka fork's Docker Compose file](https://github.com/absolutepraya/marka/blob/main/docker/docker-compose.yml). After creating the stack, you'll need to setup some env variables similar to that from the [Docker Compose installation docs](/installation/docker#3-populate-the-environment-variables).

## Community Apps

Expand Down
6 changes: 3 additions & 3 deletions docs/docs/02-installation/06-debuntu.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ The script will download and install all dependencies (except for Ollama), insta

The script functions as an update script in addition to an installer. See **[Updating](#updating)**.

### 1. Download the script from the [Karakeep repository](https://github.com/absolutepraya/karakeep/blob/main/karakeep-linux.sh)
### 1. Download the script from the [Marka fork repository](https://github.com/absolutepraya/marka/blob/main/karakeep-linux.sh)

```
wget https://raw.githubusercontent.com/absolutepraya/karakeep/main/karakeep-linux.sh
```bash
wget https://raw.githubusercontent.com/absolutepraya/marka/main/karakeep-linux.sh
```

### 2. Run the script
Expand Down
10 changes: 5 additions & 5 deletions docs/docs/02-installation/11-guided-docker-setup.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Guided Docker Setup for This Fork

:::info Fork-specific setup
This page documents the guided setup shipped by `absolutepraya/karakeep`. It is not the upstream Karakeep setup flow.
This page documents the guided setup shipped by `absolutepraya/marka`. It is not the upstream Karakeep setup flow.
:::

The guided script creates a Docker Compose deployment without installing system packages, changing firewall rules, configuring DNS, or provisioning TLS. Docker Engine, Docker Compose v2, and OpenSSL must already be installed on a Linux `amd64` host.
Expand All @@ -11,15 +11,15 @@ The guided script creates a Docker Compose deployment without installing system
Run the latest guided script from this fork:

```bash
curl -fsSLo /tmp/karakeep-setup.sh https://raw.githubusercontent.com/absolutepraya/karakeep/main/scripts/install.sh && bash /tmp/karakeep-setup.sh
curl -fsSLo /tmp/karakeep-setup.sh https://raw.githubusercontent.com/absolutepraya/marka/main/scripts/install.sh && bash /tmp/karakeep-setup.sh
```

The script is downloaded to a file before execution rather than piped directly into a shell. During setup it copies itself into the selected configuration directory, which defaults to `~/karakeep`.

For a reproducible setup, pin the download to an immutable release tag or commit SHA after reviewing that revision:

```bash
REF=<tag-or-commit-sha>; curl -fsSLo /tmp/karakeep-setup.sh "https://raw.githubusercontent.com/absolutepraya/karakeep/${REF}/scripts/install.sh" && bash /tmp/karakeep-setup.sh
REF=<tag-or-commit-sha>; curl -fsSLo /tmp/karakeep-setup.sh "https://raw.githubusercontent.com/absolutepraya/marka/${REF}/scripts/install.sh" && bash /tmp/karakeep-setup.sh
```

## Preflight checks
Expand Down Expand Up @@ -69,8 +69,8 @@ Fresh deployments always start with signups enabled so the first administrator a

The script uses the stable Compose project name `karakeep` and the paired fork images:

- `ghcr.io/absolutepraya/karakeep:web-main`
- `ghcr.io/absolutepraya/karakeep:workers-main`
- `ghcr.io/absolutepraya/marka:web-main`
- `ghcr.io/absolutepraya/marka:workers-main`

A default fully featured installation runs four containers:

Expand Down
Loading
Loading