The following guide assumes running the commands below as root
for simplicity. Later in the guide directory permissions are restricted to follow the principle of least privilege.
-
Install dependencies.
apt install -y git unzip apache2 php7.4 curl php7.4-fpm php7.4-curl php7.4-mbstring php7.4-ldap \ php7.4-tidy php7.4-xml php7.4-zip php7.4-gd php7.4-mysql libapache2-mod-php7.4 \ default-mysql-server
-
Setup database.
# You can manually define the password below or autogenerate it. DB_PASS="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13)" # TODO: Consider moving away from 'mysql_native_password' to a more secure authentication mechanism. mysql -u root --execute="CREATE DATABASE bookstack;" mysql -u root --execute="CREATE USER 'bookstack'@'localhost' IDENTIFIED WITH mysql_native_password AS PASSWORD('$DB_PASS');" mysql -u root --execute="GRANT ALL ON bookstack.* TO 'bookstack'@'localhost';FLUSH PRIVILEGES;"
QA: Running
mysql -u root --execute="SELECT user FROM mysql.user"
should show the created user 'bookstack'. -
Install PHP package manager.
# Install composer EXPECTED_CHECKSUM="$(php -r 'copy("https://composer.github.io/installer.sig", "php://stdout");')" php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ] then >&2 echo 'ERROR: Invalid composer installer checksum' rm composer-setup.php exit 1 fi php composer-setup.php --quiet rm composer-setup.php # Move composer to global installation mv composer.phar /usr/local/bin/composer
QA: Running
composer about
should output some text. -
Download BookStack PHP webapp files.
cd /var/www git clone https://github.com/BookStackApp/BookStack.git --branch release --single-branch bookstack cd bookstack
-
Define BookStack environment variables (Change BASE_URL value below!).
# Change the BASE_URL value to either an IP or hostname. See the three examples below (delete all except one BASE_URL) BASE_URL=http://bookstack.mydomain.com BASE_URL=http://192.168.1.1:6875 BASE_URL=http://localhost # Copy and update BookStack environment variables cp .env.example .env sed -i.bak "s@APP_URL=.*\$@APP_URL=$BASE_URL@" .env sed -i.bak 's/DB_DATABASE=.*$/DB_DATABASE=bookstack/' .env sed -i.bak 's/DB_USERNAME=.*$/DB_USERNAME=bookstack/' .env sed -i.bak "s/DB_PASSWORD=.*\$/DB_PASSWORD=$DB_PASS/" .env
QA: Inspect the contents of the '.env' file and confirm that the four variables (APP_URL, DB_DATABASE, DB_USERNAME, DB_PASSWORD) have valid values.
-
Configure BookStack.
# Install BookStack composer dependencies export COMPOSER_ALLOW_SUPERUSER=1 php /usr/local/bin/composer install --no-dev --no-plugins # Generate the application key php artisan key:generate --no-interaction --force # Migrate the databases php artisan migrate --no-interaction --force # Set file and folder permissions chown www-data:www-data -R bootstrap/cache public/uploads storage && chmod -R 755 bootstrap/cache public/uploads storage
-
Configure Apache to serve new BookStack app.
# Set up apache a2enmod rewrite a2enmod php7.4 # Create apache config file to serve webapp vim /etc/apache2/sites-available/bookstack.conf <VirtualHost *:80> # Set the 'ServerName' to a static IP address unless you have a DNS entry for the hostname already. ServerName 10.10.10.100 ServerAdmin webmaster@localhost DocumentRoot /var/www/bookstack/public/ <Directory /var/www/bookstack/public/> Options Indexes FollowSymLinks AllowOverride None Require all granted <IfModule mod_rewrite.c> <IfModule mod_negotiation.c> Options -MultiViews -Indexes </IfModule> RewriteEngine On # Handle Authorization Header RewriteCond %{HTTP:Authorization} . RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] # Redirect Trailing Slashes If Not A Folder... RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} (.+)/$ RewriteRule ^ %1 [L,R=301] # Handle Front Controller... RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L] </IfModule> </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
-
Verify config file and enable it
/usr/sbin/a2ensite bookstack.conf # You need to enable it before using `apachectl configtest` /usr/sbin/apachectl configtest # You might see a `AH00558` warning message. It is safe to ignore (related to DNS lookup). # The main thing to see is a `Syntax OK` message. /usr/sbin/a2dissite 000-default.conf # Disable default website systemctl restart apache2
-
Login into Bookstack: Browser > http://$BOOKSTACK_IP:80 > Login('[email protected]', 'password')
- Problem: I messed up during the mysql steps and lost the password! How can I reset the password for the 'bookstack' user?
- Solution:
mysql -u root --execute="SET PASSWORD FOR 'bookstack'@'localhost' = PASSWORD('AWESOME_NEW_PASSWORD')"
Though the line
looks like an error message, it is actually just a warning that can be safely ignored. The
Syntax OK
is the key part that confirms that yourapache.conf
file syntax is correct. So you can proceed with the next steps in the guide without issues.The warning message is related to your Apache having issues resolving hostnames (DNS issues) for a particular entry. It won't pose an issue for the guide, but if you plan on eventually swapping to a hostname, say
myAwesomeBookStackApp.com
to resolve to your machine IP, then you might want to consider modifying your/etc/hosts
file to add a static entry (a solution but might not be the best depending on your exact setup).I've updated the guide to mention this and make it clearer. Thank you for taking the time and commenting!