PlainPage is a self-hosted wiki app that embodies simplicity, ease of use, and privacy. It offers a plain and simplistic user experience while providing essential wiki-like functionality. It adheres to the π KISS principle, focusing on delivering a straightforward and efficient user experience without unnecessary complexities.
Powered by Go, Vue/Nuxt. Made with π
-
Markdown Syntax β¨ Create and edit your content using Markdown syntax, a lightweight and intuitive markup language that makes writing and formatting a breeze.
-
Plain File Storage π€© PlainPage utilizes a plain file storage system, your content is stored in a simple and accessible format.
-
Snappy User Interface π PlainPage offers a snappy and responsive user interface, allowing you to focus on your content and enhancing your productivity.
-
Privacy-First π PlainPage does not track your usage, collect statistics, or employ any analytics tools. Your data remains private and under your control.
-
Access Rights π PlainPage provides robust access control with powerful yet user-friendly ACLs. You can easily manage and assign permissions to your content, ensuring that the right people have access to the right information.
- Localization: English, German, Spanish
- Supports light/dark mode
- Embedded full text search
- Not optimized for access by machines, e.g., search engines
- Concurrent/conflicting edits are not prevented
Trying out PlainPage is as simple as it can be:
Option 1: Download Binary
- Download the latest release,
- Run the PlainPage executable, and
- Browse to http://localhost:8080/
Option 2: Docker
docker run --rm -p 8080:8080 ghcr.io/tfabritius/plainpageCreate a docker-compose.yml file:
services:
plainpage:
image: ghcr.io/tfabritius/plainpage:latest
container_name: plainpage
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- ./data:/dataStart the service:
docker compose up -dMake sure to persist your data by mounting a volume or local folder to the container's /data directory:
docker run -d \
--name plainpage \
--restart unless-stopped \
-p 8080:8080 \
-v /path/on/host:/data \
ghcr.io/tfabritius/plainpageWhen running in production you typically want to run a reverse proxy in front of PlainPage that provides encryption via TLS/SSL. Popular choices are:
π‘ Tip: As usual, backup your data regularly!
PlainPage executable has very few configuration settings with sensible default values that can be configured by environment variables (or a .env file):
# Directory to store data, defaults to `data` directory next to executable
DATA_DIR=./data
# Port to listen on, defaults to 8080
PORT=8080All other settings can be done via the UI or by editing the config.yml file in the data directory:
# Title of the app - customize your installation
appTitle: "My app"
# Access rules independent from individual pages/folders
acl: []
# Secret for signing JWT tokens (auto-generated, keep it safe!)
jwtSecret: "..."
# Enables anonymous registration with admin rights (auto-disabled after first registration)
setupMode: falsejwtSecret is used to sign and verify JWT tokens. It is generated automatically. Keep it safe! For security reasons it's neither exposed nor can be changed via UI.
PlainPage stores your information on pages. Pages are organized into folders that can be nested.
Pages are written in Markdown syntax with support for:
- Headings, paragraphs, and text formatting
- Lists (ordered and unordered)
- Links and images
- Code blocks with syntax highlighting
- Tables
Access rights can be modified by administrators.
PlainPage's permission system is powerful yet easy to use. If you don't adjust it, all registered users will be able to access and edit all content.
Permissions can be defined for both pages and folders. By default, permissions for pages and folders are inherited from the parent folder.
- A page
/folder/pagewill inherit its access rights from the folder/folder, unless explicit permissions are defined for this page. - The folder
/folderwill itself inherit its permissions from the parent folder/, unless permissions are defined for/folder. - The home folder
/cannot inherit permissions.
Permissions can be granted to:
- Individual users
- All registered users
- Anonymous users (not logged in)
Permissions are controlled with fine-grained operations:
| Permission | Description |
|---|---|
| Read | Allows users to access pages and folders |
| Write | Allows users to change pages and folders (e.g., create new ones) |
| Delete | Allows users to delete pages and folders completely |
This allows you to restrict certain content to specific users and/or expose certain content publicly.
Besides pages and folders, PlainPage allows you to grant additional permissions:
-
Register β Allows creating new users in PlainPage. This way you can control whether new users can create their own account and whether existing users can create additional user accounts. By default, only administrators can register new users.
-
Admin β Grants special rights, e.g., to change permissions. Users with this privilege are automatically granted all other possible permissions on all content.
| Shortcut | Action |
|---|---|
Ctrl+K, / |
Search |
E |
Edit page |
Ctrl+S |
Save page (when editing) |
Esc |
Cancel edit / close full screen mode |
Ctrl+Backspace |
Delete current page/folder |
PlainPage takes security seriously:
- Password Storage β User passwords are hashed using Argon2, the winner of the Password Hashing Competition.
- Authentication β JWT (JSON Web Tokens) are used for session management.
- No Tracking β No analytics, telemetry, or external requests are made.
- Always run PlainPage behind a reverse proxy with TLS/SSL in production
- Keep the
jwtSecretinconfig.ymlsecure and backed up - Use strong passwords for user accounts
- Regularly backup your data directory
- Keep PlainPage updated to the latest version
π€© You're welcome to contribute to PlainPage!
During development, there are two processes running:
1. Nuxt Frontend
cd frontend
pnpm install
pnpm dev2. Go Backend
cd backend
go run .Browse to http://localhost:3000. Nuxt will proxy requests to the backend.
In production, the static frontend files are served together with the backend:
1. Generate static frontend files
cd frontend
pnpm install
pnpm generate2. Build Go backend (with embedded frontend)
cd backend
go generate ./...
go build .The resulting binary can be found in the backend directory. Browse to http://localhost:8080.
Backend Tests
cd backend
go test ./...Frontend Linting and Typechecking
cd frontend
pnpm lint
pnpm typecheck- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests to ensure everything works
- Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
If you find PlainPage useful, please consider giving it a β on GitHub!