Modern and lightweight Wiki.js

When it comes to self-hosted wiki platforms, MediaWiki has been a solid and proven solution for many years. However, for modern use cases and user expectations, Wiki.js offers a more approachable and visually appealing alternative. It combines structured content management with a modern admin UI and flexible authentication and storage options.

Running Wiki.js inside an LXC container on a Red Hat-based distribution (RHEL, AlmaLinux, Rocky Linux, or CentOS) is lightweight, efficient, and easy to maintain. Wiki.js is built on Node.js and relies on PostgreSQL (or other supported relational databases) for data storage. Its web interface is powered by modern web technologies, providing a responsive and intuitive experience for both contributors and administrators.

Containerization with LXC ensures isolation and minimal overhead, while Nginx handles secure HTTPS access with a simple reverse proxy setup.

System requirements

Wiki.js runs comfortably even on very modest infrastructure. Here’s what I used for this container setup:

ComponentRequirementNotes
OSRHEL 9 derivative (AlmaLinux / Rocky / CentOS)Minimal installation recommended
CPU1 vCPUWiki.js is light on CPU
RAM512 MB (1 GB recommended)Works fine for small teams
Storage~300 MB base, 1–2 GB with contentMainly database and uploads
NetworkHTTP(S) via Nginx reverse proxyNo direct exposure of port 3000
Container TypeUnprivileged LXCBetter isolation and easy snapshots

System preparation

Before starting the installation, I prepared the system with basic updates, tools, and firewall rules.

sudo dnf update -y
sudo dnf install wget curl nano vim-enhanced unzip tar net-tools -y

PostgreSQL installation and configuration

Install PostgreSQL and initialize the database:

sudo dnf install -y postgresql-server postgresql-contrib
sudo postgresql-setup --initdb
sudo systemctl enable postgresql
sudo systemctl start postgresql

Next, create the Wiki.js database and user explicitly over the default entries. This ensures that Wiki.js can connect without conflicts with the default postgres user or local ident authentication:

sudo -i -u postgres psql

-- Create the database
CREATE DATABASE wikijs;

-- Create the user with an encrypted password
CREATE USER wikijs WITH ENCRYPTED PASSWORD 'CHANGE-THIS-PASSWORD';

-- Grant privileges to the user
GRANT ALL PRIVILEGES ON DATABASE wikijs TO wikijs;

-- Assign the database owner explicitly
ALTER DATABASE wikijs OWNER TO wikijs;
\q

Update the pg_hba.conf file above the default entries to enforce password authentication for the Wiki.js user:

sudo nano /var/lib/pgsql/data/pg_hba.conf

Add these three lines at the top of the file, above any default host entries:

# Wiki.js database access
host    wikijs      wikijs      127.0.0.1/32      md5
host    wikijs      wikijs      ::1/128           md5

Important: Placing these entries above the defaults ensures that PostgreSQL applies the intended authentication method for the Wiki.js user instead of falling back to ident or other default rules. If the default rules come first, they may override your configuration, causing login failures.

Finally, reload PostgreSQL to apply the changes:

sudo systemctl restart postgresql

Node.js installation

Wiki.js requires Node.js 20 or higher. On RHEL-based systems, the module streams make this simple:

sudo dnf module list nodejs
sudo dnf module enable nodejs:20
sudo dnf install nodejs

# Verify the installation
node --version

Wiki.js installation

Create the installation folder and set ownership:

sudo mkdir -p /var/www/wikijs
sudo chown $USER:$USER /var/www/wikijs
cd /var/www/wikijs

Download and extract Wiki.js:

wget https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz
tar xzf wiki-js.tar.gz

Copy and edit the configuration file:

cp config.sample.yml config.yml
nano config.yml

Adjust database settings to match the user and database you created:

host: localhost
port: 5432
user: wikijs
pass: CHANGE-THIS-PASSWORD
db: wikijs
ssl: false

Bind Wiki.js to localhost:

bindIP: 127.0.0.1

Test the initial run:

node server

Create a systemd service for permanent operation:

sudo nano /etc/systemd/system/wikijs.service

Paste the following:

[Unit]
Description=Wiki.js
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/node server
Restart=always
User=root
Environment=NODE_ENV=production
WorkingDirectory=/var/www/wikijs

[Install]
WantedBy=multi-user.target

Activate the service:

sudo systemctl daemon-reload
sudo systemctl enable wikijs
sudo systemctl start wikijs

Nginx Reverse Proxy and SSL

To expose Wiki.js safely to the outside world, I used Nginx as a reverse proxy and integrated SSL using certificates from our internal PKI. This setup keeps the Wiki.js service listening only on localhost and lets Nginx handle all HTTPS traffic.

Install Nginx

sudo dnf install -y nginx
sudo systemctl enable nginx
sudo systemctl start nginx

Adjust SELinux (if enabled)

If SELinux is enforcing, allow Nginx to connect to the Wiki.js port and give proper file permissions:

sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/wikijs(/.*)?"
sudo restorecon -Rv /var/www/wikijs
sudo semanage port -a -t http_port_t -p tcp 3000
sudo setsebool -P httpd_can_network_connect 1

Configure Nginx

Create the configuration file:

sudo nano /etc/nginx/conf.d/wikijs.conf

Paste the following:

# Redirect HTTP to HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name wiki.example.com;
    return 301 https://$server_name$request_uri;
}

# HTTPS server
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name wiki.example.com;

    root /var/www/wikijs;

    access_log  /var/log/nginx/wiki.access.log;
    error_log   /var/log/nginx/wiki.error.log;

    http2_push_preload on;

    ssl_certificate /etc/nginx/conf.d/wiki01.examplecorp.crt;
    ssl_certificate_key /etc/nginx/conf.d/wiki01.examplecorp.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384';
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout 1d;

    ssl_stapling on;
    ssl_stapling_verify on;

    location / {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://127.0.0.1:3000;
    }
}

Adjust main Nginx settings

Increase the server name hash bucket size to avoid warnings:

sudo nano /etc/nginx/nginx.conf

  server_names_hash_bucket_size 64; <-- Add the following line before include
  include /etc/nginx/conf.d/*.conf;

Test and reload Nginx

sudo nginx -t
sudo systemctl reload nginx

Finishing the installation

Open your browser at:

https://wiki.example.com

The Wiki.js setup wizard will guide you through creating the admin account, configuring storage, and authentication options. Once complete, your Wiki.js instance is ready to use.

In-Place upgrade

Upgrading Wiki.js is straightforward. Backup your configuration first:

sudo systemctl stop wikijs
cd /var/www/
cp wikijs/config.yml ~/config.yml.bak
rm -rf wikijs/*
wget https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz
tar xzf wiki-js.tar.gz -C ./wikijs
cd wikijs
cp ~/config.yml.bak ./config.yml
node server   # quick check
CTRL+C
sudo systemctl start wikijs

Backup strategy

For reliable recovery, back up both the database and application files.

Database backup:

pg_dump -U wikijs -h localhost wikijs > ~/wikijs_backup.sql

Application files backup:

tar -czvf ~/wikijs_www_backup.tar.gz /var/www/wikijs

Schedule these backups with cron or an automated backup script.

Final Thoughts

Wiki.js proves its value through usability and efficiency. Editing content, adding images or tables, and managing permissions is straightforward, which saves time in daily work. Running it in a containerized environment is lightweight and easy to maintain, and the interface is intuitive for contributors.

A small note of impatience: version 3.x has been awaited for quite some time, and some enhancements are still pending. Nevertheless, the current version is stable, reliable, and fits my workflow well, providing a modern and practical wiki experience.