Run Linkding as a Self-Hosted Bookmark Manager With Docker Compose
Stand up a clean private bookmark manager that is easy to back up, easy to proxy, and modest enough not to turn a simple personal knowledge tool into an infrastructure project.
How to deploy Linkding with Compose, persist its SQLite data, create the initial admin account, and proxy it without breaking host headers.
People who want a small self-hosted place for bookmarks, saved articles, and browser-extension captures without a heavy knowledge-management suite.
The easy mistake is forgetting the first-user setup or misconfiguring proxy headers so login and CSRF-protected actions fail in annoying ways.
Before you begin
- A Docker host with the Compose plugin.
- A private or authenticated hostname, such as
links.example.com. - A directory for persistent data.
- A plan for backups if the bookmarks matter.
Linkding's installation docs still describe Docker and Docker Compose as the primary deployment path. The project uses SQLite by default, stores
its data under /etc/linkding/data, and does not create an initial user for you unless you configure an automatic superuser option.
Step 1: Create the Compose files
Create the stack directory:
mkdir -p /opt/stacks/linkding/data
cd /opt/stacks/linkding
Save this as compose.yaml:
services:
linkding:
image: sissbruecker/linkding:latest
container_name: linkding
restart: unless-stopped
ports:
- 127.0.0.1:9090:9090
volumes:
- ./data:/etc/linkding/data
env_file:
- .env
Create a minimal .env:
LD_DISABLE_BACKGROUND_TASKS=False
The official docs provide an upstream docker-compose.yml and .env.sample. For a small local deployment, the simplified
pattern above is enough as long as the data path is persistent.
Step 2: Start Linkding and create the first user
Start the stack:
docker compose up -d
docker compose ps
Then create the initial superuser:
docker compose exec linkding python manage.py createsuperuser --username=joe --email=joe@example.com
The project docs are explicit here: the Docker image does not provide an initial user by default, so you must create one after setup unless you
intentionally use an automatic superuser option like LD_SUPERUSER_NAME.
Once the command completes, verify you can log in through the local bind before adding a reverse proxy.
Step 3: Put it behind Caddy or Nginx
A simple Caddy entry:
links.example.com {
reverse_proxy 127.0.0.1:9090
}
A minimal Nginx server block:
server {
listen 80;
server_name links.example.com;
location / {
proxy_pass http://127.0.0.1:9090;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Linkding's docs warn that reverse proxies may need to forward the correct Host header or configure
LD_CSRF_TRUSTED_ORIGINS when login or CSRF-protected requests fail.
Step 4: Operate and back it up
Routine checks:
docker compose ps
docker logs linkding --tail 50
ls -la /opt/stacks/linkding/data
For a small installation using SQLite, your backup boundary is straightforward: the data directory is the thing that matters. Protect it before upgrades and before experimenting with archiving-heavy features.
Step 5: Update the installation cleanly
Update Linkding by pulling the image and recreating the container against the same data directory:
cd /opt/stacks/linkding
docker compose pull
docker compose up -d
If you later switch to a different image variant, such as one that includes HTML snapshot archiving, review the extra disk and memory costs before making the change permanent.
Rollback notes
Linkding is easy to recover if you preserve the data mount. A rollback usually means restoring the previous image tag or putting the backed-up
/etc/linkding/data contents back in place.
If login fails after a proxy change, revert the proxy headers first before assuming the application data is damaged.
Troubleshooting
The app starts but you cannot log in.
Confirm you actually created the initial superuser and are reaching the same instance you initialized.
Login works locally but fails behind Nginx.
Forward the correct Host and X-Forwarded-Proto headers, or set LD_CSRF_TRUSTED_ORIGINS.
Bookmarks vanish after a rebuild.
Check that the data path is mounted to /etc/linkding/data and not left inside the container filesystem.
You want a full team wiki, not just bookmarks.
That is a different product category. Linkding is strongest when it stays a fast, focused bookmark manager.