Back to blog
Blog

Run BookStack on a VPS With Docker and TLS

Run BookStack on a VPS behind HTTPS with Docker Compose, reverse proxy, backups, and safe updates for an internal team wiki.

By Anurag Singh
Updated on Oct 31, 2026
Category: Blog
Share article
Run BookStack on a VPS With Docker and TLS

Most “team wiki” projects don’t fail because the software is bad. They fail because logins are scattered across tools. Docs get buried in chat, and nobody trusts the permissions model.

BookStack tackles those practical problems. It gives you a clear structure for SOPs, runbooks, and internal docs. It does this without forcing your team into a new mental model.

If you want to run BookStack on a VPS, you keep the data on infrastructure you control. You can put it behind HTTPS and operate it like a production service.

That means monitoring, backups, and upgrades you do on purpose.

This is an open-source spotlight for people who run websites, apps, and servers. You’ll get the “why,” a quick reality check against hosted options, and a deployment blueprint using Docker Compose, Nginx, and Let’s Encrypt on a Linux VPS.

Why BookStack works well as an internal wiki

BookStack is an open-source documentation platform built around a simple hierarchy: Books contain Chapters, and chapters contain Pages. That sounds basic because it is. That simplicity is the point.

Teams need predictable places to put things. “Onboarding,” “Incident response,” and “Customer runbooks” become books, not a messy pile of tags.

You also get versioned page history, full-text search, file/image attachments, and granular permissions.

Authentication options include local accounts and common SSO patterns. LDAP and SAML are available via supported configuration/plugins. This matters once the wiki becomes part of daily work.

License note: BookStack is open source under the MIT License. It’s permissive, business-friendly, and uncomplicated for internal deployments.

Who should run BookStack (and who shouldn’t)

BookStack is a good fit if you want a “team handbook” style wiki with a clear IA (information architecture). It tends to work well for:

  • Small teams that need SOPs, checklists, and shared troubleshooting notes.
  • Agencies and resellers documenting recurring client work and handoffs.
  • Ops teams maintaining runbooks, maintenance windows, and onboarding docs.

If your docs workflow revolves around Markdown, pull requests, and Git history, a Git-backed documentation system may fit better.

BookStack can still serve developers. It’s strongest when non-developers contribute often.

Quick comparison: BookStack vs hosted/proprietary wiki tools

Most teams land on BookStack after living in one of these camps:

  • Hosted workspaces (like Notion-style tools): quick to launch, but long-term cost creep, export anxiety, and permissions sprawl usually show up later.
  • Enterprise wikis (often Atlassian-style): feature-rich, but can feel heavy if you just need a clean internal knowledge base.

Self-hosting BookStack buys you control. You own your domain, backups, retention policy, and privacy model (VPN, internal network, or IP allowlists).

The tradeoff is owning the basics: updates, monitoring, and backups. That’s fine on a VPS if you run it like a service.

Don’t treat it like “a container someone started once.”

What you need to run BookStack on a VPS (resources and OS)

Most BookStack installs hit RAM and database I/O before CPU. For many small teams, these ranges are realistic:

  • Minimum: 1 vCPU / 2 GB RAM / 30 GB SSD
  • Comfortable: 2 vCPU / 4 GB RAM / 60+ GB SSD (room for attachments and growth)

On the host, stick with a server distro you already know how to operate. Ubuntu Server LTS and Debian stable are common picks.

If you expect to add monitoring, backups, or a mail relay later, 4 GB RAM keeps the VPS from feeling tight.

If you want an uncomplicated base to build on, start with a HostMyCode VPS. If you’d rather not handle OS patching and routine server care, managed VPS hosting is a pragmatic choice for internal tools people depend on every day.

Deployment blueprint (Docker Compose + MariaDB)

BookStack runs neatly under Docker Compose. You typically run one container for BookStack and one for the database. MariaDB is a common choice.

The setup below assumes:

  • Your server runs Ubuntu or Debian.
  • Docker Engine and the Docker Compose plugin are installed.
  • You have a DNS name like wiki.example.com pointing at your VPS.

If DNS is part of the rollout, treat it like a real cutover. Use a low TTL and validate in parallel.

This guide on DNS cutover for zero-downtime migrations applies even to “internal” tools that still need working TLS.

Suggested directory layout

Keep the Compose file, environment, and persistent volumes in one predictable location:

  • /opt/bookstack/compose.yml
  • /opt/bookstack/.env
  • /opt/bookstack/data/ (uploads, app storage)
  • /opt/bookstack/db/ (database volume, if using bind mounts)

Example Docker Compose file

This is a conservative baseline. It doesn’t pin to a specific BookStack tag here because you should pick a pinning strategy (covered in the upgrade section).

Use environment variables for secrets, and keep them out of Git.

services:
  db:
    image: mariadb:11
    container_name: bookstack-db
    environment:
      - MARIADB_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
      - MARIADB_DATABASE=${DB_NAME}
      - MARIADB_USER=${DB_USER}
      - MARIADB_PASSWORD=${DB_PASSWORD}
    volumes:
      - ./db:/var/lib/mysql
    restart: unless-stopped

  bookstack:
    image: lscr.io/linuxserver/bookstack
    container_name: bookstack
    depends_on:
      - db
    environment:
      - PUID=1000
      - PGID=1000
      - APP_URL=https://${BOOKSTACK_FQDN}
      - DB_HOST=db
      - DB_DATABASE=${DB_NAME}
      - DB_USERNAME=${DB_USER}
      - DB_PASSWORD=${DB_PASSWORD}
    volumes:
      - ./data:/config
    restart: unless-stopped

Why the linuxserver image? It’s widely used and documented for self-hosted patterns, including volume paths and UID/GID mapping.

If you prefer an upstream image, that’s fine. Just adjust volume paths and environment variable expectations.

Example .env file (keep it private)

BOOKSTACK_FQDN=wiki.example.com
DB_ROOT_PASSWORD=use-a-long-random-string
DB_NAME=bookstack
DB_USER=bookstack
DB_PASSWORD=use-a-long-random-string

Bring it up:

cd /opt/bookstack
docker compose up -d

At this point, BookStack is running on an internal Docker network. Don’t expose the container directly to the internet.

Put a reverse proxy in front of it. Terminate TLS properly.

Reverse proxy + HTTPS (Nginx + Let’s Encrypt)

Even for internal tools, HTTPS isn’t optional. It protects logins, session cookies, and API calls.

It also prevents browser warnings that train people to click through security prompts.

If you want a reusable TLS checklist, this HostMyCode tutorial is a solid reference: TLS setup guide (2026). The steps below focus on what’s specific to BookStack.

Nginx site config

Create /etc/nginx/sites-available/wiki.example.com and proxy requests to the BookStack container.

If BookStack only listens on the internal Docker network, you have two options. You can proxy to that network, or publish a localhost-only port. In practice, localhost-only is usually the least surprising.

Add this to your bookstack service in Compose:

    ports:
      - "127.0.0.1:8085:80"

Then use an Nginx server block like:

server {
  listen 80;
  server_name wiki.example.com;

  location /.well-known/acme-challenge/ {
    root /var/www/letsencrypt;
  }

  location / {
    return 301 https://$host$request_uri;
  }
}

server {
  listen 443 ssl http2;
  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;

  client_max_body_size 50m;

  location / {
    proxy_pass http://127.0.0.1:8085;
    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;
  }
}

Two settings that prevent annoying tickets:

  • client_max_body_size prevents failed uploads for PDFs and screenshots.
  • APP_URL must match the external URL (including https://), or you’ll get mixed content and odd redirects.

Certificate issuance

Use Certbot with the Nginx plugin, or run in webroot mode. Webroot is predictable when you want to keep the flow explicit:

sudo mkdir -p /var/www/letsencrypt
sudo certbot certonly --webroot -w /var/www/letsencrypt -d wiki.example.com

Reload Nginx after the cert exists:

sudo nginx -t && sudo systemctl reload nginx

If you hit a 502 during setup, it’s almost always a proxy target problem. Typical causes include the wrong port, a container that isn’t listening, or firewall rules.

The troubleshooting steps in Nginx 502 Bad Gateway fix on Ubuntu apply directly to BookStack behind Nginx.

Backups that actually let you restore (database + uploads)

A usable BookStack backup has two parts:

  • Database dump (MariaDB): pages, users, permissions, revisions.
  • App storage: uploaded files, images, and config from the BookStack volume.

Back up both on the same schedule. Then do at least one restore test.

Most “we have backups” plans fail because nobody proves they can recover.

Database dump (daily)

Create a backup directory such as /var/backups/bookstack and lock it down:

sudo mkdir -p /var/backups/bookstack
sudo chmod 700 /var/backups/bookstack

Dump the database from the DB container:

docker exec bookstack-db mariadb-dump -u${DB_USER} -p${DB_PASSWORD} ${DB_NAME} > /var/backups/bookstack/bookstack.sql

If you want fewer sharp edges, store credentials in a root-owned file. Then call a script via cron.

For a broader workflow, this guide is a useful companion: Install MariaDB and create secure backups.

Back up uploads/config volume

In this example, BookStack’s persistent data lives under /opt/bookstack/data. A simple, reliable approach is a compressed archive:

tar -C /opt/bookstack -czf /var/backups/bookstack/bookstack-data.tgz data

Keep at least 7–30 days locally. Also copy backups offsite (object storage, another VPS, or a dedicated backup box).

Offsite is what saves you from ransomware and accidental deletion.

Restore drill (the short version)

  • Start fresh containers with the same DB name/user.
  • Restore data/ into place (permissions matter).
  • Import the SQL dump into MariaDB.
  • Verify login and a few random pages/attachments.

If your team is serious about SOPs, write the restore procedure as a page inside BookStack. It’s the one document you’ll be happiest to have later.

Safe upgrades: what to do, what to avoid

BookStack upgrades usually go smoothly. When they fail, the cause is often self-inflicted.

Common mistakes include skipping backups. Others are pulling a new image without reading notes, or missing required migrations (if the image expects them).

A sensible Docker-based upgrade routine looks like this:

  1. Take a fresh DB dump and a fresh archive of the BookStack volume.
  2. Pull images.
  3. Restart with Compose.
  4. Check logs and load the UI.
cd /opt/bookstack
./backup-bookstack.sh
docker compose pull
docker compose up -d
docker logs --tail=200 bookstack

Pinning strategy: For internal tools, don’t run “floating latest” unless you’re comfortable with surprise changes.

Pin to a major version or follow a stable tag policy from your chosen image provider. Then upgrade deliberately.

Maintenance window tip: Put upgrades on a calendar. A wiki becomes a dependency quickly.

If it breaks mid-morning on a weekday, you’ll hear about it.

Operational checks: keep it boring

After launch, the goal is silence. A few routine checks prevent most issues:

  • Disk usage: attachments grow slowly, then all at once. Watch /opt/bookstack/data and your DB volume size.
  • Mail delivery: if you enable invites or notifications, verify SMTP works and messages don’t get junked.
  • Health monitoring: alert if the HTTPS endpoint fails or starts returning 500s.

If you don’t already run uptime checks, you can host them yourself. The setup in Self-host Uptime Kuma on a VPS works well for BookStack.

One HTTPS probe plus a login-page keyword check catches most problems early.

Security baseline for an internal wiki on a VPS

“Internal” isn’t the same as “safe.” Wikis often end up containing the keys to everything else: IPs, vendor details, and operational playbooks.

  • Patch the OS: enable unattended security updates or patch weekly.
  • Restrict access: if the wiki is truly internal, put it behind VPN or IP allowlists.
  • Harden SSH: keys only, disable password auth, limit admin access.

On Ubuntu, a solid baseline is UFW with only 22/80/443 open. Or use 22 and 443 if you don’t need port 80 beyond ACME.

If you need a walkthrough, use Set up UFW firewall on Ubuntu for a web server.

One more practical control: give each operator their own BookStack admin account. Don’t share credentials.

Offboarding is easier, and audit trails stay meaningful.

Where BookStack fits in a real hosting setup

BookStack is rarely the only self-hosted tool you’ll run. Most teams build a small internal stack over time: a wiki, uptime monitoring, automation jobs, and maybe a mail relay or newsletter tool.

If you already automate incident workflows, connect the pieces. Link runbooks automatically, post status updates, or trigger a backup verification step.

If that’s where you’re headed, you’ll want a clear “source of truth” for the automation itself. This post on self-hosting n8n with Docker and HTTPS pairs well with BookStack for documenting automation SOPs.

Summary: a wiki you control, with production habits

BookStack is simple enough that people will use it. It’s also structured enough that your docs don’t collapse into chaos.

If you run BookStack on a VPS with a reverse proxy, HTTPS, and tested backups, you get a knowledge base you can treat like an owned service.

It won’t feel like a fragile side project.

Leave headroom in your VPS size, terminate TLS with Nginx, back up the database and uploads together, and upgrade on a schedule.

That’s the difference between “we have a wiki” and “we rely on our wiki.”

If you want an internal wiki on infrastructure you control, start with a HostMyCode VPS and keep BookStack tucked behind HTTPS. If you’d rather offload patching, baseline monitoring, and routine server care, managed VPS hosting is a practical fit for team-critical internal tools.

FAQ

Should I run BookStack on the same VPS as my public website?

You can, but separation is cleaner. If the wiki contains internal SOPs or credentials, put it on its own VPS or restrict access tightly (VPN/IP allowlist). At minimum, isolate it behind a separate vhost and strong authentication.

What’s the minimum I need for a small team?

For a handful of users and light attachments, 2 GB RAM and SSD storage works. If you expect lots of screenshots, PDFs, or embedded media, plan for more disk before you need it.

Do I need a reverse proxy if I’m using Docker?

Yes, if the service is accessed via a browser. Terminate HTTPS at Nginx (or Caddy) and only publish the app on 127.0.0.1. It keeps ports clean and simplifies TLS renewals.

What should I back up: just the database?

No. You need the database and the BookStack storage volume (uploads and config). Backing up only one of them guarantees an incomplete restore.

How do I update BookStack safely?

Take backups first, pull the new image, restart with Compose, then verify logs and the UI. Avoid floating tags if you want predictable change windows.

Run BookStack on a VPS With Docker and TLS | HostMyCode