name: linkwarden services: linkwarden: image: ghcr.io/linkwarden/linkwarden:v2.16.3 restart: unless-stopped depends_on: postgres: condition: service_healthy meilisearch: condition: service_healthy ports: - "127.0.0.1:${LINKWARDEN_PORT:-3000}:3000" environment: DATABASE_URL: postgresql://${POSTGRES_USER:-linkwarden}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-linkwarden} NEXTAUTH_SECRET: ${NEXTAUTH_SECRET} NEXTAUTH_URL: ${LINKWARDEN_URL:-https://links.example.com}/api/v1/auth BASE_URL: ${LINKWARDEN_URL:-https://links.example.com} NEXT_PUBLIC_DISABLE_REGISTRATION: ${NEXT_PUBLIC_DISABLE_REGISTRATION:-false} NEXT_PUBLIC_USER_CONTENT_DOMAIN: ${LINKWARDEN_USER_CONTENT_URL:-https://saved.example.net} MEILI_HOST: http://meilisearch:7700 MEILI_MASTER_KEY: ${MEILI_MASTER_KEY} ALLOW_PRIVATE_NETWORK_ACCESS: "false" ALLOW_INSECURE_TLS: "false" TZ: ${LINKWARDEN_TIME_ZONE:-Etc/UTC} volumes: - linkwarden-data:/data/data healthcheck: test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3000/').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"] interval: 30s timeout: 10s retries: 10 start_period: 120s security_opt: - no-new-privileges:true stop_grace_period: 60s postgres: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_DB: ${POSTGRES_DB:-linkwarden} POSTGRES_USER: ${POSTGRES_USER:-linkwarden} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_INITDB_ARGS: "--data-checksums" TZ: ${LINKWARDEN_TIME_ZONE:-Etc/UTC} volumes: - linkwarden-postgres:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-linkwarden} -d ${POSTGRES_DB:-linkwarden}"] interval: 10s timeout: 5s retries: 10 security_opt: - no-new-privileges:true stop_grace_period: 60s meilisearch: image: getmeili/meilisearch:v1.13.3 restart: unless-stopped environment: MEILI_ENV: production MEILI_NO_ANALYTICS: "true" MEILI_MASTER_KEY: ${MEILI_MASTER_KEY} volumes: - linkwarden-meilisearch:/meili_data healthcheck: test: ["CMD-SHELL", "curl --fail --silent http://127.0.0.1:7700/health | grep -q '\"status\":\"available\"'"] interval: 10s timeout: 5s retries: 15 security_opt: - no-new-privileges:true stop_grace_period: 60s volumes: linkwarden-data: name: ${LINKWARDEN_DATA_VOLUME:-linkwarden-data} linkwarden-postgres: name: ${LINKWARDEN_DB_VOLUME:-linkwarden-postgres} linkwarden-meilisearch: name: ${LINKWARDEN_MEILI_VOLUME:-linkwarden-meilisearch}