--- title: "How to Install BookStack on Ubuntu 24.04 with Nginx" description: "Install BookStack on Ubuntu 24.04 with Nginx, PHP-FPM 8.3 and MariaDB, secure it with Let's Encrypt, configure email, and set up updates and nightly backups." category: "Web Applications Hosting" language: en source: https://cubepath.com/docs/web-applications-hosting/bookstack-documentation-platform-installation updated: 2026-09-25 --- # How to Install BookStack on Ubuntu 24.04 with Nginx 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: ```bash 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: ```bash php -v composer --version ``` ```output PHP 8.3.6 (cli) (built: ...) (NTS) ... Composer version 2.7.1 ... ``` Open the firewall for SSH and web traffic: ```bash 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): ```bash sudo mariadb-secure-installation ``` Open the MariaDB shell: ```bash sudo mariadb ``` Create a database and a user for BookStack, replacing `your_db_password` with a strong password: ```sql 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: ```bash mariadb -u bookstack -p -e 'SHOW DATABASES;' ``` ```output +--------------------+ | 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: ```bash 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: ```bash cd /var/www/bookstack composer install --no-dev ``` ```output ... Generating optimized autoload files ... ``` ## Step 4 - Configuring the environment file BookStack reads its settings from `.env`. Create it from the example: ```bash 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: ```ini 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: ```bash php artisan key:generate --force ``` ```output 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: ```bash 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: ```bash cd /var/www/bookstack sudo -u www-data php artisan migrate --force ``` ```output INFO Preparing database. ... INFO Running migrations. ... ``` ## Step 6 - Configuring Nginx and HTTPS Allow larger uploads in PHP-FPM with a small override file: ```bash sudo nano /etc/php/8.3/fpm/conf.d/99-bookstack.ini ``` ```ini upload_max_filesize = 50M post_max_size = 50M memory_limit = 256M ``` Restart PHP-FPM: ```bash 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: ```bash sudo nano /etc/nginx/sites-available/bookstack ``` ```nginx 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: ```bash 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: ```bash 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: ```bash curl -sI https://your_domain/login | head -n 1 ``` ```output HTTP/2 200 ``` ## Step 7 - Securing the admin account The migrations create a default administrator with the email `admin@admin.com` 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: ```bash nano /var/www/bookstack/.env ``` Replace the `MAIL_` lines with your SMTP provider's details: ```ini 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: ```bash 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): ```bash 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: ```bash sudo nano /usr/local/sbin/bookstack-backup ``` ```bash #!/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: ```bash sudo chmod 700 /usr/local/sbin/bookstack-backup sudo /usr/local/sbin/bookstack-backup sudo ls -lh /var/backups/bookstack ``` ```output -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: ```bash 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 -- `. ## 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.