← All articles
PRODUCTIVITY Self-Hosted Productivity Apps: Nextcloud, BookStack,... 2026-02-09 · 9 min read · productivity · nextcloud · bookstack

Self-Hosted Productivity Apps: Nextcloud, BookStack, Vikunja, and Paperless-ngx

Productivity 2026-02-09 · 9 min read productivity nextcloud bookstack vikunja paperless-ngx self-hosted docker organization

Cloud productivity tools are convenient, but they come with trade-offs: monthly costs that add up, data stored on someone else's servers, features that change or disappear at the provider's discretion, and the nagging feeling that your documents, tasks, and files are only yours as long the service lets them be.

Self-hosting productivity apps gives you full control. Your data stays on your hardware, you choose when to update, and the only monthly cost is the electricity your server already uses. The catch is setup and maintenance — but with Docker, that's gotten remarkably easy.

This guide covers four essential self-hosted productivity apps that, together, replace most of what Google Workspace or Microsoft 365 provides.

Nextcloud logo

The Self-Hosted Productivity Stack

Need Cloud Service Self-Hosted Alternative
File storage/sync Google Drive, Dropbox, OneDrive Nextcloud
Documentation/wiki Notion, Confluence, Google Docs BookStack
Task management Todoist, Asana, Trello Vikunja
Document scanning/management Google Drive, Evernote Paperless-ngx
Calendar Google Calendar Nextcloud (built-in)
Contacts Google Contacts Nextcloud (built-in)
Notes Google Keep, Apple Notes Nextcloud Notes or Memos

Nextcloud: Your Personal Cloud

Nextcloud is the Swiss Army knife of self-hosted productivity. At its core, it's a file sync and share platform — like Dropbox or Google Drive. But its app ecosystem extends it into calendars, contacts, notes, office documents, video calls, and much more.

Deployment

The recommended setup uses Nextcloud with PostgreSQL and Redis for performance:

services:
  nextcloud:
    image: nextcloud:stable-apache
    container_name: nextcloud
    restart: unless-stopped
    ports:
      - "8080:80"
    volumes:
      - ./nextcloud-html:/var/www/html
      - ./nextcloud-data:/var/www/html/data
      - /mnt/storage/nextcloud-files:/var/www/html/data/admin/files  # Optional: external storage
    environment:
      - POSTGRES_HOST=nextcloud-db
      - POSTGRES_DB=nextcloud
      - POSTGRES_USER=nextcloud
      - POSTGRES_PASSWORD=secure-db-password
      - REDIS_HOST=nextcloud-redis
      - NEXTCLOUD_ADMIN_USER=admin
      - NEXTCLOUD_ADMIN_PASSWORD=secure-admin-password
      - NEXTCLOUD_TRUSTED_DOMAINS=nextcloud.home.lab
      - OVERWRITEPROTOCOL=https
      - OVERWRITECLIURL=https://nextcloud.home.lab
    depends_on:
      - nextcloud-db
      - nextcloud-redis

  nextcloud-db:
    image: postgres:16-alpine
    container_name: nextcloud-db
    restart: unless-stopped
    volumes:
      - ./nextcloud-db:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=nextcloud
      - POSTGRES_USER=nextcloud
      - POSTGRES_PASSWORD=secure-db-password

  nextcloud-redis:
    image: redis:7-alpine
    container_name: nextcloud-redis
    restart: unless-stopped
    volumes:
      - ./nextcloud-redis:/data

  nextcloud-cron:
    image: nextcloud:stable-apache
    container_name: nextcloud-cron
    restart: unless-stopped
    volumes:
      - ./nextcloud-html:/var/www/html
      - ./nextcloud-data:/var/www/html/data
    entrypoint: /cron.sh
    depends_on:
      - nextcloud-db
      - nextcloud-redis

Post-Installation Configuration

After first login, configure these settings via occ commands:

# Enter the container
docker exec -u www-data nextcloud bash

# Set the background job method to cron (already handled by nextcloud-cron container)
php occ background:cron

# Configure email notifications
php occ config:system:set mail_from_address --value="nextcloud"
php occ config:system:set mail_domain --value="home.lab"
php occ config:system:set mail_smtpmode --value="smtp"
php occ config:system:set mail_smtphost --value="smtp.home.lab"
php occ config:system:set mail_smtpport --value="587"

# Enable memory caching
php occ config:system:set memcache.local --value="\OC\Memcache\APCu"
php occ config:system:set memcache.distributed --value="\OC\Memcache\Redis"
php occ config:system:set memcache.locking --value="\OC\Memcache\Redis"

# Increase upload limits
php occ config:system:set php_upload_limit --value="16G"

Also update PHP settings for large file uploads. Create a custom PHP config:

# Create custom PHP config
docker exec nextcloud bash -c 'cat > /usr/local/etc/php/conf.d/custom.ini << EOF
upload_max_filesize = 16G
post_max_size = 16G
max_execution_time = 3600
max_input_time = 3600
memory_limit = 512M
EOF'

docker restart nextcloud

Essential Nextcloud Apps

Install these from the Nextcloud App Store (Settings > Apps):

App Purpose
Calendar CalDAV calendar with sharing
Contacts CardDAV contact management
Notes Markdown notes synced across devices
Tasks CalDAV-based task management
Nextcloud Office Document editing (Collabora Online or OnlyOffice)
Talk Video calls and chat
Deck Kanban boards
News RSS feed reader
Passwords Password manager (or use Vaultwarden separately)

Desktop and Mobile Sync

Nextcloud has sync clients for all platforms:

Performance Tips

Nextcloud can feel sluggish without optimization:

  1. Use Redis: Already included in the compose file above. Without Redis, Nextcloud is noticeably slower.
  2. PostgreSQL over MySQL/SQLite: PostgreSQL handles concurrent access better than MySQL and is far faster than SQLite.
  3. Enable APCu: Local memory cache for frequently accessed data.
  4. SSD for database and app data: The Nextcloud database and app directory should be on an SSD. Bulk file storage can be on HDDs.
  5. Preview generation: Install the previewgenerator app and run it on a schedule to pre-generate thumbnails instead of generating them on-demand.
# Pre-generate previews (run after large uploads)
docker exec -u www-data nextcloud php occ preview:generate-all

# Schedule preview generation
# Add to crontab or systemd timer:
# 0 2 * * * docker exec -u www-data nextcloud php occ preview:generate-all

BookStack: Documentation and Wiki

BookStack is a self-hosted wiki platform that organizes content into a hierarchy of Shelves > Books > Chapters > Pages. It's cleaner than MediaWiki, simpler than Confluence, and perfect for documenting your homelab setup, procedures, and knowledge.

Deployment

services:
  bookstack:
    image: lscr.io/linuxserver/bookstack:latest
    container_name: bookstack
    restart: unless-stopped
    ports:
      - "6875:80"
    volumes:
      - ./bookstack-config:/config
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York
      - APP_URL=https://wiki.home.lab
      - DB_HOST=bookstack-db
      - DB_PORT=3306
      - DB_USER=bookstack
      - DB_PASS=secure-db-password
      - DB_DATABASE=bookstackapp
    depends_on:
      - bookstack-db

  bookstack-db:
    image: mariadb:11
    container_name: bookstack-db
    restart: unless-stopped
    volumes:
      - ./bookstack-db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=secure-root-password
      - MYSQL_DATABASE=bookstackapp
      - MYSQL_USER=bookstack
      - MYSQL_PASSWORD=secure-db-password

Default login: [email protected] / password. Change immediately.

Content Organization

BookStack's hierarchy maps naturally to homelab documentation:

Shelf: Infrastructure
├── Book: Networking
│   ├── Chapter: VLANs
│   │   ├── Page: VLAN Design
│   │   └── Page: VLAN Configuration (switch-specific)
│   ├── Chapter: DNS
│   │   ├── Page: Pi-hole Setup
│   │   └── Page: DNS Records
│   └── Chapter: VPN
│       └── Page: WireGuard Configuration
├── Book: Servers
│   ├── Chapter: Proxmox Host
│   │   ├── Page: Hardware Specs
│   │   ├── Page: Installation Notes
│   │   └── Page: GPU Passthrough Config
│   └── Chapter: NAS
│       ├── Page: ZFS Pool Layout
│       └── Page: Share Configuration
└── Book: Services
    ├── Chapter: Media Stack
    └── Chapter: Monitoring

Shelf: Procedures
├── Book: Disaster Recovery
│   ├── Page: Backup Restoration Steps
│   └── Page: Full Rebuild Procedure
├── Book: Maintenance
│   ├── Page: Monthly Checklist
│   └── Page: Update Procedures
└── Book: Troubleshooting
    ├── Page: Common Issues
    └── Page: Network Debugging

Why BookStack Over Alternatives

Feature BookStack Wiki.js Outline Dokuwiki
Setup complexity Very easy Easy Moderate Easy
Editor WYSIWYG + Markdown Markdown + Visual Markdown Markup
Organization Shelves/Books/Chapters Folders Collections/Docs Namespaces
Search Full-text Full-text Full-text Full-text
API REST API GraphQL REST API Limited
Diagrams draw.io integration draw.io, Mermaid Mermaid Plugins
Resource usage Low Low Moderate Very low
Best for Structured docs Technical wikis Team knowledge Simple wikis

BookStack wins for homelab use because its hierarchical organization matches how most people think about infrastructure documentation, and its WYSIWYG editor makes it easy to write and update without learning markup syntax.

Vikunja: Task and Project Management

Vikunja is a self-hosted task manager that replaces Todoist, Asana, or Trello. It supports lists, kanban boards, Gantt charts, and CalDAV sync — so your tasks show up in your calendar app.

Deployment

services:
  vikunja:
    image: vikunja/vikunja:latest
    container_name: vikunja
    restart: unless-stopped
    ports:
      - "3456:3456"
    volumes:
      - ./vikunja-files:/app/vikunja/files
      - ./vikunja-db:/db
    environment:
      VIKUNJA_SERVICE_PUBLICURL: https://tasks.home.lab
      VIKUNJA_DATABASE_TYPE: sqlite
      # For PostgreSQL instead:
      # VIKUNJA_DATABASE_TYPE: postgres
      # VIKUNJA_DATABASE_HOST: vikunja-db
      # VIKUNJA_DATABASE_DATABASE: vikunja
      # VIKUNJA_DATABASE_USER: vikunja
      # VIKUNJA_DATABASE_PASSWORD: secure-password
      VIKUNJA_SERVICE_ENABLEREGISTRATION: "false"
      VIKUNJA_MAILER_ENABLED: "false"

Features Worth Using

Kanban boards: Drag-and-drop task management. Create boards for different areas:

CalDAV integration: Sync tasks with Nextcloud, Thunderbird, or any CalDAV client:

Labels and filters: Tag tasks across projects and create saved filters:

Repeating tasks: Set up recurring tasks for homelab maintenance:

Task Organization for Homelabbers

Project: Homelab Maintenance
├── List: Weekly Tasks
│   ├── Verify backup completion
│   ├── Check monitoring dashboards
│   └── Review system updates
├── List: Monthly Tasks
│   ├── Test backup restoration
│   ├── Review container image updates
│   ├── Check certificate expiration
│   └── Review firewall rules
└── List: Quarterly Tasks
    ├── Full disaster recovery test
    ├── Review access permissions
    └── Clean up unused containers/images

Project: Homelab Upgrades
├── List: Planning
├── List: In Progress
└── List: Completed

Paperless-ngx: Document Management

Paperless-ngx turns your homelab into a paperless office. Scan documents (receipts, bills, letters, manuals), and Paperless automatically OCRs them, extracts metadata, and makes everything searchable. It's the self-hosted equivalent of a filing cabinet that you can search instantly.

Deployment

services:
  paperless:
    image: ghcr.io/paperless-ngx/paperless-ngx:latest
    container_name: paperless
    restart: unless-stopped
    ports:
      - "8000:8000"
    volumes:
      - ./paperless-data:/usr/src/paperless/data
      - ./paperless-media:/usr/src/paperless/media
      - ./paperless-export:/usr/src/paperless/export
      - ./paperless-consume:/usr/src/paperless/consume    # Drop files here
    environment:
      PAPERLESS_REDIS: redis://paperless-redis:6379
      PAPERLESS_DBHOST: paperless-db
      PAPERLESS_DBNAME: paperless
      PAPERLESS_DBUSER: paperless
      PAPERLESS_DBPASS: secure-db-password
      PAPERLESS_SECRET_KEY: change-this-to-a-long-random-string
      PAPERLESS_URL: https://docs.home.lab
      PAPERLESS_ADMIN_USER: admin
      PAPERLESS_ADMIN_PASSWORD: secure-admin-password
      PAPERLESS_OCR_LANGUAGE: eng
      PAPERLESS_CONSUMER_RECURSIVE: "true"
      PAPERLESS_CONSUMER_SUBDIRS_AS_TAGS: "true"
      PAPERLESS_FILENAME_FORMAT: "{created_year}/{correspondent}/{title}"
      USERMAP_UID: 1000
      USERMAP_GID: 1000
    depends_on:
      - paperless-db
      - paperless-redis

  paperless-db:
    image: postgres:16-alpine
    container_name: paperless-db
    restart: unless-stopped
    volumes:
      - ./paperless-db:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: paperless
      POSTGRES_USER: paperless
      POSTGRES_PASSWORD: secure-db-password

  paperless-redis:
    image: redis:7-alpine
    container_name: paperless-redis
    restart: unless-stopped

How the Workflow Works

  1. Consume: Drop a PDF, image, or scan into the consume directory (or use the web UI upload, email, or mobile app)
  2. OCR: Paperless runs Tesseract OCR on the document, making it full-text searchable
  3. Classify: Automatic matching rules assign correspondents (who sent it), document types (invoice, receipt, letter), and tags
  4. Store: The original file is stored with a structured filename in the media directory
  5. Search: Find any document instantly by content, date, correspondent, or tags

Setting Up Auto-Classification

Paperless can automatically classify documents. Set up matching rules:

Correspondent: "Electric Company"
  Match: "Electric Utility" OR "power bill"
  Matching algorithm: Any word

Document Type: "Invoice"
  Match: "invoice" OR "amount due" OR "payment due"
  Matching algorithm: Any word

Tag: "Tax Deductible"
  Match: "business expense" OR "home office"
  Matching algorithm: Any word

Scanning Workflow

Phone scanning: Use the Paperless-ngx mobile app or any scanning app that can upload to a folder:

Network scanner: Configure your scanner to save to the Paperless consume directory via SMB/NFS:

# Create an SMB share for the consume directory
# In /etc/samba/smb.conf:
[paperless]
    path = /path/to/paperless-consume
    writeable = yes
    valid users = scanner

Email consumption: Paperless can automatically ingest email attachments:

    environment:
      PAPERLESS_EMAIL_TASK_CRON: "*/10 * * * *"    # Check every 10 minutes
      # Configure in the web UI under Admin > Mail Accounts

Document Organization

A practical tagging scheme:

Correspondents:
- Bank (statements, notices)
- Insurance (policies, claims)
- Utilities (power, water, internet)
- Government (tax forms, licenses)
- Medical (bills, records)

Document Types:
- Invoice
- Receipt
- Statement
- Contract
- Manual
- Letter

Tags:
- Tax (year) — e.g., "Tax 2025", "Tax 2026"
- Important
- Action Required
- Warranty
- Homelab

Connecting Everything Together

Single Sign-On with Authentik

If you're running all four apps, a single sign-on solution prevents having to manage separate accounts:

  authentik:
    image: ghcr.io/goauthentik/server:latest
    container_name: authentik
    restart: unless-stopped
    command: server
    ports:
      - "9000:9000"
    volumes:
      - ./authentik-media:/media
      - ./authentik-templates:/templates
    environment:
      AUTHENTIK_SECRET_KEY: generate-a-long-random-string
      AUTHENTIK_REDIS__HOST: authentik-redis
      AUTHENTIK_POSTGRESQL__HOST: authentik-db
      AUTHENTIK_POSTGRESQL__USER: authentik
      AUTHENTIK_POSTGRESQL__PASSWORD: secure-password
      AUTHENTIK_POSTGRESQL__NAME: authentik

Nextcloud, BookStack, and Vikunja all support OIDC/OAuth2 authentication. Configure each app to use Authentik as the identity provider, and you get a single login for everything.

Reverse Proxy Configuration

Behind a reverse proxy (Caddy example):

nextcloud.home.lab {
    reverse_proxy nextcloud:80
    request_body {
        max_size 16GB
    }
}

wiki.home.lab {
    reverse_proxy bookstack:80
}

tasks.home.lab {
    reverse_proxy vikunja:3456
}

docs.home.lab {
    reverse_proxy paperless:8000
}

Backup Strategy

These apps contain important personal data. Back them up:

#!/bin/bash
# backup-productivity.sh

BACKUP_DIR="/mnt/backup/productivity"
DATE=$(date +%Y-%m-%d)

mkdir -p "$BACKUP_DIR"

# Database dumps
docker exec nextcloud-db pg_dumpall -U nextcloud > "$BACKUP_DIR/nextcloud-$DATE.sql"
docker exec bookstack-db mysqldump -u root --password=secure-root-password bookstackapp > "$BACKUP_DIR/bookstack-$DATE.sql"
docker exec paperless-db pg_dumpall -U paperless > "$BACKUP_DIR/paperless-$DATE.sql"

# Application data
tar -czf "$BACKUP_DIR/nextcloud-data-$DATE.tar.gz" ./nextcloud-data
tar -czf "$BACKUP_DIR/bookstack-config-$DATE.tar.gz" ./bookstack-config
tar -czf "$BACKUP_DIR/paperless-media-$DATE.tar.gz" ./paperless-media
tar -czf "$BACKUP_DIR/vikunja-$DATE.tar.gz" ./vikunja-files ./vikunja-db

# Rotate (keep 7 days)
find "$BACKUP_DIR" -name "*.sql" -mtime +7 -delete
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +7 -delete

Resource Requirements

App RAM (minimum) RAM (recommended) CPU Storage
Nextcloud + DB + Redis 1GB 2-4GB 2 cores 10GB + files
BookStack + DB 512MB 1GB 1 core 2GB
Vikunja (SQLite) 128MB 256MB 0.5 cores 1GB
Paperless-ngx + DB + Redis 1GB 2GB 2 cores 5GB + documents
Total ~3GB ~6-8GB 4-6 cores 20GB + data

All four apps run comfortably on a single server with 8GB of RAM. They're not resource-intensive — the main storage consideration is how much file/document data you accumulate.

Final Thoughts

Self-hosted productivity apps hit a sweet spot between cloud convenience and data ownership. Nextcloud replaces Google Drive and calendar, BookStack replaces Notion or Confluence for documentation, Vikunja replaces Todoist for task management, and Paperless-ngx turns your paper pile into a searchable archive.

The setup time for all four is about an afternoon. The maintenance is minimal — update containers monthly, verify backups weekly, and they largely run themselves. The payoff is knowing that your files, documents, tasks, and notes are yours, on your hardware, under your control.

Start with whichever one solves your most pressing need. For most people, that's Nextcloud (everyone needs file sync) or Paperless-ngx (everyone has a pile of paper they should deal with). Add the others as you see the value.