BookStack Common — Shared Application Configuration
BookStack_Common is the shared application layer for BookStack. It is not
deployed on its own; instead it supplies the BookStack-specific configuration that
both BookStack_GKE and
BookStack_CloudRun build on, so the two platform variants
behave identically where it matters. End users never configure this layer directly —
it has no deployment UI inputs of its own — but understanding what it provides
explains the defaults you see in the platform docs.
For the infrastructure that actually provisions and runs BookStack, see the platform guides (BookStack_GKE, BookStack_CloudRun) and the foundation guides (App_GKE, App_CloudRun, App_Common).
1. What this layer provides
| Area | Provided by BookStack_Common | Where it surfaces |
|---|---|---|
| Cryptographic secrets | Generates the Laravel APP_KEY (base64:<44-char base64>) and stores it in Secret Manager | Injected automatically as secret env APP_KEY |
| Container image | Fixes the prebuilt linuxserver/bookstack image (no custom build) | container_image output of the platform deployment |
| Database engine | Fixes Cloud SQL for MySQL 8.0 as the only supported engine | §Database in the platform guides |
| Database bootstrap | Defines the first-deploy job (db-init) that creates the database, user, and grants | initialization_jobs output |
| Object storage | Declares the Cloud Storage bookstack-uploads bucket | storage_buckets output |
| Persistent files | Declares the NFS mount at /var/lib/bookstack for uploaded images and attachments | §Storage in the platform guides |
| Core settings | Sets DB_CONNECTION = mysql, DB_PORT = 3306, APP_URL, and the Laravel-native DB env var names | Application behaviour in the platform guides |
| Health checks | Supplies the default startup (TCP) / liveness (HTTP /status) probes | §Observability in the platform guides |
2. Cryptographic secrets in Secret Manager
One secret is generated automatically and stored in Secret Manager — it is never set in plain text and must never be changed after the first deployment:
APP_KEY— the Laravel application key, in the formatbase64:<44-char base64>(32 random bytes, base64-encoded). Generated byrandom_passwordinBookStack_Common, stored as secretsecret-<resource_prefix>-bookstack-app-key, and injected as the secret env varAPP_KEY. BookStack uses it to encrypt all application data stored encrypted (two-factor secrets and some settings). Rotating it after first boot makes those encrypted values permanently undecryptable — it is effectively immutable for the life of the deployment.
Retrieve the secret after deployment:
# List secrets for this deployment (names include the resource prefix):
gcloud secrets list --project "$PROJECT" --filter="name~app-key"
# Read a secret version:
gcloud secrets versions access latest --secret=<secret-name> --project "$PROJECT"
The database password is generated and managed separately by the foundation; its
secret name is reported in the platform deployment outputs (database_password_secret)
and it is injected as DB_PASSWORD. See App_Common for the shared
secret and Workload Identity model.
3. Database engine and bootstrap
BookStack requires MySQL 8.0 (database_type = "MYSQL_8_0"); the engine is fixed
and PostgreSQL or other engines are not supported. On the first deployment a one-shot
job (db-init) runs using mysql:8.0-debian and idempotently:
- Detects the Cloud SQL Auth Proxy Unix socket or the TCP endpoint and selects the
right connection form for the
mysqlclient, - Waits for MySQL to be reachable,
- Creates (or updates) the application user with the generated password,
- Creates the application database,
- Grants full privileges on the database to the application user,
- Verifies the application user can connect,
- Signals the Cloud SQL Auth Proxy sidecar to shut down gracefully
(
POST /quitquitquit).
The job is safe to re-run (max_retries = 3). Inspect the database directly with:
gcloud sql connect <instance-name> --user=bookstack --database=<db-name> --project "$PROJECT"
The instance, database, and user names are in the platform deployment outputs.
Note: db-init provisions only the database, user, and grants — the schema itself
is created by the image's automatic php artisan migrate --force on the first
container start (and re-applied on later boots for upgrades). There is no separate
migration job.
4. Container image
BookStack is deployed from the official LinuxServer.io prebuilt image,
linuxserver/bookstack:<version> — there is no custom Cloud Build. The Application
modules forward container_image_source = "prebuilt" (and
container_build_config.enabled = false), so the platform mirrors the image into
Artifact Registry (enable_image_mirroring = true) and deploys it directly.
Because BookStack is a Laravel app, it reads the Laravel-native database
environment variables rather than the image's generic DB_USER/DB_PASS. The
Application modules map the platform's injected DB values onto the Laravel names via
db_*_env_var_name:
db_user_env_var_name = "DB_USERNAME",db_password_env_var_name = "DB_PASSWORD",db_name_env_var_name = "DB_DATABASE".
BookStack_Common additionally sets the static DB_CONNECTION = "mysql" and
DB_PORT = "3306". DB_HOST differs by platform:
- Cloud Run connects over the Cloud SQL private IP (
enable_cloudsql_volume = false), soDB_HOSTis the instance private IP; MySQL over private-IP TCP needs no SSL. - GKE connects through the Cloud SQL Auth Proxy sidecar
(
enable_cloudsql_volume = true), so the GKE wiring overridesDB_HOST = "127.0.0.1".
The LinuxServer image runs php artisan migrate --force on start (see §3), so no
custom entrypoint is needed to create the schema.
5. Core application settings
BookStack_Common establishes the baseline BookStack environment so the application
comes up correctly on first boot:
- Database connection —
DB_CONNECTION = "mysql",DB_PORT = "3306"; the Laravel-nativeDB_USERNAME/DB_PASSWORD/DB_DATABASEandDB_HOSTare injected by the foundation (see §4). - Application URL —
APP_URLis set from the predicted service URL so links, assets, and login redirects resolve to the real address. - Redis (optional) — when Redis is enabled via the platform deployment settings,
REDIS_HOSTandREDIS_PORTare injected so BookStack can use Redis for cache and sessions; otherwise BookStack uses its local drivers. - First-run administrator — the LinuxServer image seeds a default admin account,
admin@admin.com/password. Change it immediately after the first login.
6. Health probe behaviour
The default probes rely on BookStack's public health surface:
- Startup — a TCP check on port
80, which passes as soon as the PHP web server binds its port. - Liveness — an HTTP
GET /status, BookStack's unauthenticated JSON health endpoint that reports app/database/cache/session status. A generous first-boot window (300-second initial delay) accommodates the automaticphp artisan migrate --forcethat runs on the first container start.
On the GKE variant, the shipped
liveness_probedefault path is a stale WordPress leftover (/wp-admin/install.php); setpath = "/status"for accurate BookStack health signalling.
7. Object storage & persistent files
Two storage surfaces are declared here and provisioned by the foundation:
- Cloud Storage — a dedicated
bookstack-uploadsbucket (in the deployment region,force_destroy = true); the workload service account is granted access. - NFS — enabled by default (
enable_nfs = true) and mounted at/var/lib/bookstack, where BookStack stores uploaded images, attachments, and files so they persist across restarts, redeploys, and scale events.
List the bucket with:
gcloud storage buckets list --project "$PROJECT"
For the BookStack-specific, user-facing configuration (variables by group, outputs, and how to explore each service from the Console and CLI), see the platform guides: BookStack_GKE and BookStack_CloudRun.