Cross-Browser Bookmark Sync.
Self-hosted server ยท Browser extension ยท PostgreSQL / MongoDB
| Category | Details |
|---|---|
| Sync | Bidirectional merge sync (push + pull), soft-delete propagation, auto-sync with periodic alarms and change listeners |
| Browsers | Chrome, Firefox, Edge, Brave, Opera, Vivaldi โ any Chromium MV3 or Firefox MV2 browser |
| Auth | JWT access + rotating refresh tokens with reuse detection, family-based revocation |
| 2FA | TOTP setup with QR code + manual secret, backup codes, enforced login challenge |
| Database | PostgreSQL (recommended) or MongoDB โ switchable via DB_PROVIDER |
| Security | OWASP-aligned: Helmet, rate limiting, bcrypt, HTTPS enforcement, encrypted 2FA secrets (AES-256-GCM) |
| Deployment | Docker multi-arch (amd64 + arm64), Docker Compose, or bare Node.js |
| UI Protection | Server URL locked behind identity verification, Clear Server requires TOTP/password |
docker run -d \
--name linknest \
-p 3000:3000 \
-e DB_PROVIDER=postgres \
-e POSTGRES_URL=postgresql://user:pass@your-db-host:5432/linknest \
-e JWT_SECRET=$(openssl rand -base64 32) \
-e REFRESH_JWT_SECRET=$(openssl rand -base64 32) \
-e TWO_FACTOR_CHALLENGE_SECRET=$(openssl rand -base64 32) \
-e TWO_FACTOR_ENCRYPTION_KEY=$(openssl rand -base64 32) \
-e REQUIRE_HTTPS=true \
-e CORS_ORIGINS=https://your-domain.com \
certyiknofetch/linknest:1.1
The image supports linux/amd64 and linux/arm64 (Apple Silicon, Raspberry Pi, AWS Graviton).
# Pull the latest
docker pull certyiknofetch/linknest:latest
# Or a specific version
docker pull certyiknofetch/linknest:1.1
Full stack with a bundled PostgreSQL instance:
git clone https://github.com/certyiknofetch/linknest.git
cd linknest
cp server/.env.example .env
Edit .env with your secrets (see Environment Variablesโ ), then:
docker compose up -d
docker-compose.yml:
services:
linknest:
image: certyiknofetch/linknest:1.1
container_name: linknest-server
restart: unless-stopped
ports:
- "3000:3000"
env_file: .env
environment:
- DB_PROVIDER=postgres
- POSTGRES_URL=postgresql://linknest:${POSTGRES_PASSWORD:-changeme}@db:5432/linknest
- POSTGRES_SSL=false
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
container_name: linknest-db
restart: unless-stopped
volumes:
- linknest_pgdata:/var/lib/postgresql/data
environment:
POSTGRES_USER: linknest
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme}
POSTGRES_DB: linknest
healthcheck:
test: ["CMD-SHELL", "pg_isready -U linknest -d linknest"]
interval: 10s
timeout: 5s
retries: 5
volumes:
linknest_pgdata:
Use this when you already have a PostgreSQL or MongoDB instance:
docker compose -f docker-compose.no-db.yml up -d
Set POSTGRES_URL or MONGODB_URI in your .env file pointing to your existing database.
Create a .env file from the example:
cp server/.env.example .env
| Variable | Required | Default | Description |
|---|---|---|---|
PORT | No | 3000 | Server listen port |
DB_PROVIDER | Yes | mongodb | Database type: postgres or mongodb |
POSTGRES_URL | If postgres | โ | PostgreSQL connection string |
POSTGRES_SSL | No | false | Enable SSL for PostgreSQL connection |
POSTGRES_SSL_REJECT_UNAUTHORIZED | No | false | Reject unauthorized SSL certificates |
MONGODB_URI | If mongodb | โ | MongoDB connection string |
JWT_SECRET | Yes | โ | Secret for signing access tokens |
ACCESS_JWT_EXPIRES_IN | No | 15m | Access token lifetime |
REFRESH_JWT_SECRET | Yes | โ | Secret for signing refresh tokens |
REFRESH_JWT_EXPIRES_IN | No | 30d | Refresh token lifetime |
TWO_FACTOR_CHALLENGE_SECRET | Yes | โ | Secret for 2FA challenge tokens |
TWO_FACTOR_CHALLENGE_EXPIRES_IN | No | 5m | 2FA challenge window |
TWO_FACTOR_ENCRYPTION_KEY | Yes | โ | AES-256-GCM key for TOTP secret encryption |
REQUIRE_HTTPS | No | true | Reject non-HTTPS requests (except localhost) |
CORS_ORIGINS | No | โ | Comma-separated allowed origins |
# Generate strong random secrets (run each one separately)
openssl rand -base64 32 # JWT_SECRET
openssl rand -base64 32 # REFRESH_JWT_SECRET
openssl rand -base64 32 # TWO_FACTOR_CHALLENGE_SECRET
openssl rand -base64 32 # TWO_FACTOR_ENCRYPTION_KEY
linknest-chrome.zipchrome://extensions/ (or edge://extensions/, etc.)linknest-firefox.zipabout:debugging#/runtime/this-firefoxmanifest.json from the extracted folderNote: Firefox temporary add-ons are removed on restart. For permanent installation, use
about:addonswith a signed.xpifile or use Firefox Developer Edition withxpinstall.signatures.requiredset tofalse.
# From the project root
rm -rf dist && mkdir -p dist/chromium dist/firefox
# Chromium
cp -R extension/. dist/chromium/
rm -f dist/chromium/manifest.firefox.json
(cd dist/chromium && zip -qr ../linknest-chromium.zip .)
# Firefox
cp -R extension/. dist/firefox/
cp extension/manifest.firefox.json dist/firefox/manifest.json
rm -f dist/firefox/manifest.firefox.json
(cd dist/firefox && zip -qr ../linknest-firefox.zip .)
If you're running LinkNest behind a reverse proxy:
linknest.yourdomain.comlinknest-server (Docker service name) or localhost3000Set in .env:
CORS_ORIGINS=https://linknest.yourdomain.com
REQUIRE_HTTPS=true
This project is open source and available under the terms specified in the LICENSEโ file.
For contributions, usage rights, and restrictions, please refer to the full license text in the repository.
Content type
Image
Digest
sha256:2d0564820โฆ
Size
54 MB
Last updated
7 months ago
docker pull certyiknofetch/linknest