Wiki.js: Modern Wiki Platform
Powerful wiki with multiple editors. Git sync, authentication, and full-text search.
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
- Navigate to
http://YOUR-SERVER-IP:3000in your browser - You’ll be greeted by the setup wizard
- 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:
- Configure Authentication: Admin → Authentication
- Set Up Storage: Admin → Storage
- Install Editors: Admin → Editors (markdown, visual, etc.)
- Configure Search: Admin → Search Engine
- Customize Theme: Admin → Theme
- 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:
- Go to Admin → Storage
- Enable “Git” storage target
- 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:
- Admin → Authentication → Local
- 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
- Click “Create Page” button
- Choose editor type (Markdown, Visual, etc.)
- Select page path (e.g.,
/documentation/getting-started) - Write content
- 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:
- Create a page with your template content
- Admin → Rendering → HTML Head
- Add template markup
Tags and Categories
Organize content with tags:
- Edit page
- Add tags in page properties
- 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:
- Admin → Utilities → Import
- Choose source format
- 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:
- Admin → Utilities → Export
- Choose format (Markdown, HTML, PDF)
- Select pages to export
- 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:
- Admin → Theme → CSS Override
- 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:
- Admin → API Access
- Generate API tokens
- Set rate limits
- 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
- Use HTTPS: Always enable SSL/TLS
- Firewall: Restrict database access
- Updates: Keep Docker images updated
- Backups: Encrypted backup storage
Access Control
Configure user groups and permissions:
- Admin → Groups
- Create groups: Readers, Editors, Admins
- Set page-level permissions
- Assign users to appropriate groups
Content Security
- Private Pages: Mark sensitive content as private
- Authentication: Require login for viewing
- 2FA: Enable two-factor authentication
- 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
- Logical Structure: Plan hierarchy before creating pages
- Naming Conventions: Use clear, descriptive paths
- Tags: Use consistently across similar content
- Cross-Links: Link related pages together
- Regular Reviews: Update outdated content
Performance Optimization
- Image Optimization: Compress images before uploading
- Database Tuning: Adjust PostgreSQL settings
- Caching: Configure reverse proxy caching
- CDN: Use for static assets
Collaboration
- Style Guide: Create documentation standards
- Templates: Provide page templates
- Permissions: Set appropriate access levels
- Comments: Enable for feedback
- Notifications: Configure email alerts
Additional Resources
- Official Documentation: https://docs.requarks.io
- GitHub Repository: https://github.com/requarks/wiki
- Docker Hub: https://hub.docker.com/r/requarks/wiki
- Community Forum: https://github.com/requarks/wiki/discussions
- GraphQL Documentation: https://docs.requarks.io/dev/api
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!