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
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
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
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:
Donating to EFF: https://eff.org/donate-le
bash nginx -t systemctl restart nginx
Application should be up and running, open local browser
bash
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_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
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
```