BookStack@nginx-Debian12.md 12 KB

HISTORY

2024-05-24  * init and screen recording /A
2024-11-23  + second instance for InstallAndUse.com /A

TODO:

  • create empty DB

    db: dox_installanduse_com-bookstack
    u:  dox_installanduse_com-bs_rw
    p:  xxxxxxxxxxxxxxxxxxx
    
  • create service account to access bucket

    bucket: dox_installanduse_com-bookstack
    user: dox-installanduse-com-bs-rw@projectname-333333.iam.gserviceaccount.com
    
  • create a bucket for storage create storage in Cloud Storage, Service account and key-secret pair

    Name: iau-data-dox
    Cloud Storage, [create],
    Region: eu-north1
    Choose a storage class for your data
    [o] Autoclass
      [x] Opt-in to allow object transitions to Coldline and Archive classes
    Choose how to control access to objects:  Allow public access, [ ] Enforce public access prevention on this bucket
    Access control: Fine-grained: Object-level ACLs enabled.
    
    Cloud storage, Buckets, iau-data-dox, Permissions, [Grant access]
    New princtipals: dox-installanduse-com-bs-rw@projectname-333333.iam.gserviceaccount.com
      Storage Legacy Bucket Owner
      Storage Legacy Bucket Reader
      Storage Legacy Bucket Writer
      Storage Legacy Object Owner
      Storage Legacy Object Reader
      Storage Object Creator
      Storage Object User
      Storage Object Viewer
    
    Cloud Storage, Settings, Interoperability, [Create a key for another service account]
    Service accountName: dox_installanduse_com-bs_rw, [Create key]
    New key access key and secret will be shown only ONCE. Write it down.
    dox-installanduse-com-bs-rw@projectname-333333.iam.gserviceaccount.com
    Access key    GOOG1ETE423VPVxxxxxxxxxxxxxxxxxxxxxxxxxxxxxDAO5JMZZA7NKLG4S
    Secret        xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    Copy this key's secret if you'll need it in the future. Once you close this dialog, the secret can't be recovered.
    
    --or--
    Cloud Storage, Settings, Interoperability, [Create a key],  Service account HMAC [Create new account]
    Name: dox_2dz_fi-bookstack, [Create and continue]
    Roles: Storage Object Admin, [Continue], [Done]
    Save key and secret! Secret will be shown once.
    --or--
    
    
    gsutil uniformbucketlevelaccess get gs://2dz-data-hub
    

Expected output

Uniform bucket-level access setting for gs://2dz-data-hub:
  Enabled: False
  • create CNAME/A record, point to a server

    dig A dox.2dz.fi
    dig A dox.installanduse.com +short
    
  • create home directory for application

    whoami
    sudo su
    # privileged user (you)
    export pu="anton"
    
    # working directory (for easy future maintenance)
    export wsd="/var/www/dox.installanduse.com"
    mkdir -p ${wsd}
    # permit priviledged user to own app directory
    chown -R ${pu}:${pu} ${wsd}
    exit
    # as priviledged user, not as root
    export wsd="/var/www/dox.installanduse.com"
    cd ${wsd}
    

clone latest application source code from repo

git clone https://github.com/BookStackApp/BookStack.git --branch release --single-branch
ls -la BookStack/

Download composer and install in global mode (as normal user, not as root), later easy to update.

mkdir -p ~/utils/composer
cd ~/utils/composer/
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === 'dac665fdc30fdd8ec78b38b9800061b4150413ff2e3b6f88543c636f7cd84f6db9189d43a81e5503cda447da73c7e5b6') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
php composer.phar
sudo mv composer.phar /usr/local/bin/composer
  • build (composer install)

    cd ${wsd}/BookStack
    which composer
    composer install --no-dev
    

Set least necessary permissions for webserver

sudo su
export wsd="/var/www/dox.installanduse.com"
# webserver's user
export wsu="www-data"
chown -R ${wsu}:${wsu} ${wsd}/BookStack/storage/
chmod -R 775           ${wsd}/BookStack/storage/
chown -R ${wsu}:${wsu} ${wsd}/BookStack/bootstrap/cache/
chmod -R 775           ${wsd}/BookStack/bootstrap/cache/
chown -R ${wsu}:${wsu} ${wsd}/BookStack/public/uploads/
chmod -R 775           ${wsd}/BookStack/public/uploads/
chown -R ${wsu}:${wsu} ${wsd}/BookStack/public/

Copy template, generate salt abd configure .env

cp .env.example .env
php artisan key:generate
vi .env
APP_KEY=base64:xxxxxxxxxxxxxxxxxxxxxxxxPbw8=
APP_URL=https://dox.installanduse.com

DB_HOST=172.21.xx.xx
DB_DATABASE=dox_installanduse_com-bookstack
DB_USERNAME=dox_installanduse_com-bs_rw
DB_PASSWORD=xxxxxxxxxxxxxxxxxxx

MAIL_DRIVER=smtp
MAIL_FROM_NAME="dox.installanduse.com"
MAIL_FROM=dox@installanduse.com
MAIL_HOST=127.0.0.1
MAIL_PORT=25
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_VERIFY_SSL=false

STORAGE_TYPE=s3
STORAGE_S3_KEY=GOOG1ETE423VPVUU3PBHxxxxxxxxxxxxxxxNZD3B4YDAO5JMZZA7NKLG4S
STORAGE_S3_SECRET=4mUF0niGoHfenkxxxxxxxxxxxZCoUqCIiwpg89Evj
STORAGE_S3_BUCKET=iau-data-dox
STORAGE_S3_REGION=europe-north1
STORAGE_S3_ENDPOINT=https://storage.googleapis.com
STORAGE_URL=https://storage.googleapis.com/iau-data-dox

Configure webserver (nginx)

create site config.

Determine, where is PHP is listening to. It is very important, as I spent many hours many years ago to figure out, troubleshooting it. There are two ways to find the answer. You should use the most generic one, because after version upgrade, confgiration will remain functional.

sudo su
systemctl | grep php
systemctl status php8.2-fpm.service
less /lib/systemd/system/php8.2-fpm.service
# observe for socket path
ls -la /run/php/php-fpm.sock
lrwxrwxrwx 1 root root 30 May 23 00:21 /run/php/php-fpm.sock -> /etc/alternatives/php-fpm.sock
ls -la /etc/alternatives/php-fpm.sock

bash lrwxrwxrwx 1 root root 24 May 23 00:21 /etc/alternatives/php-fpm.sock -> /run/php/php8.2-fpm.sock

bash ls -la /run/php/php8.2-fpm.sock

bash srw-rw---- 1 www-data www-data 0 May 23 00:21 /run/php/php8.2-fpm.sock


Or check via configuration

bash fgrep -irn fpm.sock /etc/php/

Determine from output location of socket

bash /etc/php/8.2/fpm/pool.d/www.conf:41:listen = /run/php/php8.2-fpm.sock


To summarize own findings, we shall use:

bash /run/php/php-fpm.sock



bash sudo su

copy output of root path

echo ${wsd}/BookStack/public cd /etc/nginx/sites-available vi dox.installanduse.com.conf


Create a simple virtualhost configuration listining on http. SSL will be enabled later by CertBot.

ini server { listen 80; listen [::]:80;

server_name dox.installanduse.com;

root /var/www/dox.installanduse.com/BookStack/public; index index.php index.html;

location / {

try_files $uri $uri/ /index.php?$query_string;

}

location ~ .php$ {

include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php-fpm.sock;

} }



- enable available site

bash ln -s /etc/nginx/sites-available/dox.installanduse.com.conf /etc/nginx/sites-enabled/ ls -latr /etc/nginx/sites-enabled


Test webserver configuration, and reload it.

bash nginx -t nginx -s reload

systemctl restart nginx

ss -ntap | grep nginx




- upgrade DB (recreate/upgrade schema to the recent), approve warning on application in production (we are doing fresh deployment)

bash exit id export wd="/var/www/dox.installanduse.com" cd ${wsd}/BookStack php artisan migrate



Check DB

bash mysql -h (dbhost) -u dox_installanduse_com-bs_rw -p

sql MySQL [(none)]> SHOW DATABASES; [...] | dox_installanduse_com-bookstack | [...] MySQL [(none)]> USE dox_installanduse_com-bookstack; [...] Database changed MySQL [dox_installanduse_com-bookstack]> SHOW TABLES; [...] | users | [...] +-------------------------------------------+ 38 rows in set (0.003 sec)

MySQL [dox_installanduse_com-bookstack]> SELECT * FROM users; [...] | 1 | Admin | admin@admin.com | $2y$12$Hw/USVgBnbR2OEuSSaxxxxxxxxxxbPLUFcw8n98xjK.MP45K | NULL | 2024-11-23 16:30:10 | 2024-11-23 16:30:10 | 1 | 0 | | NULL | admin | [...] 2 rows in set (0.003 sec) quit


After DB is built, main page of application should be accessible over HTTP, it will be automatically redirected to HTTPS and will not be possible to view via browser. But from CLI, it will be possible using curl:

bash curl http://dox.installanduse.com

bash <!DOCTYPE html>

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="refresh" content="0;url='https://dox.installanduse.com/login'" />

    <title>Redirecting to https://dox.installanduse.com/login</title>
</head>
<body>
    Redirecting to <a href="https://dox.installanduse.com/login">https://dox.installanduse.com/login</a>.
</body>


It is possible to leave plain HTTP, but highly recommended enable SSL at the same time!
- Enable SSL using Let's Encrypt and Certbot. Before doing that, let's ensure, that pointing FQDN match actual IP address.

bash curl https://myip.2dz.fi

bash 35.228.9.88

bash dig A dox.installanduse.com +short

bash installanduse.com. 35.228.9.88

bash sudo su apt install certbot python3-certbot-nginx certbot --nginx -d dox.installanduse.com

bash Saving debug log to /var/log/letsencrypt/letsencrypt.log Requesting a certificate for dox.installanduse.com

Successfully received certificate. Certificate is saved at: /etc/letsencrypt/live/dox.installanduse.com/fullchain.pem Key is saved at: /etc/letsencrypt/live/dox.installanduse.com/privkey.pem This certificate expires on 2025-02-21. These files will be updated when the certificate renews. Certbot has set up a scheduled task to automatically renew this certificate in the background.

Deploying certificate Successfully deployed certificate for dox.installanduse.com to /etc/nginx/sites-enabled/dox.installanduse.com.conf Congratulations! You have successfully enabled HTTPS on https://dox.installanduse.com


If you like Certbot, please consider supporting our work by:

open -a firefox https://dox.installanduse.com/


Login with default credentials:

Email: admin@admin.com Password: password


Change admin email (do not delay, do it now.):

url https://dox.installanduse.com/my-account/profile



Change admin password and enroll MFA (good OTP manger is 'FreeOTP+' for Android):

url https://dox.installanduse.com/my-account/auth


Create your personal account (do not use admin account for daily operations)!

url https://dox.installanduse.com/settings/users/create

Logout, login,  enroll MFA!

url https://dox.installanduse.com/mfa/setup



# Fine-tuning:

bash vi .env

ini

File Upload Limit

Maximum file size, in megabytes, that can be uploaded to the system.

FILE_UPLOAD_SIZE_LIMIT=50




- S3 driver to mount storage in Cloud Bucket
- fine-tune (nginx.conf)

bash vi /etc/nginx/nginx.conf

ini [...] http {

#...
    client_max_body_size 100m;
    client_body_timeout 120s; # Default is 60, May need to be increased for very large uploads
#...

} [...]




- fine-tune PHP

bash ps aux | grep php

observe path to php-fpm.conf file

vi /etc/php/8.2/fpm/php-fpm.conf

ini post_max_size = 10M upload_max_filesize = 10M memory_limit = 256M



ref. https://www.bookstackapp.com/docs/admin/installation/#requirements https://www.bookstackapp.com/docs/admin/upload-config/#s3



more notes on location os filesizes for upload

bash

[08:23:12 Sat Nov 30] @gcp1mx1 /home/dox_2dz_fi-bookstack/storage/logs# fgrep -irn post_max_size /etc/php /etc/php/8.2/apache2/php.ini:703:post_max_size = 8M /etc/php/8.2/cli/php.ini:703:post_max_size = 8M /etc/php/8.2/fpm/php.ini:703:post_max_size = 8M vi /etc/php/8.2/apache2/php.ini vi /etc/php/8.2/fpm/php.ini vi /etc/php/8.2/cli/php.ini

[08:23:48 Sat Nov 30] @gcp1mx1 /home/dox_2dz_fi-bookstack/storage/logs# fgrep -irn upload_max_filesize /etc/php /etc/php/8.2/apache2/php.ini:855:upload_max_filesize = 2M /etc/php/8.2/cli/php.ini:855:upload_max_filesize = 2M /etc/php/8.2/fpm/php.ini:855:upload_max_filesize = 2M vi /etc/php/8.2/apache2/php.ini vi /etc/php/8.2/cli/php.ini vi /etc/php/8.2/fpm/php.ini

systemctl | grep fpm systemctl restart php8.2-fpm.service systemctl restart nginx

```