OpenLogs

All tools

Linkwarden

Bookmark manager that saves pages and organizes links into collections.

Replaces

Paid read-later services, such as Pocket.

All open-source alternatives to Pocket

Difficulty

Difficulty: Medium

3 services (2 database or broker: postgres, meilisearch), 3 volume mounts, 2 env values to set, no elevated host access. Heuristic score 5 of 11: medium.

Stack

TypeScript (language), PostgreSQL (database)

Deployment

docker_compose

Requirements

Not stated.

License

AGPL-3.0 (OSI-approved open source)

Read from github.com/linkwarden/linkwarden/blob/952ac45/LICENSE.md

Business model

Unknown

The README at the pinned commit does not state a business model, so it stays unknown.

Source: github.com/linkwarden/linkwarden/blob/952ac45/README.md, read on .

Repository

linkwarden/linkwarden

GitHub stats

Stars
20,176
Forks
874
Open issues and pull requests
688
Last push
2026-10-19
Latest release
v2.16.3
Released
2026-09-09

From the GitHub API on . These numbers are a snapshot, not live. GitHub detected the license as AGPL-3.0.

Compose file

Config check passed docker compose config exited 0 on this exact file on 2026-10-22.
docker-compose.yml Version 1
services:
  postgres:
    image: postgres:16-alpine
    env_file: .env
    restart: always
    volumes:
      - ./pgdata:/var/lib/postgresql/data
  linkwarden:
    env_file: .env
    environment:
      - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/postgres
    restart: always
    image: ghcr.io/linkwarden/linkwarden:latest
    ports:
      - 3000:3000
    volumes:
      - ./data:/data/data
    depends_on:
      - postgres
      - meilisearch
  meilisearch:
    image: getmeili/meilisearch:v1.13.3
    restart: always
    env_file:
      - .env
    volumes:
      - ./meili_data:/meili_data

From the app's own repository: github.com/linkwarden/linkwarden/blob/952ac45/docker-compose.yml.

Compose file from the app repository.

Install

  1. Docker with the Compose plugin (github.com/linkwarden/docs/blob/53e2dce/docs/self-hosting/setup.md)

    A host with Docker and the Docker Compose plugin. This entry runs from a compose file.

  2. Save the compose file as docker-compose.yml (github.com/linkwarden/linkwarden/blob/952ac45/docker-compose.yml)

    Use the compose file shown above.

  3. Save as .env next to the compose file (github.com/linkwarden/linkwarden/blob/952ac45/.env.sample)
    # Full list of environment variables with descriptions can be found in the documentation: https://docs.linkwarden.app/self-hosting/environment-variables
    
    NEXTAUTH_URL=http://localhost:3000/api/v1/auth
    NEXTAUTH_SECRET=
    
    # Manual installation database settings
    # Example: DATABASE_URL=postgresql://user:password@localhost:5432/linkwarden
    DATABASE_URL=
    
    # Docker installation database settings
    POSTGRES_PASSWORD=
    
    # Additional Optional Settings
    PAGINATION_TAKE_COUNT=
    STORAGE_FOLDER=
    AUTOSCROLL_TIMEOUT=
    NEXT_PUBLIC_DISABLE_REGISTRATION=
    NEXT_PUBLIC_CREDENTIALS_ENABLED=
    DISABLE_NEW_SSO_USERS=
    MAX_LINKS_PER_USER=
    ARCHIVE_TAKE_COUNT=
    BROWSER_TIMEOUT=
    BROWSER_LIFECYCLE=
    IGNORE_URL_SIZE_LIMIT=
    NEXT_PUBLIC_DEMO=
    NEXT_PUBLIC_DEMO_USERNAME=
    NEXT_PUBLIC_DEMO_PASSWORD=
    NEXT_PUBLIC_ADMIN=
    NEXT_PUBLIC_MAX_FILE_BUFFER=
    PDF_MAX_BUFFER=
    SCREENSHOT_MAX_BUFFER=
    READABILITY_MAX_BUFFER=
    PREVIEW_MAX_BUFFER=
    MONOLITH_MAX_BUFFER=
    MONOLITH_CUSTOM_OPTIONS=
    IMPORT_LIMIT=
    PLAYWRIGHT_LAUNCH_OPTIONS_EXECUTABLE_PATH=
    PLAYWRIGHT_WS_URL=
    MAX_WORKERS=
    DISABLE_BROWSER=
    NEXT_PUBLIC_RSS_POLLING_INTERVAL_MINUTES=
    RSS_SUBSCRIPTION_LIMIT_PER_USER=
    TEXT_CONTENT_LIMIT=
    SEARCH_FILTER_LIMIT=
    INDEX_TAKE_COUNT=
    MEILI_TIMEOUT=
    ALLOW_PRIVATE_NETWORK_ACCESS=
    ALLOW_INSECURE_TLS=
    NEXT_PUBLIC_USER_CONTENT_DOMAIN=
    NEXT_PUBLIC_MOBILE_APP_REDIRECT_ENABLED=
    
    # AI Settings
    NEXT_PUBLIC_OLLAMA_ENDPOINT_URL=
    OLLAMA_MODEL=
    
    # https://ai-sdk.dev/providers/openai-compatible-providers
    OPENAI_API_KEY=
    OPENAI_MODEL=
    # Optional: Set a custom OpenAI base URL and name (for third-party providers)
    CUSTOM_OPENAI_BASE_URL=
    CUSTOM_OPENAI_NAME=
    
    # https://sdk.vercel.ai/providers/ai-sdk-providers/azure
    AZURE_API_KEY=
    AZURE_RESOURCE_NAME=
    AZURE_MODEL=
    
    # https://sdk.vercel.ai/providers/ai-sdk-providers/anthropic
    ANTHROPIC_API_KEY=
    ANTHROPIC_MODEL=
    
    # https://github.com/OpenRouterTeam/ai-sdk-provider
    OPENROUTER_API_KEY=
    OPENROUTER_MODEL=
    
    # https://ai-sdk.dev/providers/ai-sdk-providers/perplexity
    PERPLEXITY_API_KEY=
    PERPLEXITY_MODEL=
    
    # MeiliSearch Settings
    MEILI_HOST=
    MEILI_MASTER_KEY=
    
    # AWS S3 Settings
    SPACES_KEY=
    SPACES_SECRET=
    SPACES_ENDPOINT=
    SPACES_BUCKET_NAME=
    SPACES_REGION=
    SPACES_FORCE_PATH_STYLE=
    
    # SMTP Settings
    NEXT_PUBLIC_EMAIL_PROVIDER=
    EMAIL_FROM=
    EMAIL_SERVER=
    BASE_URL=
    
    # Proxy settings
    PROXY=
    PROXY_USERNAME=
    PROXY_PASSWORD=
    PROXY_BYPASS=
    
    # PDF archive settings
    PDF_MARGIN_TOP=
    PDF_MARGIN_BOTTOM=
    
    #################
    # SSO Providers #
    #################
    
    # 42 School
    NEXT_PUBLIC_FORTYTWO_ENABLED=
    FORTYTWO_CUSTOM_NAME=
    FORTYTWO_CLIENT_ID=
    FORTYTWO_CLIENT_SECRET=
    
    # Apple
    NEXT_PUBLIC_APPLE_ENABLED=
    APPLE_CUSTOM_NAME=
    APPLE_CLIENT_ID=
    APPLE_TEAM_ID=
    APPLE_KEY_ID=
    APPLE_PRIVATE_KEY=
    APPLE_CLIENT_SECRET=
    
    # Atlassian
    NEXT_PUBLIC_ATLASSIAN_ENABLED=
    ATLASSIAN_CUSTOM_NAME=
    ATLASSIAN_CLIENT_ID=
    ATLASSIAN_CLIENT_SECRET=
    ATLASSIAN_SCOPE=
    
    # Auth0
    NEXT_PUBLIC_AUTH0_ENABLED=
    AUTH0_CUSTOM_NAME=
    AUTH0_ISSUER=
    AUTH0_CLIENT_SECRET=
    AUTH0_CLIENT_ID=
    
    # Authelia
    NEXT_PUBLIC_AUTHELIA_ENABLED=
    AUTHELIA_CLIENT_ID=
    AUTHELIA_CLIENT_SECRET=
    AUTHELIA_WELLKNOWN_URL=
    
    # Authentik
    NEXT_PUBLIC_AUTHENTIK_ENABLED=
    AUTHENTIK_CUSTOM_NAME=
    AUTHENTIK_ISSUER=
    AUTHENTIK_CLIENT_ID=
    AUTHENTIK_CLIENT_SECRET=
    
    # Azure AD B2C
    NEXT_PUBLIC_AZURE_AD_B2C_ENABLED=
    AZURE_AD_B2C_TENANT_NAME=
    AZURE_AD_B2C_CLIENT_ID=
    AZURE_AD_B2C_CLIENT_SECRET=
    AZURE_AD_B2C_PRIMARY_USER_FLOW=
    
    # Azure AD
    NEXT_PUBLIC_AZURE_AD_ENABLED=
    AZURE_AD_CLIENT_ID=
    AZURE_AD_CLIENT_SECRET=
    AZURE_AD_TENANT_ID=
    
    # Battle.net
    NEXT_PUBLIC_BATTLENET_ENABLED=
    BATTLENET_CUSTOM_NAME=
    BATTLENET_CLIENT_ID=
    BATTLENET_CLIENT_SECRET=
    BATTLENET_ISSUER=
    
    # Box
    NEXT_PUBLIC_BOX_ENABLED=
    BOX_CUSTOM_NAME=
    BOX_CLIENT_ID=
    BOX_CLIENT_SECRET=
    
    # Bungie
    NEXT_PUBLIC_BUNGIE_ENABLED=
    BUNGIE_CUSTOM_NAME=
    BUNGIE_CLIENT_ID=
    BUNGIE_CLIENT_SECRET=
    BUNGIE_API_KEY=
    
    # Cognito
    NEXT_PUBLIC_COGNITO_ENABLED=
    COGNITO_CUSTOM_NAME=
    COGNITO_CLIENT_ID=
    COGNITO_CLIENT_SECRET=
    COGNITO_ISSUER=
    
    # Coinbase
    NEXT_PUBLIC_COINBASE_ENABLED=
    COINBASE_CUSTOM_NAME=
    COINBASE_CLIENT_ID=
    COINBASE_CLIENT_SECRET=
    
    # Discord
    NEXT_PUBLIC_DISCORD_ENABLED=
    DISCORD_CUSTOM_NAME=
    DISCORD_CLIENT_ID=
    DISCORD_CLIENT_SECRET=
    
    # Dropbox
    NEXT_PUBLIC_DROPBOX_ENABLED=
    DROPBOX_CUSTOM_NAME=
    DROPBOX_CLIENT_ID=
    DROPBOX_CLIENT_SECRET=
    
    # DuendeIndentityServer6
    NEXT_PUBLIC_DUENDE_IDS6_ENABLED=
    DUENDE_IDS6_CUSTOM_NAME=
    DUENDE_IDS6_CLIENT_ID=
    DUENDE_IDS6_CLIENT_SECRET=
    DUENDE_IDS6_ISSUER=
    
    # EVE Online
    NEXT_PUBLIC_EVEONLINE_ENABLED=
    EVEONLINE_CUSTOM_NAME=
    EVEONLINE_CLIENT_ID=
    EVEONLINE_CLIENT_SECRET=
    
    # Facebook
    NEXT_PUBLIC_FACEBOOK_ENABLED=
    FACEBOOK_CUSTOM_NAME=
    FACEBOOK_CLIENT_ID=
    FACEBOOK_CLIENT_SECRET=
    
    # FACEIT
    NEXT_PUBLIC_FACEIT_ENABLED=
    FACEIT_CUSTOM_NAME=
    FACEIT_CLIENT_ID=
    FACEIT_CLIENT_SECRET=
    
    # Foursquare
    NEXT_PUBLIC_FOURSQUARE_ENABLED=
    FOURSQUARE_CUSTOM_NAME=
    FOURSQUARE_CLIENT_ID=
    FOURSQUARE_CLIENT_SECRET=
    FOURSQUARE_APIVERSION=
    
    # Freshbooks
    NEXT_PUBLIC_FRESHBOOKS_ENABLED=
    FRESHBOOKS_CUSTOM_NAME=
    FRESHBOOKS_CLIENT_ID=
    FRESHBOOKS_CLIENT_SECRET=
    
    # FusionAuth
    NEXT_PUBLIC_FUSIONAUTH_ENABLED=
    FUSIONAUTH_CUSTOM_NAME=
    FUSIONAUTH_CLIENT_ID=
    FUSIONAUTH_CLIENT_SECRET=
    FUSIONAUTH_ISSUER=
    FUSIONAUTH_TENANT_ID=
    
    # GitHub
    NEXT_PUBLIC_GITHUB_ENABLED=
    GITHUB_CUSTOM_NAME=
    GITHUB_ID=
    GITHUB_SECRET=
    
    # GitLab
    NEXT_PUBLIC_GITLAB_ENABLED=
    GITLAB_CUSTOM_NAME=
    GITLAB_CLIENT_ID=
    GITLAB_CLIENT_SECRET=
    GITLAB_AUTH_URL=
    
    # Google
    NEXT_PUBLIC_GOOGLE_ENABLED=
    GOOGLE_CUSTOM_NAME=
    GOOGLE_CLIENT_ID=
    GOOGLE_CLIENT_SECRET=
    
    # HubSpot
    NEXT_PUBLIC_HUBSPOT_ENABLED=
    HUBSPOT_CUSTOM_NAME=
    HUBSPOT_CLIENT_ID=
    HUBSPOT_CLIENT_SECRET=
    
    # IdentityServer4
    NEXT_PUBLIC_IDS4_ENABLED=
    IDS4_CUSTOM_NAME=
    IDS4_CLIENT_ID=
    IDS4_CLIENT_SECRET=
    IDS4_ISSUER=
    
    # Kakao
    NEXT_PUBLIC_KAKAO_ENABLED=
    KAKAO_CUSTOM_NAME=
    KAKAO_CLIENT_ID=
    KAKAO_CLIENT_SECRET=
    
    # Keycloak
    NEXT_PUBLIC_KEYCLOAK_ENABLED=
    KEYCLOAK_CUSTOM_NAME=
    KEYCLOAK_ISSUER=
    KEYCLOAK_CLIENT_ID=
    KEYCLOAK_CLIENT_SECRET=
    
    # LINE
    NEXT_PUBLIC_LINE_ENABLED=
    LINE_CUSTOM_NAME=
    LINE_CLIENT_ID=
    LINE_CLIENT_SECRET=
    
    # LinkedIn
    NEXT_PUBLIC_LINKEDIN_ENABLED=
    LINKEDIN_CUSTOM_NAME=
    LINKEDIN_CLIENT_ID=
    LINKEDIN_CLIENT_SECRET=
    
    # Mailchimp
    NEXT_PUBLIC_MAILCHIMP_ENABLED=
    MAILCHIMP_CUSTOM_NAME=
    MAILCHIMP_CLIENT_ID=
    MAILCHIMP_CLIENT_SECRET=
    
    # Mail.ru
    NEXT_PUBLIC_MAILRU_ENABLED=
    MAILRU_CUSTOM_NAME=
    MAILRU_CLIENT_ID=
    MAILRU_CLIENT_SECRET=
    
    # Naver
    NEXT_PUBLIC_NAVER_ENABLED=
    NAVER_CUSTOM_NAME=
    NAVER_CLIENT_ID=
    NAVER_CLIENT_SECRET=
    
    # Netlify
    NEXT_PUBLIC_NETLIFY_ENABLED=
    NETLIFY_CUSTOM_NAME=
    NETLIFY_CLIENT_ID=
    NETLIFY_CLIENT_SECRET=
    
    # Okta
    NEXT_PUBLIC_OKTA_ENABLED=
    OKTA_CUSTOM_NAME=
    OKTA_CLIENT_ID=
    OKTA_CLIENT_SECRET=
    OKTA_ISSUER=
    
    # OneLogin
    NEXT_PUBLIC_ONELOGIN_ENABLED=
    ONELOGIN_CUSTOM_NAME=
    ONELOGIN_CLIENT_ID=
    ONELOGIN_CLIENT_SECRET=
    ONELOGIN_ISSUER=
    
    # Osso
    NEXT_PUBLIC_OSSO_ENABLED=
    OSSO_CUSTOM_NAME=
    OSSO_CLIENT_ID=
    OSSO_CLIENT_SECRET=
    OSSO_ISSUER=
    
    # osu!
    NEXT_PUBLIC_OSU_ENABLED=
    OSU_CUSTOM_NAME=
    OSU_CLIENT_ID=
    OSU_CLIENT_SECRET=
    
    # Patreon
    NEXT_PUBLIC_PATREON_ENABLED=
    PATREON_CUSTOM_NAME=
    PATREON_CLIENT_ID=
    PATREON_CLIENT_SECRET=
    
    # Pinterest
    NEXT_PUBLIC_PINTEREST_ENABLED=
    PINTEREST_CUSTOM_NAME=
    PINTEREST_CLIENT_ID=
    PINTEREST_CLIENT_SECRET=
    
    # Pipedrive
    NEXT_PUBLIC_PIPEDRIVE_ENABLED=
    PIPEDRIVE_CUSTOM_NAME=
    PIPEDRIVE_CLIENT_ID=
    PIPEDRIVE_CLIENT_SECRET=
    
    # Reddit
    NEXT_PUBLIC_REDDIT_ENABLED=
    REDDIT_CUSTOM_NAME=
    REDDIT_CLIENT_ID=
    REDDIT_CLIENT_SECRET=
    
    # Salesforce
    NEXT_PUBLIC_SALESFORCE_ENABLED=
    SALESFORCE_CUSTOM_NAME=
    SALESFORCE_CLIENT_ID=
    SALESFORCE_CLIENT_SECRET=
    
    # Slack
    NEXT_PUBLIC_SLACK_ENABLED=
    SLACK_CUSTOM_NAME=
    SLACK_CLIENT_ID=
    SLACK_CLIENT_SECRET=
    
    # Spotify
    NEXT_PUBLIC_SPOTIFY_ENABLED=
    SPOTIFY_CUSTOM_NAME=
    SPOTIFY_CLIENT_ID=
    SPOTIFY_CLIENT_SECRET=
    
    # Strava
    NEXT_PUBLIC_STRAVA_ENABLED=
    STRAVA_CUSTOM_NAME=
    STRAVA_CLIENT_ID=
    STRAVA_CLIENT_SECRET=
    
    # Synology
    NEXT_PUBLIC_SYNOLOGY_ENABLED=
    SYNOLOGY_CUSTOM_NAME=
    SYNOLOGY_CLIENT_ID=
    SYNOLOGY_CLIENT_SECRET=
    SYNOLOGY_WELLKNOWN_URL=
    
    # Todoist
    NEXT_PUBLIC_TODOIST_ENABLED=
    TODOIST_CUSTOM_NAME=
    TODOIST_CLIENT_ID=
    TODOIST_CLIENT_SECRET=
    
    # Twitch
    NEXT_PUBLIC_TWITCH_ENABLED=
    TWITCH_CUSTOM_NAME=
    TWITCH_CLIENT_ID=
    TWITCH_CLIENT_SECRET=
    
    # United Effects
    NEXT_PUBLIC_UNITED_EFFECTS_ENABLED=
    UNITED_EFFECTS_CUSTOM_NAME=
    UNITED_EFFECTS_CLIENT_ID=
    UNITED_EFFECTS_CLIENT_SECRET=
    UNITED_EFFECTS_ISSUER=
    
    # VK
    NEXT_PUBLIC_VK_ENABLED=
    VK_CUSTOM_NAME=
    VK_CLIENT_ID=
    VK_CLIENT_SECRET=
    
    # Wikimedia
    NEXT_PUBLIC_WIKIMEDIA_ENABLED=
    WIKIMEDIA_CUSTOM_NAME=
    WIKIMEDIA_CLIENT_ID=
    WIKIMEDIA_CLIENT_SECRET=
    
    # Wordpress.com
    NEXT_PUBLIC_WORDPRESS_ENABLED=
    WORDPRESS_CUSTOM_NAME=
    WORDPRESS_CLIENT_ID=
    WORDPRESS_CLIENT_SECRET=
    
    # Yandex
    NEXT_PUBLIC_YANDEX_ENABLED=
    YANDEX_CUSTOM_NAME=
    YANDEX_CLIENT_ID=
    YANDEX_CLIENT_SECRET=
    
    # Zitadel
    NEXT_PUBLIC_ZITADEL_ENABLED=
    ZITADEL_CUSTOM_NAME=
    ZITADEL_CLIENT_ID=
    ZITADEL_CLIENT_SECRET=
    ZITADEL_ISSUER=
    
    # Zoho
    NEXT_PUBLIC_ZOHO_ENABLED=
    ZOHO_CUSTOM_NAME=
    ZOHO_CLIENT_ID=
    ZOHO_CLIENT_SECRET=
    
    # Zoom
    NEXT_PUBLIC_ZOOM_ENABLED=
    ZOOM_CUSTOM_NAME=
    ZOOM_CLIENT_ID=
    ZOOM_CLIENT_SECRET=
    
    # Generic OIDC
    NEXT_PUBLIC_OIDC_ENABLED=
    OIDC_CUSTOM_NAME=
    OIDC_WELLKNOWN_URL=
    OIDC_CLIENT_ID=
    OIDC_CLIENT_SECRET=
    OIDC_SCOPES=
    
  4. What the compose file check ran with (github.com/linkwarden/docs/blob/53e2dce/docs/self-hosting/setup.md)

    The compose file check ran together with .env.sample from the same commit, saved as .env. The folder held only these files. The self-hosting guide tells the reader to download docker-compose.yml and .env.sample (saved as .env), change the secrets and run docker compose up.

  5. Start it (github.com/linkwarden/docs/blob/53e2dce/docs/self-hosting/setup.md)
    docker compose up -d
  6. Open the app (github.com/linkwarden/linkwarden/blob/952ac45/docker-compose.yml)

    Open http://localhost:3000. The compose file publishes host port 3000 for the linkwarden service.

Compose file check: config_ok on 2026-10-22.

Gotchas and maintenance

Gotchas

Signals

  • Open issues and pull requests: 688
  • Last push: 2026-10-19 (3 days before this page was built)
  • Latest release: v2.16.3 on 2026-09-09 (43 days before this page was built)