Skip to content

stlouis12/Squirrel.Wiki

Repository files navigation

Squirrel.Wiki

A modern, extensible wiki platform built with ASP.NET Core 8.0, featuring a plugin architecture and support for multiple database providers.

About this project

Full disclosure, this project was largely generated by AI for fun because I wanted to see how far I could go. There's some good, surely some bad, but the result still appears to be a functional wiki engine with some basic file management, tagging and categorization. I'm no C# developer and although I do have some C# knowledge I don't do it in a professional capacity and I haven't really touched it since before dotnet core was a thing. I did massage some things manually, but whether I did it best way... ¯\(ツ)

It also includes plugin features that allow custom markdown extensions (table of contents plugin included), search providers (Lucene plugin included for more robust search), file storage providers (untested), authentication providers (OIDC plugin included). The intent is to support multiple databases as well since the project uses Entity Framework, though so far I've only tested sqlite locally

It has a flexible configuration system that allows both the just running the application and configuring it the way you want through the Settings page, or you can control every setting by setting docker environment variables which will lock the settings on the Settings page preventing them from being modified.

It has been a fun experience toying with AI code generation, and sometimes rather infuriating trying to coerce it to get back on track, often times having to fix some things manually and in all honesty, I've learned a few things along the way such as the distinction between a strategy pattern and factory pattern. There's definitely area's where AI can be extremely useful, and definitely areas where it falls short.

Why this project specifally for this AI project? Well a wiki came to mind as something I could use in my homelab to retain some form of knowledge base in case I need to do things again later. In my thought process I recalled Roadkill v2 wiki which I used years ago and really liked at the time, but roadkill v2 is quite stale and roadkill v3 as far as I can tell went dead around dotnet5.0 and remains incomplete. As such, I set out to make something similar and this is the result.

Why the name Squirrel? Well being inspired by Roadkill, I asked AI what is the opposite of roadkill? It obviously came back with nothing concrete but somewhere in the nonsense result it did refer to rodents, including squirrels, and my ADD brain thought Squirrels squirrel things away, so that was that.

Contributing

If you like this project, and want to give some real human contribution, feel free to fork the repo and send me PR's. I'd really love to see this polished up as I'm sure there's lots of room for improvement

Features

  • Markdown-based content editing - extensible via plugins
  • Site Customization (Menu, Navigation, Footer content)
  • Home page can be replaced by simply creating a wiki page named "Home"
  • Extensible plugin system (Search, File storage, Markdown, and Authentication)
  • Search capabilities
  • Tagging and Categories
  • File Management
  • Built in authentication (OpenID Connect plugin included)
  • Multiple database support (SQLite, PostgreSQL, MySQL, MariaDB, SQL Server)
  • Docker support for easy deployment
  • Built-in caching (Memory or Redis)

Quick Start with Docker

Building the Docker Image

docker build -t squirrel-wiki:latest .

Running the Container

Basic SQLite Setup (Default)

docker run -d \
  --name squirrel-wiki \
  -p 8080:8080 \
  -v squirrel-data:/app/App_Data \
  squirrel-wiki:latest

Access the wiki at http://localhost:8080

Default credentials:

  • Username: admin
  • Password: Squirrel123!

PostgreSQL Setup

docker run -d \
  --name squirrel-wiki \
  -p 8080:8080 \
  -e SQUIRREL_DATABASE_PROVIDER=PostgreSQL \
  -e SQUIRREL_DATABASE_CONNECTION_STRING="Host=postgres;Database=squirrelwiki;Username=squirrel;Password=yourpassword" \
  -v squirrel-data:/app/App_Data \
  squirrel-wiki:latest

With Redis Caching

docker run -d \
  --name squirrel-wiki \
  -p 8080:8080\
  -e SQUIRREL_CACHE_PROVIDER=Redis \
  -e SQUIRREL_REDIS_CONFIGURATION="redis:6379" \
  -v squirrel-data:/app/App_Data \
  squirrel-wiki:latest

Docker Compose Example

version: '3.8'

services:
  squirrel-wiki:
    image: squirrel-wiki:latest
    ports:
      - "8080:80"
    environment:
      - SQUIRREL_DATABASE_PROVIDER=PostgreSQL
      - SQUIRREL_DATABASE_CONNECTION_STRING=Host=postgres;Database=squirrelwiki;Username=squirrel;Password=yourpassword
      - SQUIRREL_SITE_NAME=My Wiki
      - SQUIRREL_SITE_URL=https://wiki.example.com
      - SQUIRREL_CACHE_PROVIDER=Redis
      - SQUIRREL_REDIS_CONFIGURATION=redis:6379
    volumes:
      - squirrel-data:/app/App_Data
    depends_on:
      - postgres
      - redis

  postgres:
    image: postgres:16-alpine
    environment:
      - POSTGRES_DB=squirrelwiki
      - POSTGRES_USER=squirrel
      - POSTGRES_PASSWORD=yourpassword
    volumes:
      - postgres-data:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine
    volumes:
      - redis-data:/data

volumes:
  squirrel-data:
  postgres-data:
  redis-data:

Configuration

Database Configuration

These settings are configured at startup and cannot be changed at runtime.

Environment Variable Description Default Allowed Values
SQUIRREL_DATABASE_PROVIDER Database provider to use SQLite SQLite, PostgreSQL, MySQL, MariaDB, SQLServer
SQUIRREL_DATABASE_CONNECTION_STRING Database connection string Data Source=App_Data/squirrel.db Valid connection string for chosen provider
SQUIRREL_DATABASE_AUTO_MIGRATE Automatically apply database migrations on startup true true, false
SQUIRREL_DATABASE_SEED_DATA Seed initial data into the database on startup true true, false

Example Connection Strings

SQLite:

Data Source=App_Data/squirrel.db

PostgreSQL:

Host=localhost;Database=squirrelwiki;Username=squirrel;Password=yourpassword

MySQL/MariaDB:

Server=localhost;Database=squirrelwiki;User=squirrel;Password=yourpassword

SQL Server:

Server=localhost;Database=squirrelwiki;User Id=squirrel;Password=yourpassword;TrustServerCertificate=True

Application Configuration

These settings can be modified at runtime through the admin interface or environment variables.

General Settings

Environment Variable Description Default Type
SQUIRREL_SITE_NAME The name of your wiki site Squirrel Wiki string
SQUIRREL_SITE_URL The public URL of your wiki site (empty) URL
SQUIRREL_DEFAULT_LANGUAGE Default language for the wiki interface en en, es, fr, de, it
SQUIRREL_TIMEZONE Default time zone for displaying dates and times (see available timezones) UTC string

Security Settings

Environment Variable Description Default Type
SQUIRREL_ADMIN_USERNAME Default admin username for initial bootstrap admin string
SQUIRREL_ADMIN_PASSWORD Default admin password for initial bootstrap Squirrel123! string (secret)
SQUIRREL_ADMIN_EMAIL Default admin email address for initial bootstrap admin@localhost string
SQUIRREL_ADMIN_DISPLAYNAME Default admin display name for initial bootstrap Administrator string
SQUIRREL_ALLOW_ANONYMOUS_READING Whether unauthenticated users can read wiki pages false boolean
SQUIRREL_SESSION_TIMEOUT_MINUTES How long a user session remains active without activity 480 integer (30-20160)
SQUIRREL_MAX_LOGIN_ATTEMPTS Number of failed login attempts before account is locked 5 integer (3-20)
SQUIRREL_ACCOUNT_LOCK_DURATION_MINUTES How long an account remains locked after too many failed login attempts 30 integer (5-1440)

Content Settings

Environment Variable Description Default Type
SQUIRREL_DEFAULT_PAGE_TEMPLATE Default markdown template for new pages (empty) string
SQUIRREL_MAX_PAGE_TITLE_LENGTH Maximum number of characters allowed in page titles 200 integer (25-500)
SQUIRREL_ENABLE_PAGE_VERSIONING Whether to keep historical versions of pages false boolean

Performance Settings

Environment Variable Description Default Type
SQUIRREL_ENABLE_CACHING Whether to enable in-memory caching for improved performance true boolean
SQUIRREL_CACHE_DURATION_MINUTES How long cached items remain valid in memory 60 integer (1-1440)
SQUIRREL_ENABLE_RESPONSE_CACHING Whether to enable HTTP response caching for pages true boolean
SQUIRREL_RESPONSE_CACHE_DURATION_MINUTES How long HTTP responses are cached by browsers and proxies 5 integer (1-60)
SQUIRREL_CACHE_PROVIDER The caching provider to use Memory Memory, Redis
SQUIRREL_REDIS_CONFIGURATION Redis connection string localhost:6379 string
SQUIRREL_REDIS_INSTANCE_NAME Redis instance name prefix for cache keys Squirrel_ string

File Storage Settings

Environment Variable Description Default Type
SQUIRREL_FILE_STORAGE_PATH Directory path where uploaded files are stored App_Data/Files string
SQUIRREL_FILE_MAX_SIZE_MB Maximum allowed file size for uploads in megabytes 100 integer (1-2048)
SQUIRREL_FILE_ALLOWED_EXTENSIONS Comma-separated list of allowed file extensions .pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.md,.jpg,.jpeg,.png,.gif,.bmp,.svg,.zip,.rar,.7z string

Application Paths

Environment Variable Description Default Type
SQUIRREL_APP_DATA_PATH The directory path where application data is stored App_Data string
SQUIRREL_SEED_DATA_FILE_PATH The path to a custom seed data YAML file (empty) string

Plugins

Squirrel.Wiki includes three built-in plugins that can be enabled and configured through environment variables.

OpenID Connect Authentication Plugin

Provides OpenID Connect / OAuth 2.0 authentication support.

Environment Variable Description Required Default
PLUGIN_SQUIRREL_AUTH_OIDC_ENABLED Enable the OIDC authentication plugin No false
PLUGIN_SQUIRREL_AUTH_OIDC_AUTHORITY The URL of the OpenID Connect provider Yes -
PLUGIN_SQUIRREL_AUTH_OIDC_CLIENTID The client ID registered with the OIDC provider Yes -
PLUGIN_SQUIRREL_AUTH_OIDC_CLIENTSECRET The client secret for authentication Yes -
PLUGIN_SQUIRREL_AUTH_OIDC_SCOPE The OAuth scopes to request (space-separated) No openid profile email
PLUGIN_SQUIRREL_AUTH_OIDC_USERNAME_CLAIM The claim to use for the username No preferred_username
PLUGIN_SQUIRREL_AUTH_OIDC_EMAIL_CLAIM The claim to use for the email address No email
PLUGIN_SQUIRREL_AUTH_OIDC_DISPLAY_NAME_CLAIM The claim to use for the display name No name
PLUGIN_SQUIRREL_AUTH_OIDC_GROUPS_CLAIM The claim that contains group memberships No groups
PLUGIN_SQUIRREL_AUTH_OIDC_ADMIN_GROUP The group name that grants admin privileges No squirrel-admins
PLUGIN_SQUIRREL_AUTH_OIDC_EDITOR_GROUP The group name that grants editor privileges No squirrel-editors
PLUGIN_SQUIRREL_AUTH_OIDC_AUTO_CREATE_USERS Automatically create user accounts on first login No true
PLUGIN_SQUIRREL_AUTH_OIDC_REQUIRE_HTTPS_METADATA Require HTTPS for metadata endpoint No true

Example: Keycloak

docker run -d \
  --name squirrel-wiki \
  -p 8080:8080\
  -e PLUGIN_SQUIRREL_AUTH_OIDC_ENABLED=true \
  -e PLUGIN_SQUIRREL_AUTH_OIDC_AUTHORITY=https://keycloak.example.com/realms/myrealm \
  -e PLUGIN_SQUIRREL_AUTH_OIDC_CLIENTID=squirrel-wiki \
  -e PLUGIN_SQUIRREL_AUTH_OIDC_CLIENTSECRET=your-client-secret \
  -e PLUGIN_SQUIRREL_AUTH_OIDC_SCOPE="openid profile email" \
  -e PLUGIN_SQUIRREL_AUTH_OIDC_ADMIN_GROUP=wiki-admins \
  -e PLUGIN_SQUIRREL_AUTH_OIDC_EDITOR_GROUP=wiki-editors \
  -v squirrel-data:/app/App_Data \
  squirrel-wiki:latest

Lucene.NET Search Plugin

High-performance full-text search using Lucene.NET.

Environment Variable Description Required Default
PLUGIN_SQUIRREL_WIKI_PLUGINS_LUCENE_ENABLED Enable the Lucene search plugin No true
PLUGIN_LUCENE_INDEX_PATH Path to the Lucene search index directory No SearchIndex

The Lucene plugin is included by default and provides advanced search features including:

  • Fast full-text search
  • Fuzzy matching
  • Field boosting
  • Relevance scoring
  • Search suggestions
  • Similarity search

Example Configuration

docker run -d \
  --name squirrel-wiki \
  -p 8080:8080\
  -e PLUGIN_SQUIRREL_WIKI_PLUGINS_LUCENE_ENABLED=true \
  -e PLUGIN_LUCENE_INDEX_PATH=SearchIndex \
  -v squirrel-data:/app/App_Data \
  squirrel-wiki:latest

Table of Contents Plugin

Generates a table of contents from markdown headings using the {{toc}} placeholder.

Environment Variable Description Required Default
PLUGIN_SQUIRREL_WIKI_PLUGINS_MARKDOWN_TABLEOFCONTENTS_ENABLED Enable the Table of Contents plugin No true
PLUGIN_TOC_MAX_DEPTH Maximum heading level to include in TOC (1-6) No 3

The Table of Contents plugin is included by default. To use it, enable the plugin and simply add {{toc}} anywhere in your markdown content where you want the table of contents to appear.

Example Usage

{{toc}}

# Introduction

This is the introduction...

# Main Content

## Subsection 1

Content here...

## Subsection 2

More content...

Volumes

When running in Docker, mount the following volumes to persist data:

  • /app/App_Data - Application data including database, search index, and uploaded files
  • /app/Plugins/CustomPluginName - Plugin directory (if you want to add a custom plugin)

Health Checks

The application exposes health check endpoints:

  • /health - Basic health check
  • /health/ready - Readiness check (includes database connectivity)

Logging

Logs are written to:

  • Console (stdout/stderr)
  • /app/logs directory (if volume mounted)

Configure logging level via environment variable:

-e Logging__LogLevel__Default=Information

Development

Building from Source

# Restore dependencies
dotnet restore

# Build the solution
dotnet build

# Run the web application
dotnet run --project Squirrel.Wiki.Web

About

Squirrel Wiki

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages