Notes intermediate ⏱ 45 minutes

Wiki.js: Modern Wiki Platform

Powerful wiki with multiple editors. Git sync, authentication, and full-text search.

By Homelab Team • 2025-01-15
#wikijs#wiki#documentation#git#docker

Introduction

Wiki.js is a powerful open-source wiki software built on Node.js and featuring a modern, intuitive interface. It’s designed to make documentation easy and beautiful, with support for multiple storage backends, authentication methods, and an extensive plugin system.

Why Choose Wiki.js?

  • Modern Interface: Clean, responsive design that works on all devices
  • Markdown Editor: Multiple editor options including WYSIWYG and markdown
  • Powerful Search: Built-in full-text search with highlighting
  • Git Integration: Sync content with Git repositories
  • Multi-Language: Full internationalization support
  • Authentication: Support for various auth providers (LDAP, OAuth, SAML)
  • Storage Options: Multiple storage backends (DB, Git, S3, etc.)
  • Customizable: Themes, custom CSS, and extensive configuration

Use Cases

  • Technical documentation
  • Company wikis and knowledge bases
  • Product documentation
  • Project documentation
  • Educational content
  • Standard operating procedures
  • API documentation
  • Personal knowledge management

Prerequisites

Before you begin, ensure you have:

  • Docker and Docker Compose installed
  • 1GB of available RAM (2GB recommended)
  • 5-10GB of disk space
  • (Optional) Domain name for reverse proxy
  • (Optional) SSL certificate for HTTPS
  • (Optional) PostgreSQL or MySQL database (SQLite works too)

Quick Start with Docker Compose

Basic Configuration (SQLite)

For a simple setup using SQLite:

mkdir -p ~/homelab/wikijs
cd ~/homelab/wikijs
nano docker-compose.yml

Basic Docker Compose configuration:

version: '3.8'

services:
  wikijs:
    image: ghcr.io/requarks/wiki:2
    container_name: wikijs
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - DB_TYPE=sqlite
      - DB_FILEPATH=/wiki/data/db.sqlite
      - TZ=America/New_York
    volumes:
      - wikijs-data:/wiki/data
      - wikijs-content:/wiki/repo
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/healthz"]
      interval: 30s
      timeout: 10s
      retries: 3

volumes:
  wikijs-data:
  wikijs-content:

Production Configuration (PostgreSQL)

For production deployments with PostgreSQL:

version: '3.8'

services:
  wikijs:
    image: ghcr.io/requarks/wiki:2
    container_name: wikijs
    restart: unless-stopped
    depends_on:
      - postgres
    networks:
      - wikijs_network
      - proxy
    expose:
      - 3000
    environment:
      # Database Configuration
      - DB_TYPE=postgres
      - DB_HOST=postgres
      - DB_PORT=5432
      - DB_USER=wikijs
      - DB_PASS=CHANGE_ME_PASSWORD
      - DB_NAME=wikijs

      # Server Configuration
      - TZ=America/New_York
      - [email protected]

      # Optional: Custom Port
      # - PORT=3000

      # Optional: SSL Configuration
      # - SSL_ENABLED=true
      # - SSL_PORT=3443

    volumes:
      - wikijs-data:/wiki/data
      - wikijs-content:/wiki/repo
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.wikijs.rule=Host(`wiki.yourdomain.com`)"
      - "traefik.http.routers.wikijs.entrypoints=websecure"
      - "traefik.http.routers.wikijs.tls=true"
      - "traefik.http.routers.wikijs.tls.certresolver=letsencrypt"
      - "traefik.http.services.wikijs.loadbalancer.server.port=3000"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/healthz"]
      interval: 30s
      timeout: 10s
      retries: 3

  postgres:
    image: postgres:15-alpine
    container_name: wikijs_postgres
    restart: unless-stopped
    networks:
      - wikijs_network
    environment:
      - POSTGRES_USER=wikijs
      - POSTGRES_PASSWORD=CHANGE_ME_PASSWORD
      - POSTGRES_DB=wikijs
    volumes:
      - postgres-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U wikijs"]
      interval: 30s
      timeout: 10s
      retries: 5

networks:
  wikijs_network:
    driver: bridge
  proxy:
    external: true

volumes:
  wikijs-data:
  wikijs-content:
  postgres-data:

Deploy Wiki.js

Start the containers:

docker-compose up -d

Monitor the startup process:

docker-compose logs -f wikijs

Initial Setup

First-Time Configuration

  1. Navigate to http://YOUR-SERVER-IP:3000 in your browser
  2. You’ll be greeted by the setup wizard
  3. Configure the following:

Administrator Account

  • Email address
  • Password (minimum 8 characters)
  • Confirm password

Site Settings

  • Site URL (e.g., https://wiki.yourdomain.com)
  • Site title
  • Default language

Storage Target

  • Choose where to store content (Local, Git, S3, etc.)
  • For basic setup, select “Local Filesystem”

Post-Installation Steps

After completing the wizard:

  1. Configure Authentication: Admin → Authentication
  2. Set Up Storage: Admin → Storage
  3. Install Editors: Admin → Editors (markdown, visual, etc.)
  4. Configure Search: Admin → Search Engine
  5. Customize Theme: Admin → Theme
  6. Set Permissions: Admin → Groups & Users

Storage Configuration

Local Filesystem

Default storage option, good for single-server deployments:

# Already configured in docker-compose
volumes:
  - wikijs-content:/wiki/repo

Git Integration

Sync your wiki with a Git repository:

  1. Go to Admin → Storage
  2. Enable “Git” storage target
  3. Configure:
Repository URL: https://github.com/yourusername/wiki-content.git
Branch: main
Authentication: SSH Key or Personal Access Token
Sync Direction: Bi-directional
Sync Schedule: Every 5 minutes

Generate SSH key for Git:

docker exec wikijs ssh-keygen -t ed25519 -C "[email protected]"
docker exec wikijs cat /root/.ssh/id_ed25519.pub
# Add this public key to your Git repository

S3 Storage

For cloud storage or MinIO:

# In Admin → Storage, configure:
# Access Key ID: your_access_key
# Secret Access Key: your_secret_key
# Region: us-east-1
# Bucket: wikijs-content
# Endpoint: http://minio:9000 (for MinIO)

Azure Blob Storage

# Account Name: youraccount
# Account Key: your_key
# Container Name: wikijs

Authentication Setup

Local Authentication

Enabled by default, allows user/password login:

  1. Admin → Authentication → Local
  2. Configure:
    • Self-registration: Enabled/Disabled
    • Email verification: Required/Optional
    • Password requirements

LDAP / Active Directory

Connect to your directory service:

# Admin → Authentication → LDAP
Server URL: ldap://ldap.yourdomain.com:389
Bind DN: cn=admin,dc=yourdomain,dc=com
Bind Password: your_password
Search Base: ou=users,dc=yourdomain,dc=com
Search Filter: (uid={{username}})
TLS Enabled: true

OAuth2 / OpenID Connect

Configure OAuth providers:

Google OAuth

Client ID: your_google_client_id
Client Secret: your_google_client_secret
Authorization URL: https://accounts.google.com/o/oauth2/v2/auth
Token URL: https://oauth2.googleapis.com/token
User Info URL: https://www.googleapis.com/oauth2/v2/userinfo

GitHub OAuth

Client ID: your_github_client_id
Client Secret: your_github_client_secret

Generic OIDC (Authelia, Keycloak, etc.)

Client ID: wikijs
Client Secret: your_secret
Authorization Endpoint: https://auth.yourdomain.com/api/oidc/authorization
Token Endpoint: https://auth.yourdomain.com/api/oidc/token
User Info Endpoint: https://auth.yourdomain.com/api/oidc/userinfo

SAML 2.0

For enterprise SSO:

Entry Point: https://idp.yourdomain.com/sso
Issuer: wikijs
Audience: wikijs
Certificate: COPY_YOUR_CERT_HERE

Content Management

Creating Pages

  1. Click “Create Page” button
  2. Choose editor type (Markdown, Visual, etc.)
  3. Select page path (e.g., /documentation/getting-started)
  4. Write content
  5. Set page properties:
    • Title
    • Description
    • Tags
    • Visibility (Public/Private)

Page Organization

Organize pages hierarchically:

Home
├── Documentation
│   ├── Getting Started
│   ├── User Guide
│   └── API Reference
├── Tutorials
│   ├── Beginner
│   └── Advanced
└── FAQ

Templates

Create page templates:

  1. Create a page with your template content
  2. Admin → Rendering → HTML Head
  3. Add template markup

Tags and Categories

Organize content with tags:

  1. Edit page
  2. Add tags in page properties
  3. Users can browse by tags: /t/tag-name

Backup and Restore

Automated Backup Script

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

BACKUP_DIR="/mnt/backups/wikijs"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=30

mkdir -p "$BACKUP_DIR"

# Backup PostgreSQL database
docker exec wikijs_postgres pg_dump -U wikijs wikijs |   gzip > "$BACKUP_DIR/wikijs_db_$TIMESTAMP.sql.gz"

# Backup content repository
docker run --rm   --volumes-from wikijs   -v "$BACKUP_DIR:/backup"   alpine tar czf "/backup/wikijs_content_$TIMESTAMP.tar.gz"   /wiki/repo /wiki/data

# Create combined archive
tar -czf "$BACKUP_DIR/wikijs_complete_$TIMESTAMP.tar.gz"   -C "$BACKUP_DIR"   "wikijs_db_$TIMESTAMP.sql.gz"   "wikijs_content_$TIMESTAMP.tar.gz"

# Cleanup temporary files
rm "$BACKUP_DIR/wikijs_db_$TIMESTAMP.sql.gz"    "$BACKUP_DIR/wikijs_content_$TIMESTAMP.tar.gz"

# Remove old backups
find "$BACKUP_DIR" -name "wikijs_complete_*.tar.gz" -mtime +$RETENTION_DAYS -delete

echo "Backup completed: wikijs_complete_$TIMESTAMP.tar.gz"

Schedule Backups

chmod +x backup-wikijs.sh

# Add to crontab
crontab -e
# Daily backup at 3 AM
0 3 * * * /path/to/backup-wikijs.sh >> /var/log/wikijs-backup.log 2>&1

Restore from Backup

#!/bin/bash
# restore-wikijs.sh

BACKUP_FILE="$1"
TEMP_DIR="/tmp/wikijs_restore"

if [ -z "$BACKUP_FILE" ]; then
  echo "Usage: $0 backup_file.tar.gz"
  exit 1
fi

# Stop Wiki.js
docker-compose down

# Extract backup
mkdir -p "$TEMP_DIR"
tar -xzf "$BACKUP_FILE" -C "$TEMP_DIR"

# Restore database
docker-compose up -d postgres
sleep 10

gunzip < "$TEMP_DIR"/wikijs_db_*.sql.gz |   docker exec -i wikijs_postgres psql -U wikijs

# Restore content
tar -xzf "$TEMP_DIR"/wikijs_content_*.tar.gz -C "$TEMP_DIR"
docker run --rm   --volumes-from wikijs   -v "$TEMP_DIR:/restore"   alpine sh -c "rm -rf /wiki/repo/* /wiki/data/* &&                 cp -r /restore/wiki/repo/* /wiki/repo/ &&                 cp -r /restore/wiki/data/* /wiki/data/"

# Cleanup
rm -rf "$TEMP_DIR"

# Start Wiki.js
docker-compose up -d

echo "Restore completed successfully"

Data Import and Export

Import from Markdown Files

Bulk import markdown files:

  1. Admin → Utilities → Import
  2. Choose source format
  3. Upload files or specify directory

Or use the API:

#!/bin/bash
# import-markdown.sh

API_TOKEN="YOUR_API_TOKEN"
WIKI_URL="https://wiki.yourdomain.com"

for file in *.md; do
  title=$(basename "$file" .md)
  content=$(cat "$file")
  path="/imported/${title}"

  curl -X POST "$WIKI_URL/graphql"     -H "Authorization: Bearer $API_TOKEN"     -H "Content-Type: application/json"     -d "{
      "query": "mutation ($content: String!, $path: String!, $title: String!) { pages { create(content: $content, path: $path, title: $title, isPublished: true, isPrivate: false, editor: \"markdown\") { responseResult { succeeded errorCode message } } } }",
      "variables": {
        "content": $(echo "$content" | jq -Rs .),
        "path": "$path",
        "title": "$title"
      }
    }"
done

Export Pages

Export all content:

  1. Admin → Utilities → Export
  2. Choose format (Markdown, HTML, PDF)
  3. Select pages to export
  4. Download archive

API-Based Export

#!/bin/bash
# export-wikijs.sh

API_TOKEN="YOUR_API_TOKEN"
WIKI_URL="https://wiki.yourdomain.com"
OUTPUT_DIR="./wiki-export"

mkdir -p "$OUTPUT_DIR"

# Get all pages
pages=$(curl -s -X POST "$WIKI_URL/graphql"   -H "Authorization: Bearer $API_TOKEN"   -H "Content-Type: application/json"   -d '{"query": "{ pages { list { id path title } } }"}')

# Extract and save each page
echo "$pages" | jq -r '.data.pages.list[] | @base64' | while read page; do
  _jq() {
    echo ${page} | base64 --decode | jq -r ${1}
  }

  id=$(_jq '.id')
  path=$(_jq '.path')
  title=$(_jq '.title')

  # Get page content
  content=$(curl -s -X POST "$WIKI_URL/graphql"     -H "Authorization: Bearer $API_TOKEN"     -H "Content-Type: application/json"     -d "{"query": "{ pages { single(id: $id) { content } } }"}" |     jq -r '.data.pages.single.content')

  # Save to file
  filepath="$OUTPUT_DIR${path}.md"
  mkdir -p "$(dirname "$filepath")"
  echo "$content" > "$filepath"
  echo "Exported: $filepath"
done

Advanced Configuration

Custom CSS and Themes

Add custom styling:

  1. Admin → Theme → CSS Override
  2. Add your CSS:
/* Custom theme example */
:root {
  --primary-color: #2c3e50;
  --accent-color: #3498db;
}

.v-toolbar {
  background-color: var(--primary-color) !important;
}

.page-content {
  font-family: 'Inter', sans-serif;
  line-height: 1.7;
}

/* Dark mode adjustments */
.theme--dark .page-content {
  background-color: #1e1e1e;
  color: #e0e0e0;
}

Custom HTML Head

Add analytics or custom scripts:

<!-- Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'GA_MEASUREMENT_ID');
</script>

<!-- Custom fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600&display=swap" rel="stylesheet">

Search Engine Configuration

Configure search backend:

Database (Default)

  • Basic full-text search
  • No additional setup required

Elasticsearch

# Admin → Search Engine → Elasticsearch
Host: http://elasticsearch:9200
Index Name: wikijs

Solr

Host: http://solr:8983/solr
Core Name: wikijs

API Configuration

Enable and configure the GraphQL API:

  1. Admin → API Access
  2. Generate API tokens
  3. Set rate limits
  4. Configure CORS if needed

Example API query:

query {
  pages {
    list {
      id
      path
      title
      description
      createdAt
      updatedAt
    }
  }
}

Troubleshooting

Common Issues

Wiki.js won’t start

# Check logs
docker-compose logs wikijs

# Common issues:
# 1. Database connection failed
docker-compose logs postgres
docker exec wikijs_postgres psql -U wikijs -c "SELECT 1"

# 2. Port already in use
sudo netstat -tlnp | grep 3000

# 3. Permission issues
docker exec wikijs ls -la /wiki/data

Database Migration Errors

# Reset database (WARNING: destroys data)
docker-compose down
docker volume rm wikijs_postgres-data
docker-compose up -d

# Or fix migrations
docker exec wikijs_postgres psql -U wikijs -d wikijs
# Check migrations table
SELECT * FROM migrations;

Search Not Working

# Rebuild search index
# Admin → Utilities → Rebuild Index

# Or via API
curl -X POST "https://wiki.yourdomain.com/graphql"   -H "Authorization: Bearer YOUR_TOKEN"   -H "Content-Type: application/json"   -d '{"query": "mutation { pages { rebuildIndex { responseResult { succeeded } } } }"}'

Git Sync Issues

# Check SSH key
docker exec wikijs cat /root/.ssh/id_ed25519.pub

# Test Git connection
docker exec wikijs git ls-remote [email protected]:user/repo.git

# Check sync logs in Admin → System → Logs

Performance Problems

# Check resources
docker stats wikijs

# Increase memory limit
services:
  wikijs:
    deploy:
      resources:
        limits:
          memory: 2G
        reservations:
          memory: 1G

# Optimize PostgreSQL
docker exec wikijs_postgres psql -U wikijs -d wikijs -c "VACUUM ANALYZE;"

Reset Admin Password

If you forget the admin password:

# Connect to database
docker exec -it wikijs_postgres psql -U wikijs

# Update admin password (bcrypt hash for "admin123")
UPDATE users SET password = '$2a$12$V.GN5kD7HxvXFB.vvY4B1.Vu7cXJT1JW7p.HK/wG3P5K9z6YhMqpy' WHERE email = '[email protected]';

# Exit and login with temporary password
# Change it immediately in Admin → Profile

Enable Debug Mode

environment:
  - WIKI_LOG_LEVEL=debug

Security Best Practices

Network Security

  1. Use HTTPS: Always enable SSL/TLS
  2. Firewall: Restrict database access
  3. Updates: Keep Docker images updated
  4. Backups: Encrypted backup storage

Access Control

Configure user groups and permissions:

  1. Admin → Groups
  2. Create groups: Readers, Editors, Admins
  3. Set page-level permissions
  4. Assign users to appropriate groups

Content Security

  1. Private Pages: Mark sensitive content as private
  2. Authentication: Require login for viewing
  3. 2FA: Enable two-factor authentication
  4. Audit Logs: Review user activities regularly

Maintenance

Regular Updates

# Update Wiki.js
docker-compose pull wikijs
docker-compose up -d wikijs

# Update PostgreSQL (be careful!)
docker-compose pull postgres
docker-compose up -d postgres

Database Maintenance

# Vacuum database monthly
docker exec wikijs_postgres psql -U wikijs -d wikijs -c "VACUUM FULL ANALYZE;"

# Check database size
docker exec wikijs_postgres psql -U wikijs -d wikijs -c "
SELECT pg_size_pretty(pg_database_size('wikijs'));"

# Check largest tables
docker exec wikijs_postgres psql -U wikijs -d wikijs -c "
SELECT tablename, pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename))
FROM pg_tables WHERE schemaname = 'public' ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;"

Log Management

services:
  wikijs:
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "5"

Monitoring

Set up health check monitoring:

# Check Wiki.js health
curl https://wiki.yourdomain.com/healthz

# Monitor with cron
*/5 * * * * curl -f https://wiki.yourdomain.com/healthz || echo "Wiki.js down!" | mail -s "Alert" [email protected]

Tips and Best Practices

Content Organization

  1. Logical Structure: Plan hierarchy before creating pages
  2. Naming Conventions: Use clear, descriptive paths
  3. Tags: Use consistently across similar content
  4. Cross-Links: Link related pages together
  5. Regular Reviews: Update outdated content

Performance Optimization

  1. Image Optimization: Compress images before uploading
  2. Database Tuning: Adjust PostgreSQL settings
  3. Caching: Configure reverse proxy caching
  4. CDN: Use for static assets

Collaboration

  1. Style Guide: Create documentation standards
  2. Templates: Provide page templates
  3. Permissions: Set appropriate access levels
  4. Comments: Enable for feedback
  5. Notifications: Configure email alerts

Additional Resources

Conclusion

Wiki.js provides a modern, feature-rich platform for documentation and knowledge management. Its clean interface, multiple authentication options, and flexible storage backends make it suitable for both personal and enterprise use.

The key to success with Wiki.js is proper initial configuration, regular backups, and establishing good documentation practices. Start with the basics, configure authentication and storage appropriately, and expand features as your needs grow.

With proper maintenance and organization, Wiki.js becomes an invaluable tool for preserving and sharing knowledge within your organization or personal projects.

Happy documenting!