Wiki.js is a Node.js wiki application that supports TLS in two ways: its own built-in HTTPS server, or via a reverse proxy. This article covers both approaches, explains how to configure the correct site URL so that generated links and authentication callbacks work, and shows how to set up OAuth providers with HTTPS redirect URIs.
Wiki.js network architecture
Wiki.js is a Node.js application running on port 3000 by default. It can:
- Serve HTTPS directly — configure a certificate in
config.ymland Wiki.js uses its built-in HTTPS server. - Run behind a reverse proxy — nginx or Caddy terminates TLS, proxies to Wiki.js on localhost:3000.
The built-in HTTPS is suitable for simple deployments. The reverse proxy approach is better for production because it gives you more control over TLS settings, enables HTTP/2 more reliably, and makes certificate renewal easier.
Option A: Built-in TLS
Step 1: Obtain a certificate
certbot certonly --standalone -d wiki.example.com
Copy and fix permissions (Wiki.js runs as the wiki user or the user that starts the process):
mkdir -p /etc/wiki/certs
cp /etc/letsencrypt/live/wiki.example.com/fullchain.pem /etc/wiki/certs/wiki.crt
cp /etc/letsencrypt/live/wiki.example.com/privkey.pem /etc/wiki/certs/wiki.key
chown wiki:wiki /etc/wiki/certs/wiki.crt /etc/wiki/certs/wiki.key
chmod 640 /etc/wiki/certs/wiki.key
Step 2: Configure config.yml
Wiki.js reads config.yml from the application directory (often /etc/wiki/config.yml or /var/wiki/config.yml):
port: 443
bindIP: 0.0.0.0
ssl:
enabled: true
port: 443
provider: custom
# Certificate files
certPath: /etc/wiki/certs/wiki.crt
keyPath: /etc/wiki/certs/wiki.key
# Use Let's Encrypt built-in (alternative to custom files)
# provider: letsencrypt
# domain: wiki.example.com
# subscriberEmail: admin@example.com
db:
type: postgres
host: localhost
port: 5432
user: wiki
pass: db-password
db: wiki
Step 3: Restart Wiki.js and verify
sudo systemctl restart wiki
sudo systemctl status wiki
openssl s_client -connect wiki.example.com:443 -servername wiki.example.com </dev/null 2>&1 \
| openssl x509 -noout -subject -dates
Option B: nginx reverse proxy (recommended)
Step 1: Configure Wiki.js to listen on localhost only
In config.yml:
port: 3000
bindIP: 127.0.0.1
ssl:
enabled: false
Restart Wiki.js.
Step 2: Create nginx configuration
sudo nano /etc/nginx/sites-available/wikijs
server {
listen 80;
server_name wiki.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
http2 on;
server_name wiki.example.com;
ssl_certificate /etc/letsencrypt/live/wiki.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/wiki.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options SAMEORIGIN always;
# Increase upload limit for file attachments
client_max_body_size 50M;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $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_read_timeout 120s;
proxy_buffering off;
}
}
Enable and reload:
sudo ln -s /etc/nginx/sites-available/wikijs /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
Step 3: Configure the Wiki.js site URL
Wiki.js uses the site URL for generating links in pages, emails, and authentication callbacks. Set it in the admin interface:
- Log in to Wiki.js as admin.
- Go to Administration → General.
- Set Site URL to
https://wiki.example.com. - Click Apply.
Or set it in the database before the first start (PostgreSQL example):
UPDATE settings SET value = '"https://wiki.example.com"' WHERE key = 'host';
Why this matters: If the Site URL is set to http://wiki.example.com but you access the site over HTTPS, OAuth callbacks (Google, GitHub, Azure AD) will fail because the redirect URI will not match.
Authentication with OAuth over HTTPS
Wiki.js supports OAuth providers (GitHub, Google, Azure AD, etc.). After enabling HTTPS, update the redirect URIs in each provider.
GitHub OAuth
- Go to GitHub → Settings → Developer Settings → OAuth Apps.
- Find your Wiki.js app.
- Update Authorization callback URL to:
https://wiki.example.com/login/github/callback.
Google OAuth
- Go to Google Cloud Console → APIs & Services → Credentials.
- Edit your OAuth 2.0 client.
- Add
https://wiki.example.com/login/google/callbackto Authorized redirect URIs.
Azure AD
- Go to Azure Portal → App registrations → find your Wiki.js app.
- Under Authentication → Redirect URIs, update or add
https://wiki.example.com/login/azure/callback.
In Wiki.js admin (Administration → Authentication), the strategy configuration will show the correct callback URL automatically once Site URL is set correctly.
Docker Compose deployment with TLS
For Docker-based Wiki.js deployments, add an nginx container:
version: '3.8'
services:
wiki:
image: requarks/wiki:2
environment:
DB_TYPE: postgres
DB_HOST: db
DB_PORT: "5432"
DB_USER: wiki
DB_PASS: db-password
DB_NAME: wiki
ports:
- "127.0.0.1:3000:3000"
depends_on:
- db
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- /etc/letsencrypt:/etc/letsencrypt:ro
depends_on:
- wiki
db:
image: postgres:15
environment:
POSTGRES_USER: wiki
POSTGRES_PASSWORD: db-password
POSTGRES_DB: wiki
volumes:
- wiki_db:/var/lib/postgresql/data
volumes:
wiki_db:
Where nginx.conf references /etc/letsencrypt/live/wiki.example.com/fullchain.pem for the certificate.
Redirecting old HTTP URLs after migration
After switching from HTTP to HTTPS, existing bookmarks and links may use http://. Nginx handles the redirect automatically with the return 301 https:// rule above.
For internal wiki links (markdown links in pages that hardcode http://), use Wiki.js’s search-and-replace to update them:
- Go to Administration → Storage.
- Export all pages to a Git repository.
- Run
find . -name "*.md" -exec sed -i 's|http://wiki\.example\.com|https://wiki.example.com|g' {} \; - Re-import.
Certificate renewal
sudo nano /etc/letsencrypt/renewal-hooks/deploy/wikijs.sh
#!/bin/bash
# For nginx reverse proxy:
systemctl reload nginx
# For built-in TLS (copy cert and restart):
# DOMAIN=wiki.example.com
# cp /etc/letsencrypt/live/${DOMAIN}/fullchain.pem /etc/wiki/certs/wiki.crt
# cp /etc/letsencrypt/live/${DOMAIN}/privkey.pem /etc/wiki/certs/wiki.key
# chown wiki:wiki /etc/wiki/certs/wiki.crt /etc/wiki/certs/wiki.key
# chmod 640 /etc/wiki/certs/wiki.key
# systemctl restart wiki
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/wikijs.sh
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
| OAuth login fails with “redirect_uri_mismatch” | Provider still has http:// callback URL | Update redirect URIs in OAuth provider settings |
| Page images/attachments show http:// URLs | Site URL set to http:// | Update Site URL in Administration → General |
| WebSocket connection fails | nginx missing Upgrade headers | Add proxy_set_header Upgrade $http_upgrade |
| 413 Request Entity Too Large on file upload | nginx client_max_body_size too small | Set client_max_body_size 50M |
| Built-in TLS: “EACCES: permission denied” on port 443 | Node.js cannot bind to port 443 | Use port 3443 or set cap_net_bind_service or use nginx |
| Cookie not being set | SameSite/Secure cookie flags | Ensure you are accessing over HTTPS; check browser console |
Summary
Wiki.js TLS with nginx is straightforward: configure nginx to terminate TLS on port 443, proxy to Wiki.js on port 3000, and set the Site URL to https://wiki.example.com in the admin panel. The Site URL setting is the most impactful — it controls OAuth callback URLs, email links, and all generated URLs. Update redirect URIs in every OAuth provider after the HTTPS migration. Certificate renewal is handled by reloading nginx.