Linkding es un gestor de marcadores autoalojado, rápido y minimalista: guarda enlaces con etiquetas y notas, permite buscarlos, marcarlos como pendientes de leer y compartirlos, y ofrece una extensión de navegador y una API REST. Funciona con SQLite y consume muy pocos recursos, así que puede convivir con otros servicios en el mismo servidor. En este tutorial instalarás Linkding con Docker Compose en Ubuntu 24.04, lo publicarás en tu dominio con Nginx y HTTPS, conectarás la extensión del navegador y probarás la API.
Requisitos previos
- Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath. Con 512 MB de RAM es suficiente.
- Un usuario no root con privilegios
sudo. - Docker Engine y el plugin Docker Compose instalados desde el repositorio oficial de Docker.
- Un subdominio (en esta guía,
links.tu_dominio) con un registro DNS A que apunte a la IP pública del servidor. - UFW activo con SSH permitido.
Paso 1: Preparar el directorio y las variables
Crea un directorio para el proyecto con una subcarpeta para los datos:
mkdir -p ~/linkding/data
cd ~/linkding
Linkding lee su configuración de variables de entorno que empiezan por LD_. Guárdalas en un archivo .env para no dejar la contraseña del administrador dentro del archivo de Compose:
nano ~/linkding/.env
LD_SUPERUSER_NAME=admin
LD_SUPERUSER_PASSWORD=your_strong_password
LD_CSRF_TRUSTED_ORIGINS=https://links.tu_dominio
Sustituye your_strong_password por una contraseña robusta y links.tu_dominio por tu subdominio real. Qué hace cada variable:
LD_SUPERUSER_NAMEyLD_SUPERUSER_PASSWORDcrean el usuario administrador en el primer arranque. Si el usuario ya existe, se ignoran.LD_CSRF_TRUSTED_ORIGINSes obligatoria cuando Linkding está detrás de un proxy con HTTPS. Sin ella, Django rechaza el inicio de sesión con un error403 CSRF verification failed.
Restringe los permisos del archivo:
chmod 600 ~/linkding/.env
Paso 2: Crear el archivo de Docker Compose
Crea compose.yaml en el mismo directorio:
nano ~/linkding/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
El puerto 9090 se publica solo en 127.0.0.1. Docker se salta las reglas de UFW para los puertos publicados, así que exponerlo en todas las interfaces dejaría Linkding accesible por HTTP sin cifrar. El acceso público irá por Nginx.
Notaexiste también la imagen
sissbruecker/linkding:latest-plus, que incluye Chromium y SingleFile para guardar una copia HTML completa de cada página. Ocupa bastante más y consume más memoria; úsala solo si quieres esas instantáneas locales.
Paso 3: Arrancar Linkding
Inicia el contenedor:
docker compose up -d
Comprueba que está en ejecución:
docker compose ps --format "table {{.Name}}\t{{.Status}}\t{{.Ports}}"
NAME STATUS PORTS
linkding Up 15 seconds 127.0.0.1:9090->9090/tcp
Verifica que la aplicación responde en local. La portada redirige a la página de inicio de sesión:
curl -sI http://127.0.0.1:9090 | head -n 1
HTTP/1.1 302 Found
La base de datos SQLite se crea en ~/linkding/data/db.sqlite3:
ls ~/linkding/data
Paso 4: Publicar Linkding con Nginx y HTTPS
Instala Nginx y Certbot:
sudo apt update
sudo apt install nginx certbot python3-certbot-nginx
Crea el bloque de servidor:
sudo nano /etc/nginx/sites-available/linkding
server {
listen 80;
listen [::]:80;
server_name links.tu_dominio;
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;
}
}
Activa el sitio, valida la configuración y recarga Nginx:
sudo ln -s /etc/nginx/sites-available/linkding /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Permite el tráfico web en UFW y solicita el certificado. Certbot añade la configuración TLS y la redirección de HTTP a HTTPS al mismo archivo:
sudo ufw allow 'Nginx Full'
sudo certbot --nginx -d links.tu_dominio
Congratulations! You have successfully enabled HTTPS on https://links.tu_dominio
Abre https://links.tu_dominio e inicia sesión con el usuario admin y la contraseña del archivo .env.
Paso 5: Configurar usuarios
Linkding no tiene registro público: todas las cuentas las crea un administrador. Puedes hacerlo desde el panel de administración de Django en https://links.tu_dominio/admin/ o desde la línea de comandos:
docker compose exec linkding python manage.py createsuperuser --username=ana --email=ana@tu_dominio
El comando pide la contraseña de forma interactiva. Para crear usuarios sin privilegios de administrador, usa el panel /admin/, entra en Users > Add user y deja sin marcar las casillas Staff status y Superuser status.
Si olvidas una contraseña, restablécela así:
docker compose exec linkding python manage.py changepassword admin
Paso 6: Instalar la extensión del navegador
La extensión oficial añade un botón para guardar la página actual con título, descripción y etiquetas. Está disponible para Firefox en Firefox Add-ons y para Chrome y navegadores basados en Chromium en la Chrome Web Store, en ambos casos con el nombre linkding extension.
Para configurarla necesitas un token de API:
- En Linkding, abre Settings > Integrations.
- Copia el valor de REST API (el token).
- En las opciones de la extensión, introduce la URL base
https://links.tu_dominioy el token. - Pulsa Test y guarda.
En la misma página de Integrations encontrarás un bookmarklet para navegadores donde no puedas instalar extensiones.
Paso 7: Etiquetas, búsqueda e importación
Al guardar un marcador, escribe las etiquetas separadas por espacios. Cada etiqueta se convierte en un filtro: haz clic en ella para ver todos los marcadores que la llevan.
La barra de búsqueda busca en título, descripción, notas y URL, y admite etiquetas con el prefijo #. Por ejemplo, docker #devops devuelve los marcadores que contienen «docker» y tienen la etiqueta devops. Linkding incluye además filtros para marcadores sin leer y sin etiquetar.
Para migrar desde el navegador o desde otro gestor, exporta tus marcadores en formato HTML de Netscape (el formato estándar de exportación de Firefox, Chrome o Pinboard) e impórtalos en Settings > General > Import. En la misma página, Export descarga todos tus marcadores en ese formato.
En Settings > General también puedes activar la creación automática de instantáneas en Internet Archive (Wayback Machine) para cada marcador nuevo, útil cuando una página desaparece.
Paso 8: Usar la API REST
La API permite automatizar altas y consultas. Guarda el token en una variable de la sesión para no repetirlo:
LD_TOKEN="your_api_token"
Crea un marcador con etiquetas:
curl -s -X POST https://links.tu_dominio/api/bookmarks/ \
-H "Authorization: Token $LD_TOKEN" \
-H "Content-Type: application/json" \
-d '{"url": "https://docs.docker.com/compose/", "title": "Docker Compose docs", "tag_names": ["docker", "docs"]}'
La respuesta es el marcador creado en JSON, con su id:
{"id":1,"url":"https://docs.docker.com/compose/","title":"Docker Compose docs",...,"tag_names":["docker","docs"],...}
Busca marcadores con los mismos operadores que en la interfaz. El parámetro q debe ir codificado en la URL (%23 es #):
curl -s "https://links.tu_dominio/api/bookmarks/?q=%23docker&limit=10" \
-H "Authorization: Token $LD_TOKEN"
Lista las etiquetas existentes:
curl -s https://links.tu_dominio/api/tags/ \
-H "Authorization: Token $LD_TOKEN"
Los listados están paginados: la respuesta incluye count, next y previous junto a results.
Paso 9: Actualizar y hacer copias de seguridad
Todos los datos (base de datos, favicons e instantáneas) están en ~/linkding/data. Para una copia consistente, detén el contenedor, empaqueta el directorio y vuelve a arrancarlo:
cd ~/linkding
docker compose stop
sudo tar -czf ~/linkding-backup-$(date +%F).tar.gz -C ~ linkding
docker compose start
Para actualizar, descarga la imagen nueva y recrea el contenedor. Las migraciones de base de datos se aplican solas al arrancar:
cd ~/linkding
docker compose pull
docker compose up -d
Para restaurar en otro servidor, extrae el archivo en el directorio personal y ejecuta docker compose up -d dentro de ~/linkding.
Solución de problemas
403 CSRF verification failed al iniciar sesión. LD_CSRF_TRUSTED_ORIGINS no coincide con la URL que usas, incluido el esquema (https://). Corrige el valor en .env y recrea el contenedor con docker compose up -d --force-recreate, ya que un simple reinicio no recarga el archivo .env.
La extensión responde con error de conexión. Comprueba el token con la API:
curl -s -o /dev/null -w "%{http_code}\n" https://links.tu_dominio/api/bookmarks/ -H "Authorization: Token $LD_TOKEN"
Un 200 indica que el token es válido; un 401 que es incorrecto o se ha regenerado.
502 Bad Gateway. Linkding no está escuchando en 127.0.0.1:9090. Revisa docker compose ps y los registros con docker compose logs linkding.
Conclusión
Linkding ya está funcionando en tu dominio con HTTPS, con usuarios gestionados por el administrador, la extensión del navegador conectada y la API lista para automatizaciones. Como siguientes pasos puedes importar tus marcadores actuales, programar la copia de seguridad del directorio data con un temporizador de systemd, o conectar la API con herramientas como n8n para guardar enlaces desde otras fuentes.
