BookStack is an open source documentation platform built on Laravel that organizes content into shelves, books, chapters and pages, with a WYSIWYG and Markdown editor, full-text search and role-based permissions. In this tutorial you will install BookStack on Ubuntu 24.04 from its official Git release branch, serve it with Nginx and PHP-FPM 8.3 over HTTPS, configure outgoing email, and set up a clean update procedure and nightly backups.

Prerequisites

To follow this guide you need:

  • A server running Ubuntu 24.04 LTS, for example a CubePath VPS, with at least 1 GB of RAM (2 GB recommended) and 10 GB of free disk space.
  • A non-root user with sudo privileges. The commands use $USER, so run them as that user.
  • A domain or subdomain (this guide uses your_domain) with a DNS A record pointing to your_server_ip.
  • Ports 80 and 443 open to the internet.

Step 1 - Installing Nginx, PHP and MariaDB

BookStack requires PHP 8.2 or newer with a handful of extensions, a MySQL-compatible database and Composer to install its PHP dependencies. Ubuntu 24.04 provides all of them:

sudo apt update
sudo apt install nginx mariadb-server git unzip composer php-fpm php-cli php-mysql php-xml php-mbstring php-curl php-gd php-zip

Check the PHP and Composer versions:

php -v
composer --version
PHP 8.3.6 (cli) (built: ...) (NTS)
...
Composer version 2.7.1 ...

Open the firewall for SSH and web traffic:

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable

Step 2 - Creating the database

MariaDB on Ubuntu authenticates root through the Unix socket, so sudo mariadb opens a shell without a password. Run the hardening script first (answer n to switching to unix_socket authentication, since it is already in use, and Y to the rest):

sudo mariadb-secure-installation

Open the MariaDB shell:

sudo mariadb

Create a database and a user for BookStack, replacing your_db_password with a strong password:

CREATE DATABASE bookstack CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'bookstack'@'localhost' IDENTIFIED BY 'your_db_password';
GRANT ALL PRIVILEGES ON bookstack.* TO 'bookstack'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Confirm the account works:

mariadb -u bookstack -p -e 'SHOW DATABASES;'
+--------------------+
| Database           |
+--------------------+
| bookstack          |
| information_schema |
+--------------------+

Step 3 - Downloading BookStack

BookStack publishes every stable version on the release branch of its repository, which also makes updates a simple git pull. Create the application directory owned by your user, with the www-data group so PHP-FPM can read it:

sudo install -d -o "$USER" -g www-data /var/www/bookstack
git clone https://github.com/BookStackApp/BookStack.git --branch release --single-branch /var/www/bookstack

Install the PHP dependencies. --no-dev skips testing tools that are not needed in production:

cd /var/www/bookstack
composer install --no-dev
...
Generating optimized autoload files
...

Step 4 - Configuring the environment file

BookStack reads its settings from .env. Create it from the example:

cp .env.example .env
nano .env

Set the public URL and the database credentials from Step 2. Leave the other lines as they are for now:

APP_URL=https://your_domain

DB_HOST=localhost
DB_DATABASE=bookstack
DB_USERNAME=bookstack
DB_PASSWORD=your_db_password

APP_URL must match the address users type in the browser exactly, including https:// and without a trailing slash, otherwise styles and links break.

Generate the application key, which encrypts sessions and stored secrets. The --force flag is needed because BookStack runs in production mode:

php artisan key:generate --force
   INFO  Application key set successfully.

Step 5 - Setting permissions and creating the schema

The code stays owned by your user and is only readable by PHP-FPM. BookStack needs write access to three directories: storage (logs, cache, sessions, attachments), bootstrap/cache and public/uploads (images). The .env file holds the database password, so only your user and the www-data group can read it:

sudo chmod -R 755 /var/www/bookstack
sudo chmod -R 775 /var/www/bookstack/storage /var/www/bookstack/bootstrap/cache /var/www/bookstack/public/uploads
sudo chmod 640 /var/www/bookstack/.env

Run the database migrations as www-data, so any files they create in storage belong to the web server:

cd /var/www/bookstack
sudo -u www-data php artisan migrate --force
   INFO  Preparing database.
   ...
   INFO  Running migrations.
   ...

Step 6 - Configuring Nginx and HTTPS

Allow larger uploads in PHP-FPM with a small override file:

sudo nano /etc/php/8.3/fpm/conf.d/99-bookstack.ini
upload_max_filesize = 50M
post_max_size = 50M
memory_limit = 256M

Restart PHP-FPM:

sudo systemctl restart php8.3-fpm

Create the Nginx server block. The document root is the public directory, so the rest of the code, including .env, is never reachable over HTTP:

sudo nano /etc/nginx/sites-available/bookstack
server {
    listen 80;
    listen [::]:80;
    server_name your_domain;

    root /var/www/bookstack/public;
    index index.php;
    client_max_body_size 50m;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }

    location ~ /\.(?!well-known) {
        deny all;
    }
}

Enable the site, remove the default one and reload Nginx:

sudo ln -s /etc/nginx/sites-available/bookstack /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx

Request a Let's Encrypt certificate. Certbot adds the HTTPS listener and a redirect from HTTP:

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d your_domain
sudo certbot renew --dry-run

Check that the login page is served over HTTPS:

curl -sI https://your_domain/login | head -n 1
HTTP/2 200

Step 7 - Securing the admin account

The migrations create a default administrator with the email [email protected] and the password password. Log in at https://your_domain with those credentials, open the user menu at the top right, choose My Account (or Edit Profile), and change both the email address and the password immediately.

Then review Settings > Features & Security. For an internal knowledge base, keep Allow public access disabled and decide whether people may register themselves or only be invited by an administrator from Settings > Users.

Step 8 - Configuring outgoing email

BookStack sends emails for user invitations, password resets and notifications. Open .env again:

nano /var/www/bookstack/.env

Replace the MAIL_ lines with your SMTP provider's details:

MAIL_DRIVER=smtp
MAIL_FROM=bookstack@your_domain
MAIL_FROM_NAME="BookStack"
MAIL_HOST=smtp.your_provider.com
MAIL_PORT=587
MAIL_USERNAME=your_smtp_user
MAIL_PASSWORD=your_smtp_password
MAIL_ENCRYPTION=null

On port 587, STARTTLS is negotiated automatically when the server supports it. If your provider uses implicit TLS on port 465, set MAIL_PORT=465 and MAIL_ENCRYPTION=tls.

Clear the cached configuration so BookStack picks up the change:

cd /var/www/bookstack
sudo -u www-data php artisan config:clear

Go to Settings > Maintenance and click Send Test Email. The message is delivered to the email address of your account.

Step 9 - Updating BookStack

New releases are published on the release branch. To update, pull the latest code, refresh dependencies, run migrations and clear the caches. Take a backup first (Step 10):

cd /var/www/bookstack
git pull origin release
composer install --no-dev
sudo -u www-data php artisan migrate --force
sudo -u www-data php artisan cache:clear
sudo -u www-data php artisan config:clear
sudo -u www-data php artisan view:clear

The installed version appears at the bottom of Settings. Read the release notes on the BookStack blog before each update, since some versions include manual steps.

Step 10 - Scheduling backups

A BookStack backup needs the database, the .env file, uploaded images in public/uploads, attachments in storage/uploads and any custom theme in themes. Create a backup script:

sudo nano /usr/local/sbin/bookstack-backup
#!/usr/bin/env bash
set -euo pipefail
umask 077

APP_DIR=/var/www/bookstack
BACKUP_DIR=/var/backups/bookstack
STAMP=$(date +%F-%H%M)

mkdir -p "$BACKUP_DIR"

# Runs as root, so MariaDB authenticates through the Unix socket
mariadb-dump --single-transaction --default-character-set=utf8mb4 bookstack \
  | gzip > "$BACKUP_DIR/bookstack-db-$STAMP.sql.gz"

tar -czf "$BACKUP_DIR/bookstack-files-$STAMP.tar.gz" -C "$APP_DIR" \
  .env public/uploads storage/uploads themes

find "$BACKUP_DIR" -type f -mtime +14 -delete

Make it executable, run it and list the result:

sudo chmod 700 /usr/local/sbin/bookstack-backup
sudo /usr/local/sbin/bookstack-backup
sudo ls -lh /var/backups/bookstack
-rw------- 1 root root 240K Sep 25 12:10 bookstack-db-2026-09-25-1210.sql.gz
-rw------- 1 root root 3.4M Sep 25 12:10 bookstack-files-2026-09-25-1210.tar.gz

Schedule it every night:

echo '45 2 * * * root /usr/local/sbin/bookstack-backup' | sudo tee /etc/cron.d/bookstack-backup

To restore on a fresh install, import the SQL dump into the new database, extract the files archive into /var/www/bookstack, and run sudo -u www-data php artisan migrate --force. Keep a copy of the backups off the server.

Troubleshooting

  • The page loads without styles or links point to the wrong host: APP_URL in .env does not match the URL in the browser. Fix it, then run sudo -u www-data php artisan config:clear.
  • HTTP 500 after installation or an update: check /var/www/bookstack/storage/logs/laravel.log. "Permission denied" errors mean the chmod 775 from Step 5 needs to be run again on storage, bootstrap/cache and public/uploads.
  • Image uploads fail for large files: raise upload_max_filesize and post_max_size in /etc/php/8.3/fpm/conf.d/99-bookstack.ini and client_max_body_size in Nginx, then restart PHP-FPM and reload Nginx.
  • git pull refuses to run because of local changes: you edited a tracked file. Move customizations to the themes directory, which BookStack provides for that purpose, and restore the file with git checkout -- <file>.

Conclusion

BookStack is now running on Ubuntu 24.04 behind Nginx with HTTPS, with a secured admin account, working email, a repeatable update procedure and nightly backups. Next, create a shelf and your first book, define roles with per-book permissions under Settings > Roles, and, if your organization uses a directory service, connect BookStack to LDAP, SAML2 or OpenID Connect by following the authentication section of the official documentation.