Linkding is a minimal, fast bookmark manager that you host yourself. It stores bookmarks with tags and descriptions, offers quick search, and can save HTML snapshots of pages so they stay readable after the original disappears. In this tutorial you will run Linkding with Docker Compose on Ubuntu 24.04, publish it over HTTPS with Nginx, and connect the browser extension and the REST API.

Prerequisites

To follow this guide you need:

  • A server running Ubuntu 24.04 LTS, for example a CubePath VPS. 512 MB of RAM is enough for the standard image; plan for 1 GB if you enable HTML snapshots.
  • A non-root user with sudo privileges.
  • Docker Engine and the Docker Compose plugin installed from Docker's official repository.
  • A domain name with an A record pointing to your server. This guide uses bookmarks.your_domain.
  • Ports 80 and 443 reachable from the internet.

Step 1 - Creating the project directory

Linkding keeps its SQLite database, favicons and snapshots in a single data directory. SQLite is the default database and is fine even for large collections, so no separate database server is needed.

sudo mkdir -p /opt/linkding/data
cd /opt/linkding

Store the initial administrator credentials in a .env file. Replace your_user with the username you want; the password is generated randomly:

sudo tee /opt/linkding/.env > /dev/null <<EOF
LD_SUPERUSER_NAME=your_user
LD_SUPERUSER_PASSWORD=$(openssl rand -base64 18)
EOF
sudo chmod 600 /opt/linkding/.env
sudo cat /opt/linkding/.env

Write down the password that is printed; you will use it to log in.

Step 2 - Writing the Docker Compose file

Linkding publishes two image variants. sissbruecker/linkding:latest is the standard image. sissbruecker/linkding:latest-plus adds Chromium and the SingleFile tool so Linkding can store full HTML snapshots of bookmarked pages. This guide uses the plus image; switch to latest if you do not want snapshots and prefer a smaller image.

Create the Compose file:

sudo nano /opt/linkding/docker-compose.yml
services:
  linkding:
    image: sissbruecker/linkding:latest-plus
    restart: unless-stopped
    ports:
      - "127.0.0.1:9090:9090"
    env_file:
      - .env
    environment:
      LD_CSRF_TRUSTED_ORIGINS: https://bookmarks.your_domain
    volumes:
      - ./data:/etc/linkding/data

What these settings do:

  • env_file passes LD_SUPERUSER_NAME and LD_SUPERUSER_PASSWORD to the container. Linkding creates this administrator on first start if it does not exist yet.
  • LD_CSRF_TRUSTED_ORIGINS must contain the public HTTPS URL. Without it, logins and forms fail with a CSRF error once Linkding runs behind a TLS proxy.
  • The port is bound to 127.0.0.1, so Linkding is only reachable through Nginx. Ports published by Docker bypass UFW.

Start the container:

sudo docker compose up -d

Check that Linkding reports itself as healthy. It exposes a /health endpoint for this:

curl -s http://127.0.0.1:9090/health; echo
{"version": "1.41.0", "status": "healthy"}

Step 3 - Configuring Nginx and HTTPS

Install Nginx and Certbot and allow web traffic:

sudo apt update
sudo apt install nginx certbot python3-certbot-nginx
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'

Create the server block:

sudo nano /etc/nginx/sites-available/linkding
server {
    listen 80;
    listen [::]:80;
    server_name bookmarks.your_domain;

    client_max_body_size 20M;

    location / {
        proxy_pass http://127.0.0.1:9090;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

The larger client_max_body_size allows importing big bookmark files. Enable the site and reload Nginx:

sudo ln -s /etc/nginx/sites-available/linkding /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Obtain a certificate; Certbot also sets up the HTTP to HTTPS redirect:

sudo certbot --nginx -d bookmarks.your_domain

Open https://bookmarks.your_domain and log in with the credentials from Step 1.

Step 4 - Importing and adding bookmarks

If you have bookmarks in a browser or another service, export them in the Netscape HTML format (the standard "Export bookmarks to HTML" option in all major browsers). In Linkding, go to Settings > General, find the Import section, select the file and upload it. Folders from the browser are not kept, but tags present in the file are imported.

To add a bookmark manually, click Add bookmark, paste the URL, and Linkding fills in the title and description from the page. Add tags separated by spaces, then save.

Search from the box at the top of the bookmark list. A few useful patterns:

QueryMatches
docker composeBookmarks containing both words in the title, description, notes or URL
#linuxBookmarks tagged linux
#linux nginxBookmarks tagged linux that also contain nginx
!untaggedBookmarks without tags

You can also search from your browser's address bar. Add a custom search engine with the URL https://bookmarks.your_domain/bookmarks?q=%s and a keyword such as ld; typing ld nginx then opens the results directly.

Step 5 - Installing the browser extension

The official linkding extension is available for Firefox and Chromium-based browsers. It needs an API token:

  1. In Linkding, go to Settings > Integrations and copy the REST API token shown there.
  2. Install the extension and open its options.
  3. Set Base URL to https://bookmarks.your_domain and paste the token.
  4. Save; the extension tests the connection.

Clicking the extension icon on any page now opens a form with the title and description already filled in, and shows if the page is already bookmarked. The same Integrations page also offers a bookmarklet if you prefer not to install an extension.

Step 6 - Enabling HTML snapshots

With the plus image, Linkding can save a complete, self-contained HTML copy of each page you bookmark. Go to Settings > General and enable automatic HTML snapshots. From then on, each new bookmark is queued and archived in the background; existing bookmarks can be archived from their detail view.

Snapshots are stored under /opt/linkding/data/assets. Check that they are being created after adding a bookmark:

sudo ls -lh /opt/linkding/data/assets | tail -n 3

Each snapshot is typically a few hundred kilobytes to a few megabytes, so monitor disk usage if you bookmark a lot:

sudo du -sh /opt/linkding/data/assets

The same settings page also lets you link bookmarks to the Internet Archive instead of, or in addition to, local snapshots.

Step 7 - Using the REST API

The API uses the same token as the browser extension, sent in an Authorization: Token header. Set two variables for convenience (install jq with sudo apt install jq if needed):

TOKEN="your_api_token"
BASE="https://bookmarks.your_domain/api"

Create a bookmark with tags:

curl -s -X POST "$BASE/bookmarks/" \
  -H "Authorization: Token $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://nginx.org/en/docs/", "tag_names": ["nginx", "docs"]}' | jq '{id, url, tag_names}'
{
  "id": 42,
  "url": "https://nginx.org/en/docs/",
  "tag_names": [
    "docs",
    "nginx"
  ]
}

Search bookmarks with the same query syntax as the web interface:

curl -s -G "$BASE/bookmarks/" -H "Authorization: Token $TOKEN" --data-urlencode "q=#nginx" | jq '.results[] | {title, url}'

The list endpoint is paginated: the response includes count and a next URL, and you can pass limit and offset parameters.

Step 8 - Adding users and backing up

To create more accounts, log in as the administrator and open https://bookmarks.your_domain/admin/. In the Django admin, go to Users > Add user. Regular users have their own bookmarks and tags, and can share bookmarks with others if sharing is enabled in their settings.

For backups, the whole state is the data directory. Stop the container for a consistent copy of the SQLite database:

cd /opt/linkding
sudo docker compose stop
sudo tar -czf ~/linkding-backup-$(date +%F).tar.gz -C /opt/linkding data
sudo docker compose start

You can also export all bookmarks as a Netscape HTML file from Settings > General, which any browser or bookmark manager can import.

Troubleshooting

Logging in fails with "CSRF verification failed". LD_CSRF_TRUSTED_ORIGINS does not match the URL in your browser. It must include the scheme, as in https://bookmarks.your_domain. Fix it and run sudo docker compose up -d.

The browser extension cannot connect. Check that the base URL has no trailing path and uses https://, and that the token matches the one on Settings > Integrations. You can test the token directly with curl -s -H "Authorization: Token $TOKEN" https://bookmarks.your_domain/api/bookmarks/ | jq .count.

Snapshots stay pending or fail. Snapshots only work with the latest-plus image. Check the logs with sudo docker compose logs linkding; Chromium needs memory, so a server with less than 1 GB of RAM may kill the process.

Conclusion

You now run Linkding on Ubuntu 24.04 with Docker Compose, served over HTTPS by Nginx, with your bookmarks imported, the browser extension connected and page snapshots enabled. As next steps, schedule the backup commands with a systemd timer, invite other users, and use the REST API to save links automatically from your RSS reader or chat tools.