← Back to linkwarden

How to Deploy & Use linkwarden

Linkwarden Deployment and Usage Guide

1. Prerequisites

Software Requirements

  • Node.js 18.x or later
  • npm or yarn package manager
  • PostgreSQL database (version 12 or higher)
  • Redis (for session storage and caching)
  • Docker and Docker Compose (optional, for containerized deployment)
  • Git (for cloning the repository)

Optional Dependencies (for full functionality)

  • Playwright (for webpage archiving - installed automatically via npm)
  • Ollama, OpenAI API, Azure API, or Anthropic API key (for AI tagging features)
  • SMTP server or email service (for email authentication and notifications)
  • Wayback Machine (archive.org) integration (for link preservation)

Accounts Needed (Optional)

  • OAuth provider accounts (for SSO integration):
    • Apple, Auth0, Azure AD, Discord, Google, etc.
    • See the full list in apps/web/pages/api/v1/auth/[...nextauth].ts

2. Installation

Clone the Repository

git clone https://github.com/linkwarden/linkwarden.git
cd linkwarden

Install Dependencies

# Install root dependencies
npm install

# Install Playwright browsers (required for archiving)
npx playwright install

Database Setup

# Create PostgreSQL database (example)
createdb linkwarden

# Or using Docker
docker run --name linkwarden-db -e POSTGRES_PASSWORD=yourpassword -d postgres:15

3. Configuration

Environment Variables

Create a .env file in the root directory with the following variables:

Required Variables

# Database
DATABASE_URL="postgresql://username:password@localhost:5432/linkwarden"

# Redis
REDIS_URL="redis://localhost:6379"

# Next.js
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="your-secret-key-here"

# File Storage (local by default)
FILE_STORAGE_PATH="./data"

Email Configuration (Optional but recommended)

EMAIL_FROM="noreply@yourdomain.com"
EMAIL_SERVER="smtp://username:password@smtp.example.com:587"

Authentication Providers (Optional)

Enable any OAuth provider by setting its environment variables:

# Example for Google OAuth
NEXT_PUBLIC_GOOGLE_ENABLED="true"
GOOGLE_CLIENT_ID="your-client-id"
GOOGLE_CLIENT_SECRET="your-client-secret"
GOOGLE_CUSTOM_NAME="Google"  # Optional custom name

# Example for GitHub
NEXT_PUBLIC_GITHUB_ENABLED="true"
GITHUB_CLIENT_ID="your-client-id"
GITHUB_CLIENT_SECRET="your-client-secret"

AI Tagging (Optional)

# Choose one AI provider
NEXT_PUBLIC_OLLAMA_ENDPOINT_URL="http://localhost:11434"  # For local Ollama
OPENAI_API_KEY="your-openai-api-key"  # For OpenAI
AZURE_API_KEY="your-azure-api-key"    # For Azure OpenAI
ANTHROPIC_API_KEY="your-anthropic-api-key"  # For Anthropic

Archiving Configuration

# Browser timeout for archiving (in minutes)
BROWSER_TIMEOUT=5

# Disable preservation if needed
DISABLE_PRESERVATION="false"

# Wayback Machine integration
WAYBACK_MACHINE_ENABLED="true"

Application Limits

# Maximum links per user
MAX_LINKS_PER_USER=30000

Database Schema

Run database migrations:

# Generate Prisma client
npx prisma generate

# Apply migrations
npx prisma db push
# Or for production:
npx prisma migrate deploy

4. Build & Run

Development Mode

# Start the development server
npm run dev

# The application will be available at http://localhost:3000

Production Build

# Build the application
npm run build

# Start the production server
npm start

Worker Process (for archiving)

Linkwarden uses a worker process for background tasks like webpage archiving. In production, you need to run:

# Start the worker
npm run worker

Using Docker Compose (Simplified)

Create a docker-compose.yml file:

version: '3.8'

services:
  postgres:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: linkwarden_password
      POSTGRES_DB: linkwarden
    volumes:
      - postgres_data:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine

  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgresql://postgres:linkwarden_password@postgres:5432/linkwarden
      REDIS_URL: redis://redis:6379
      NEXTAUTH_URL: http://localhost:3000
      NEXTAUTH_SECRET: your-secret-key-here
    depends_on:
      - postgres
      - redis

volumes:
  postgres_data:

Build and run:

docker-compose up -d

5. Deployment

Platform Recommendations

VPS/Cloud Server (Recommended for full control)

  • DigitalOcean, Linode, AWS EC2, Google Cloud Compute
  • Requires manual setup of PostgreSQL, Redis, and Node.js
  • Use PM2 or systemd for process management

PM2 configuration example:

npm install -g pm2
pm2 start npm --name "linkwarden-web" -- start
pm2 start npm --name "linkwarden-worker" -- run worker
pm2 save
pm2 startup

Container Platforms

  • Docker with Docker Compose (simplest)
  • Kubernetes (for scalable deployments)
  • Railway, Render, Fly.io (platforms with good Node.js support)

Managed Database Options

  • Supabase (PostgreSQL with built-in authentication)
  • Neon, Aiven, AWS RDS (managed PostgreSQL)

Deployment Checklist

  1. Set up infrastructure:

    • PostgreSQL database
    • Redis instance
    • File storage (local disk or S3-compatible storage)
  2. Configure environment:

    • Set all required environment variables
    • Configure SSL/TLS certificates
    • Set up firewall rules (open ports 3000, 5432, 6379)
  3. Build and deploy:

    git pull origin main
    npm install
    npm run build
    npx prisma migrate deploy
    npm start
    
  4. Set up reverse proxy (recommended):

    • Use Nginx or Caddy as reverse proxy
    • Configure SSL with Let's Encrypt

Example Nginx configuration:

server {
    listen 80;
    server_name yourdomain.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name yourdomain.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

6. Troubleshooting

Common Issues and Solutions

Database Connection Issues

Error: P1001: Can't reach database server

# Solution:
1. Verify DATABASE_URL is correct
2. Check if PostgreSQL is running: `sudo systemctl status postgresql`
3. Verify firewall allows port 5432
4. Test connection: `psql DATABASE_URL`

Authentication Problems

# If email login doesn't work:
1. Verify EMAIL_FROM and EMAIL_SERVER are set
2. Check SMTP server credentials
3. Test email sending manually

# If OAuth providers don't appear:
1. Check if NEXT_PUBLIC_[PROVIDER]_ENABLED="true"
2. Verify client ID and secret are correct
3. Ensure callback URLs are configured in OAuth provider dashboard

Archiving Not Working

# If screenshots/PDFs aren't generated:
1. Check Playwright installation: `npx playwright install --with-deps`
2. Verify DISABLE_PRESERVATION="false"
3. Check browser timeout: BROWSER_TIMEOUT should be > 0
4. Look for errors in worker logs

File Upload Issues

# If file uploads fail:
1. Check FILE_STORAGE_PATH exists and is writable
2. Verify file size limits (default 50MB)
3. Check available disk space

Performance Issues

# Slow page loads:
1. Enable Redis caching
2. Check database indexes: `npx prisma studio`
3. Monitor worker process CPU/memory usage
4. Consider increasing BROWSER_TIMEOUT for complex pages

Mobile App Connection

# If mobile app can't connect to self-hosted instance:
1. Ensure your instance is publicly accessible
2. Configure CORS if needed
3. Use HTTPS for production (required by mobile apps)
4. Verify API endpoints are accessible

Logs and Debugging

# View application logs
npm run dev  # Development logs
pm2 logs linkwarden-web  # Production logs (if using PM2)
docker-compose logs -f  # Docker logs

# Check worker process logs
npm run worker  # Development
pm2 logs linkwarden-worker  # Production

# Database debugging
npx prisma studio  # GUI for database inspection

Getting Help