Linkwarden: Self-Hosted Bookmark Manager Setup
Deploy Linkwarden on Docker to save, organize, and archive web pages, with full-page screenshots, PDF snapshots, and tag-based organization.
Most bookmark managers are a graveyard. You save things, never organize them, can’t find them later, and the bookmarked page might not even exist anymore. Linkwarden is different in one key way: it archives what you save. When you bookmark a link, Linkwarden captures a screenshot, creates a PDF snapshot, and stores a readable text version. The link can go dead tomorrow and you still have the content.
It’s self-hosted, runs on Docker, has a browser extension, and supports collections and tags for organizing your library. If you’ve been frustrated with Pocket, Raindrop, or plain browser bookmarks, it’s worth ten minutes to try.
What Linkwarden Stores Per Link
When you save a URL:
- Screenshot — full-page visual capture
- PDF — printable/searchable version of the page
- Monolith — a single-file HTML archive (includes images, CSS — useful for complex pages)
- Readable — extracted article text without navigation or ads
Not every page archives perfectly — SPAs (single-page applications), pages behind logins, and dynamic content don’t always capture well. Static articles and documentation pages archive reliably.
Directory Setup
mkdir -p /opt/linkwarden/{data,nextcloud-data}
Docker Compose
Linkwarden uses Postgres for its database. Create /opt/linkwarden/docker-compose.yml:
services:
linkwarden:
image: ghcr.io/linkwarden/linkwarden:latest
container_name: linkwarden
environment:
- DATABASE_URL=postgresql://linkwarden:changeme@postgres:5432/linkwarden
- NEXTAUTH_SECRET=your_random_secret_here
- NEXTAUTH_URL=http://localhost:3000
- STORAGE_FOLDER=/data/data
- NEXT_PUBLIC_DISABLE_REGISTRATION=false
volumes:
- /opt/linkwarden/data:/data/data
ports:
- "3000:3000"
depends_on:
postgres:
condition: service_healthy
restart: unless-stopped
postgres:
image: postgres:16-alpine
container_name: linkwarden-postgres
environment:
- POSTGRES_USER=linkwarden
- POSTGRES_PASSWORD=changeme
- POSTGRES_DB=linkwarden
volumes:
- /opt/linkwarden/pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U linkwarden"]
interval: 5s
timeout: 5s
retries: 5
restart: unless-stopped
NEXTAUTH_SECRET — Generate a random string for this:
openssl rand -base64 36
NEXTAUTH_URL — The URL where Linkwarden is accessible. If you’re putting it behind a reverse proxy with a domain, update this to the full URL (e.g., https://links.yourdomain.com).
NEXT_PUBLIC_DISABLE_REGISTRATION=false — Allows new users to register. Once you’ve created your account, set this to true and redeploy.
changeme — Change the Postgres password to something real.
Start Linkwarden
cd /opt/linkwarden
docker compose up -d
First start takes a minute while the database initializes and migrations run. Access the web interface at http://YOUR_SERVER_IP:3000.
Initial Setup
Create your account at http://YOUR_SERVER_IP:3000/register. After registering, go back to your compose file and disable registration:
- NEXT_PUBLIC_DISABLE_REGISTRATION=true
docker compose up -d
Organizing Links
Collections are the top-level organizational unit — think folders. Create a collection for each topic area (e.g., “Homelab,” “Dev,” “Reading,” “Recipes”).
Tags are cross-cutting labels you can apply to any link regardless of collection. Use them for things like “to-read,” “important,” or topic tags that span multiple collections.
Pinned links appear at the top of your dashboard. Use them for links you access frequently.
Browser Extension
Linkwarden has a browser extension (Firefox and Chrome) that adds a one-click save button. When you click it, it shows a dialog to set the collection and tags before saving.
Install it from the extension marketplace and configure it:
- Click the extension icon
- Enter your Linkwarden URL
- Log in
After that, saving a page is one click and two optional fields.
AI Tagging (Optional)
Linkwarden supports automatic AI-based tag suggestions using OpenAI or Ollama (your local LLM). If you’re running Ollama on your homelab (the Ollama guide covers that), you can connect Linkwarden to it:
- OLLAMA_API_KEY=ollama
- OLLAMA_MODEL=llama3
- OLLAMA_URL=http://your-server-ip:11434
When you save a link, Ollama analyzes the content and suggests tags. It’s not magic, but it’s useful for links you save without taking the time to tag manually.
Searching Your Archive
The search bar searches across link titles, URLs, tags, and collections. With the readable text archive, it also searches the saved content of pages — not just the title you gave it.
Practically, this means if you saved a blog post about Docker networking six months ago and can’t remember what you called it, searching “overlay networks” finds it based on the article text.
Backups
Back up the data directory and database:
# Database dump
docker exec linkwarden-postgres pg_dump -U linkwarden linkwarden > /backup/linkwarden-db-$(date +%Y%m%d).sql
# Archive data (screenshots, PDFs, etc.)
tar -czf /backup/linkwarden-data-$(date +%Y%m%d).tar.gz /opt/linkwarden/data/
The data directory is the large one — it contains all your archived screenshots, PDFs, and readable copies. Size depends on how many links you’ve saved and their content type.
Updating
cd /opt/linkwarden
docker compose pull
docker compose up -d
Linkwarden handles database migrations automatically on startup. Check the Linkwarden releases for notable updates.
Why Not Just Use Browser Bookmarks
Browser bookmarks are fine for 20 links. At 200+, finding anything requires remembering exactly what you called something. At 500+, it’s a disaster. Linkwarden scales because you can search content, not just titles — and because the archive means the content is actually there even when the original page disappears.