Skip to content

Deploying a BookStack App

Introduction

BookStack is a powerful, free, and open-source platform for creating documentation and organizing knowledge. Built on Laravel PHP framework, BookStack provides an intuitive interface for creating, organizing, and sharing documentation through a three-tier hierarchy of Books, Chapters, and Pages. It’s perfect for teams, businesses, and individuals who need a simple yet powerful solution for knowledge management, technical documentation, internal wikis, and collaborative content creation.

Deploying BookStack on Klutch.sh gives you a production-ready, scalable platform with automated deployments from GitHub, persistent storage for your documentation content and uploads, and reliable infrastructure for hosting your knowledge base. Whether you’re building an internal company wiki, creating product documentation, or managing technical guides, this comprehensive guide walks you through deploying BookStack using Docker to ensure a reproducible, secure, and maintainable setup.

This guide covers everything you need to successfully deploy BookStack on Klutch.sh: from creating your production-ready Dockerfile to configuring MySQL database connections, setting up persistent volumes for uploads and storage, managing environment variables securely, configuring the internal port routing, and implementing best practices for security, performance, and scalability.


Prerequisites

Before you begin deploying BookStack on Klutch.sh, ensure you have the following:

  • A Klutch.sh account (access the dashboard here)
  • A GitHub repository for your BookStack deployment project
  • Basic familiarity with Docker, environment variables, and database management
  • A MySQL database (you can provision one on Klutch.sh or use an external managed database service)
  • Understanding of Laravel applications (helpful but not required)

What You’ll Deploy

By the end of this guide, you’ll have:

  • A fully functional BookStack documentation platform running on Klutch.sh
  • Persistent storage for file uploads, images, and application data
  • MySQL database connectivity for storing your documentation content
  • Secure environment variable configuration for credentials and secrets
  • Production-ready setup with proper permissions and security configurations
  • A Docker-based deployment that’s reproducible and easy to maintain
  • HTTP traffic routing configured properly for web access

Understanding BookStack Architecture

BookStack is built on the Laravel PHP framework and requires:

  • PHP 8.1 or higher with required extensions (OpenSSL, PDO, Mbstring, Tokenizer, XML, Ctype, JSON, BCMath, GD)
  • Web server (Apache or Nginx) for serving the application
  • MySQL 5.7+ or MariaDB 10.2+ database for storing documentation, users, and content
  • File storage for uploads, images, attachments, and application assets
  • Composer for PHP dependency management

The application runs on port 80 by default when using Apache. For Klutch.sh deployments with HTTP traffic, you’ll configure the internal port to 80, and traffic will be routed from external port 8000 to your container.


1. Prepare Your BookStack Repository

    1. Create a new GitHub repository for your BookStack deployment.

    2. In your repository root, you’ll create a Dockerfile that defines the container image for BookStack. This ensures reproducible builds and makes deployment consistent.

    3. Keep sensitive data (database credentials, application keys, email passwords) out of your repository. We’ll use Klutch.sh environment variables to manage secrets securely.

    4. Organize your repository structure:

      bookstack-deployment/
      ├── Dockerfile
      ├── .dockerignore
      ├── docker-compose.yml (for local development only)
      ├── entrypoint.sh
      └── README.md
    5. Create a .dockerignore file to exclude unnecessary files from the Docker build:

      .git
      .github
      .env
      .env.*
      node_modules
      storage/logs/*
      storage/framework/cache/*
      storage/framework/sessions/*
      storage/framework/views/*
      public/uploads/*

For more details on setting up your repository and connecting to GitHub, refer to the Klutch.sh Quick Start Guide.


2. Sample Dockerfile for BookStack

Below is a production-ready Dockerfile that sets up BookStack with all required PHP extensions, Composer dependencies, and proper configurations. This Dockerfile uses the official BookStack approach, installing from source and configuring Apache to serve the application.

FROM php:8.2-apache
# Set working directory
WORKDIR /var/www/bookstack
# Install system dependencies and PHP extensions
RUN apt-get update && apt-get install -y \
git \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
libzip-dev \
zip \
unzip \
libfreetype6-dev \
libjpeg62-turbo-dev \
libldap2-dev \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-configure ldap --with-libdir=lib/x86_64-linux-gnu/ \
&& docker-php-ext-install -j$(nproc) \
pdo \
pdo_mysql \
mbstring \
exif \
pcntl \
bcmath \
gd \
zip \
ldap \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Download BookStack from GitHub
ARG BOOKSTACK_VERSION=v23.12
RUN git clone --branch ${BOOKSTACK_VERSION} --depth 1 https://github.com/BookStackApp/BookStack.git /var/www/bookstack \
&& cd /var/www/bookstack \
&& composer install --no-dev --no-plugins --no-scripts
# Configure Apache
RUN a2enmod rewrite \
&& sed -i 's!/var/www/html!/var/www/bookstack/public!g' /etc/apache2/sites-available/000-default.conf \
&& sed -i 's!AllowOverride None!AllowOverride All!g' /etc/apache2/apache2.conf
# Set proper permissions
RUN chown -R www-data:www-data /var/www/bookstack \
&& chmod -R 755 /var/www/bookstack/storage /var/www/bookstack/bootstrap/cache /var/www/bookstack/public/uploads
# Create entrypoint script
COPY entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/entrypoint.sh
EXPOSE 80
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["apache2-foreground"]

Dockerfile Explanation

  • Base Image: Uses php:8.2-apache which includes PHP 8.2 and Apache web server
  • PHP Extensions: Installs all required extensions for BookStack (GD for images, LDAP for authentication, PDO for database)
  • Composer: Copies Composer from official image for dependency management
  • BookStack Source: Clones specific version from GitHub repository
  • Apache Configuration: Configures Apache to serve from BookStack public directory with URL rewriting enabled
  • Permissions: Sets proper ownership and permissions for storage and upload directories
  • Port: Exposes port 80 for HTTP traffic

3. Create the Entrypoint Script

Create an entrypoint.sh file in your repository root to handle initialization tasks like generating the application key, running migrations, and starting the web server:

#!/bin/bash
set -e
# Create .env file from environment variables if it doesn't exist
if [ ! -f /var/www/bookstack/.env ]; then
cat > /var/www/bookstack/.env <<EOF
APP_NAME="${APP_NAME:-BookStack}"
APP_ENV="${APP_ENV:-production}"
APP_KEY="${APP_KEY}"
APP_URL="${APP_URL:-http://localhost}"
APP_DEBUG="${APP_DEBUG:-false}"
DB_CONNECTION=mysql
DB_HOST="${DB_HOST}"
DB_PORT="${DB_PORT:-3306}"
DB_DATABASE="${DB_DATABASE}"
DB_USERNAME="${DB_USERNAME}"
DB_PASSWORD="${DB_PASSWORD}"
MAIL_DRIVER="${MAIL_DRIVER:-smtp}"
MAIL_HOST="${MAIL_HOST:-localhost}"
MAIL_PORT="${MAIL_PORT:-1025}"
MAIL_FROM="${MAIL_FROM:-admin@example.com}"
MAIL_FROM_NAME="${MAIL_FROM_NAME:-BookStack}"
MAIL_ENCRYPTION="${MAIL_ENCRYPTION:-null}"
MAIL_USERNAME="${MAIL_USERNAME:-null}"
MAIL_PASSWORD="${MAIL_PASSWORD:-null}"
STORAGE_TYPE="${STORAGE_TYPE:-local}"
EOF
chown www-data:www-data /var/www/bookstack/.env
fi
# Wait for database to be ready
echo "Waiting for database connection..."
until php /var/www/bookstack/artisan migrate --force 2>/dev/null; do
echo "Database is unavailable - sleeping"
sleep 3
done
echo "Database is up - running migrations"
php /var/www/bookstack/artisan migrate --force
# Generate app key if not set
if [ -z "$APP_KEY" ]; then
php /var/www/bookstack/artisan key:generate --force
fi
# Clear and cache config
php /var/www/bookstack/artisan config:clear
php /var/www/bookstack/artisan cache:clear
php /var/www/bookstack/artisan view:clear
# Ensure permissions are correct
chown -R www-data:www-data /var/www/bookstack/storage /var/www/bookstack/bootstrap/cache /var/www/bookstack/public/uploads
echo "BookStack initialization complete"
# Execute the main command (Apache)
exec "$@"

Entrypoint Script Explanation

  • Environment Configuration: Creates .env file from environment variables
  • Database Waiting: Waits for MySQL to be ready before proceeding
  • Migrations: Runs database migrations to set up tables
  • Application Key: Generates Laravel application key if not provided
  • Cache Clearing: Clears configuration and view caches for fresh start
  • Permissions: Ensures proper file permissions for web server
  • Startup: Executes Apache to serve the application

4. Persistent Storage Configuration

BookStack requires persistent storage for file uploads, images, attachments, and logs. On Klutch.sh, you’ll attach a persistent volume to store this data.

    1. In the Klutch.sh dashboard, navigate to your app configuration.

    2. Under the Volumes section, add a new persistent volume.

    3. Set the mount path to /var/www/bookstack/storage/uploads for storing uploaded files and images.

    4. Set the volume size based on your expected storage needs (start with 5GB and scale up as needed).

    5. Optionally, add another volume for logs at /var/www/bookstack/storage/logs if you want to persist application logs separately.

Important: The mount path is where your application data will persist across deployments. BookStack stores user uploads, images, and attachments in the storage/uploads directory.

For more information about volumes, see the Klutch.sh Volumes Guide.


5. Database Setup

BookStack requires a MySQL database to store documentation content, users, and configuration. You can use a managed MySQL service or deploy your own MySQL container.

Option A: Using an External MySQL Service

If you’re using a managed MySQL service (like AWS RDS, DigitalOcean Managed Databases, or PlanetScale):

    1. Create a new MySQL database instance through your provider.

    2. Create a dedicated database for BookStack (e.g., bookstack_db).

    3. Create a dedicated MySQL user with full privileges on the BookStack database:

      CREATE DATABASE bookstack_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
      CREATE USER 'bookstack_user'@'%' IDENTIFIED BY 'your_secure_password';
      GRANT ALL PRIVILEGES ON bookstack_db.* TO 'bookstack_user'@'%';
      FLUSH PRIVILEGES;
    4. Note the database host, port, database name, username, and password for configuration in Klutch.sh.

    5. Ensure network connectivity between your Klutch.sh app and the database (configure security groups/firewall rules as needed).

Option B: Using Klutch.sh MySQL

For deploying MySQL on Klutch.sh, refer to the MySQL deployment guide.


6. Environment Variables Configuration

Configure the following environment variables in the Klutch.sh dashboard under your app’s settings. These variables are essential for BookStack to connect to the database and operate correctly.

Required Environment Variables

Terminal window
# Application Settings
APP_NAME=BookStack
APP_ENV=production
APP_KEY=base64:YOUR_32_CHARACTER_KEY_HERE
APP_URL=https://example-app.klutch.sh
APP_DEBUG=false
# Database Configuration
DB_HOST=your-mysql-host.example.com
DB_PORT=3306
DB_DATABASE=bookstack_db
DB_USERNAME=bookstack_user
DB_PASSWORD=your_secure_database_password
# Mail Configuration (Optional but recommended)
MAIL_DRIVER=smtp
MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_FROM=bookstack@example.com
MAIL_FROM_NAME=BookStack
MAIL_ENCRYPTION=tls
MAIL_USERNAME=your_smtp_username
MAIL_PASSWORD=your_smtp_password

Environment Variables Explanation

  • APP_KEY: Laravel application encryption key. Generate one using: php artisan key:generate --show or use a base64-encoded 32-character random string
  • APP_URL: The public URL where your BookStack instance will be accessible (e.g., https://example-app.klutch.sh)
  • DB_* variables**: Database connection details from your MySQL setup
  • MAIL_* variables**: SMTP configuration for sending emails (password resets, notifications). Optional for initial setup but recommended for production

Optional Environment Variables

Terminal window
# Storage Configuration
STORAGE_TYPE=local
STORAGE_S3_KEY=your_s3_key
STORAGE_S3_SECRET=your_s3_secret
STORAGE_S3_BUCKET=your_bucket
STORAGE_S3_REGION=us-east-1
# Authentication
AUTH_METHOD=standard
LDAP_SERVER=ldap.example.com
LDAP_BASE_DN=dc=example,dc=com
# Cache Configuration
CACHE_DRIVER=file
SESSION_DRIVER=file

Security Best Practice: Mark sensitive values like APP_KEY, DB_PASSWORD, and MAIL_PASSWORD as secrets in Klutch.sh to prevent them from being logged or displayed in the UI.

For more on Nixpacks environment variables and customization, if you need to override build or start commands, you can set these buildtime/runtime environment variables in Klutch.sh:

  • NIXPACKS_BUILD_CMD: Custom build command
  • NIXPACKS_START_CMD: Custom start command

However, with a Dockerfile, these are not needed as the build and start commands are defined in the Dockerfile itself.


7. Deploying to Klutch.sh

Now that you have your repository configured with the Dockerfile, entrypoint script, and understanding of the required environment variables, let’s deploy BookStack to Klutch.sh.

    1. Push your repository to GitHub: Ensure your Dockerfile, entrypoint.sh, .dockerignore, and README.md are committed and pushed to your GitHub repository.

    2. Access the Klutch.sh dashboard: Log in to klutch.sh/app.

    3. Create a new project (if you haven’t already): Projects help organize related apps and resources.

    4. Create a new app:

      • Click “New App” or “Create App”
      • Select your GitHub repository containing the BookStack Dockerfile
      • Klutch.sh will automatically detect the Dockerfile in your root directory
    5. Configure the app settings:

      • Name: Give your app a meaningful name (e.g., “bookstack-docs”)
      • Branch: Select the Git branch to deploy (usually main or master)
    6. Set up persistent volumes:

      • Navigate to the Volumes section in the app configuration
      • Add a volume with mount path: /var/www/bookstack/storage/uploads
      • Set size: Start with 5GB (adjust based on your needs)
      • Optionally add another volume for logs: /var/www/bookstack/storage/logs
    7. Configure environment variables:

      • Add all the required environment variables listed in Section 6
      • Mark sensitive values (APP_KEY, DB_PASSWORD, MAIL_PASSWORD) as secrets
      • Ensure APP_URL matches your intended domain (e.g., https://example-app.klutch.sh)
    8. Configure network settings:

      • Select HTTP traffic type (not TCP)
      • Set the internal port to 80 (the port Apache listens on inside the container)
      • External traffic from port 8000 will be automatically routed to your container’s port 80
    9. Review and deploy:

      • Review all settings to ensure everything is configured correctly
      • Click “Create” or “Deploy” to start the build and deployment process
    10. Monitor the deployment:

      • Watch the build logs to ensure the Docker image builds successfully
      • Once deployed, the app status should show as “Running”
      • Check the runtime logs for any errors or issues
    11. Access your BookStack instance:

      • Navigate to your app URL (e.g., https://example-app.klutch.sh)
      • You should see the BookStack setup wizard on first run
      • Create your admin account and start building your documentation

For more detailed deployment instructions, see the Klutch.sh Quick Start Guide.


8. Initial BookStack Setup

After your deployment is successful and the app is running:

    1. Navigate to your BookStack URL (e.g., https://example-app.klutch.sh).

    2. If this is your first deployment, you’ll see the BookStack initial setup page.

    3. The default credentials for a fresh BookStack installation are:

      • Email: admin@admin.com
      • Password: password
    4. Important: Log in immediately and change these default credentials:

      • Go to your profile settings (top-right avatar menu)
      • Update your email address and password
      • Configure two-factor authentication if needed
    5. Configure system settings:

      • Navigate to Settings → System Settings
      • Update the site name, logo, and branding
      • Configure registration settings (disable public registration for internal wikis)
      • Set up email settings if you haven’t done so via environment variables
    6. Start creating your documentation:

      • Create your first Book
      • Add Chapters to organize content
      • Create Pages with your documentation

9. Custom Domain Configuration

To use a custom domain with your BookStack instance instead of the default Klutch.sh subdomain:

    1. In the Klutch.sh dashboard, navigate to your BookStack app.

    2. Go to the Domains section and add your custom domain (e.g., docs.example.com).

    3. Klutch.sh will provide you with DNS configuration instructions:

      • Add a CNAME record pointing to your Klutch.sh app URL, or
      • Add an A record pointing to the provided IP address
    4. Update the APP_URL environment variable to match your custom domain:

      Terminal window
      APP_URL=https://docs.example.com
    5. Wait for DNS propagation (can take up to 48 hours but usually much faster).

    6. Klutch.sh automatically provisions and manages SSL/TLS certificates for your custom domain.

    7. Once DNS propagates, access BookStack at your custom domain with HTTPS enabled.

For more information, see the Custom Domains Guide.


10. Backup and Maintenance

Regular backups are essential for protecting your documentation content.

Database Backups

Use mysqldump to create regular database backups:

Terminal window
mysqldump -h $DB_HOST -u $DB_USERNAME -p$DB_PASSWORD $DB_DATABASE > bookstack-backup-$(date +%F).sql

Automate this with a cron job or scheduled task, and store backups in object storage (S3, Backblaze B2, etc.).

File Storage Backups

The persistent volume at /var/www/bookstack/storage/uploads contains all uploaded files, images, and attachments. Consider:

  • Taking regular snapshots of the volume through your hosting provider
  • Syncing the volume to object storage periodically
  • Implementing a backup rotation policy (daily, weekly, monthly)

Restoration

To restore from a backup:

    1. Restore the database:

      Terminal window
      mysql -h $DB_HOST -u $DB_USERNAME -p$DB_PASSWORD $DB_DATABASE < bookstack-backup-2024-01-15.sql
    2. Restore uploaded files to the persistent volume.

    3. Restart the application to pick up the restored data.


11. Security Best Practices

Application Security

  • Change default credentials immediately after first login
  • Enable two-factor authentication for admin accounts
  • Restrict registration: Disable public registration for internal documentation
  • Regular updates: Keep BookStack updated to the latest version for security patches
  • Use strong passwords: Enforce strong password policies for all users

Database Security

  • Use strong database passwords with at least 20 characters
  • Limit database access: Only allow connections from your BookStack app
  • Enable SSL/TLS for database connections when possible
  • Regular backups: Automate database backups to prevent data loss

Infrastructure Security

  • HTTPS only: Always use HTTPS for production deployments (automatic with Klutch.sh)
  • Environment variables: Never commit secrets to your repository
  • Minimal permissions: Grant only necessary permissions to database users
  • Monitor logs: Regularly review application and access logs for suspicious activity

Content Security

  • Review permissions: Regularly audit user permissions and access levels
  • Configure page permissions: Use BookStack’s granular permission system
  • Audit logging: Enable and review audit logs for sensitive operations
  • Content versioning: Take advantage of BookStack’s revision history

12. Performance Optimization

Application Optimization

  • Enable caching: Configure Redis or Memcached for session and cache storage for better performance
  • Optimize images: Use BookStack’s image optimization settings
  • Database indexing: Ensure proper database indexes for large documentation sites
  • PHP opcache: Enable PHP opcache in production (included in most PHP-FPM images)

Infrastructure Optimization

  • Scale vertically: Increase CPU and memory if the app becomes slow under load
  • Database optimization: Use appropriate MySQL configuration for your workload
  • CDN integration: Consider using a CDN for serving static assets
  • Monitoring: Set up monitoring for CPU, memory, and response time metrics

Scaling Considerations

For high-traffic BookStack deployments:

  • Consider horizontal scaling with multiple app instances behind a load balancer
  • Use external session storage (Redis/Memcached) for session persistence across instances
  • Configure external storage (S3) for uploads to share files across instances
  • Implement database read replicas for read-heavy workloads

13. Troubleshooting

Common Issues and Solutions

Issue: “Application Key Not Set” Error

Solution: Ensure the APP_KEY environment variable is set. Generate one with:

Terminal window
php artisan key:generate --show

Add it to your Klutch.sh environment variables as APP_KEY=base64:your_generated_key.

Issue: Database Connection Failed

Solution:

  • Verify database credentials in environment variables
  • Check network connectivity between app and database
  • Ensure database user has proper privileges
  • Test connection manually: mysql -h $DB_HOST -u $DB_USERNAME -p$DB_PASSWORD -e "SELECT 1"

Issue: 502 Bad Gateway or App Not Responding

Solution:

  • Check that Apache is running inside the container
  • Verify internal port is set to 80
  • Review application logs for startup errors
  • Ensure entrypoint script completed successfully

Issue: File Upload Fails

Solution:

  • Check persistent volume is mounted correctly at /var/www/bookstack/storage/uploads
  • Verify permissions: chown -R www-data:www-data /var/www/bookstack/storage
  • Check disk space on the persistent volume
  • Review PHP upload limits in php.ini if needed

Issue: Email Sending Fails

Solution:

  • Verify SMTP credentials in environment variables
  • Test SMTP connection from container: telnet $MAIL_HOST $MAIL_PORT
  • Check mail server logs for rejected connections
  • Ensure MAIL_FROM address is valid and authorized

Debugging Tips

View Application Logs:

Terminal window
# Inside the container
tail -f /var/www/bookstack/storage/logs/laravel.log

Check Apache Logs:

Terminal window
# Inside the container
tail -f /var/log/apache2/error.log
tail -f /var/log/apache2/access.log

Test Database Connectivity:

Terminal window
php artisan tinker
DB::connection()->getPdo();

Clear All Caches:

Terminal window
php artisan cache:clear
php artisan config:clear
php artisan view:clear
php artisan route:clear

14. Updating BookStack

To update BookStack to a newer version:

    1. Update the BOOKSTACK_VERSION argument in your Dockerfile to the desired version:

      ARG BOOKSTACK_VERSION=v24.01
    2. Commit and push the change to your GitHub repository.

    3. Klutch.sh will automatically trigger a new build with the updated version.

    4. The entrypoint script will run migrations automatically to update the database schema.

    5. Test the updated version thoroughly before promoting to production.

    6. Monitor logs during and after the update for any issues.

Always review the BookStack release notes before updating to check for breaking changes or required manual steps.


15. Additional Features and Integrations

LDAP/Active Directory Authentication

BookStack supports LDAP authentication for enterprise environments:

Terminal window
# Add these environment variables
AUTH_METHOD=ldap
LDAP_SERVER=ldap.example.com:389
LDAP_BASE_DN=dc=example,dc=com
LDAP_DN=cn=admin,dc=example,dc=com
LDAP_PASS=admin_password
LDAP_USER_FILTER=(&(uid=${user}))

SAML2 Authentication

For single sign-on with SAML2:

Terminal window
AUTH_METHOD=saml2
SAML2_NAME=SSO
SAML2_EMAIL_ATTRIBUTE=email
SAML2_DISPLAY_NAME_ATTRIBUTES=username
SAML2_EXTERNAL_ID_ATTRIBUTE=uid

S3 Storage for Uploads

To use S3 for file uploads instead of local storage:

Terminal window
STORAGE_TYPE=s3
STORAGE_S3_KEY=your_access_key
STORAGE_S3_SECRET=your_secret_key
STORAGE_S3_BUCKET=bookstack-uploads
STORAGE_S3_REGION=us-east-1

Webhooks

BookStack supports webhooks for events like page updates, which you can use for integrations with Slack, Discord, or custom automation.


Resources


Deploying BookStack on Klutch.sh provides you with a robust, scalable platform for creating and managing documentation. With persistent volumes for uploads, MySQL database integration, and automated deployments from GitHub, you have a production-ready setup that’s easy to maintain and scale. The Docker-based approach ensures consistency across environments and makes updates straightforward. Whether you’re building an internal knowledge base, product documentation, or a collaborative wiki, BookStack on Klutch.sh gives you the reliability and features you need to organize and share information effectively.