From 5c749b2762b03ddd64c41ee06aca0cf3dae1cb9a Mon Sep 17 00:00:00 2001 From: Simon Martens Date: Fri, 31 Oct 2025 12:18:21 +0100 Subject: [PATCH] +bookstack --- deckard/bookstack/.env.example | 26 ++ deckard/bookstack/.gitignore | 26 ++ deckard/bookstack/README.md | 423 +++++++++++++++++++ deckard/bookstack/bookstack.env.example | 33 ++ deckard/bookstack/bookstack.testing.env | 33 ++ deckard/bookstack/docker-compose.testing.yml | 60 +++ deckard/bookstack/docker-compose.yml | 58 +++ deckard/caddy/sites/wiki.tss-hd.de | 9 + 8 files changed, 668 insertions(+) create mode 100644 deckard/bookstack/.env.example create mode 100644 deckard/bookstack/.gitignore create mode 100644 deckard/bookstack/README.md create mode 100644 deckard/bookstack/bookstack.env.example create mode 100644 deckard/bookstack/bookstack.testing.env create mode 100644 deckard/bookstack/docker-compose.testing.yml create mode 100644 deckard/bookstack/docker-compose.yml create mode 100644 deckard/caddy/sites/wiki.tss-hd.de diff --git a/deckard/bookstack/.env.example b/deckard/bookstack/.env.example new file mode 100644 index 0000000..d1430b4 --- /dev/null +++ b/deckard/bookstack/.env.example @@ -0,0 +1,26 @@ +# BookStack Production Configuration +# Copy this file to .env and update with your actual values + +# ============================================ +# User/Group Configuration +# ============================================ +# Run `id` on your host to get your UID/GID +PUID=1000 +PGID=1000 + +# Timezone +TZ=Europe/Berlin + +# ============================================ +# Database Configuration +# ============================================ + +# Database name +DB_DATABASE=bookstack_testing +DB_USERNAME=bookstack_testing +DB_PASSWORD=testing_password_123 +MYSQL_ROOT_PASSWORD=testing_password_123 + +# Optional: Enable async email processing (recommended for better performance) +# QUEUE_CONNECTION=database + diff --git a/deckard/bookstack/.gitignore b/deckard/bookstack/.gitignore new file mode 100644 index 0000000..4d7403e --- /dev/null +++ b/deckard/bookstack/.gitignore @@ -0,0 +1,26 @@ +# Environment configuration (contains secrets) +.env +bookstack.env + +# Testing data directory (bind mount) +bookstack_testing_data/ +.claude/ + +# Backups +*.sql +*.tar.gz +backup*/ + +# Docker override +docker-compose.override.yml + +# OS files +.DS_Store +Thumbs.db + +# Editor files +.vscode/ +.idea/ +*.swp +*.swo +*~ diff --git a/deckard/bookstack/README.md b/deckard/bookstack/README.md new file mode 100644 index 0000000..69196c0 --- /dev/null +++ b/deckard/bookstack/README.md @@ -0,0 +1,423 @@ +# BookStack for Deckard + +Production deployment of BookStack using the official [linuxserver.io](https://docs.linuxserver.io/images/docker-bookstack/) Docker image. + +## Overview + +This setup uses: +- **Official linuxserver/bookstack image** - Pre-built, well-maintained +- **MariaDB database** - linuxserver/mariadb image +- **Caddy reverse proxy** - For production HTTPS +- **All configuration via .env** - No secrets in docker-compose files +- **Persistent volumes** - Data stored in `./bookstack_data` + +## Quick Start - Production + +### 1. Generate APP_KEY + +```bash +docker run -it --rm --entrypoint /bin/bash lscr.io/linuxserver/bookstack:latest appkey +``` + +Copy the output (looks like `base64:xxxxx...`) + +### 2. Configure Environment + +#### 2.1 Settings for DB/Docker + +```bash +# Copy example file +cp .env.example .env + +# Edit configuration +nano .env +``` + +**Required changes:** +- MySQL settings +- `PUID`/`PGID` - Run `id` to get your user/group IDs +- `TZ` - Your timezone + +#### 2.2 Settings for BookStack + +```bash +cp bookstack.env.example bookstack.env +``` + +REQUIRED CHANGES: +- App name / App kek +- Email settings + + +### 3. Configure Caddy + +```bash +# Navigate to Caddy sites directory +cd ../server-package/deckard/caddy/sites/ + +# Rename template to your domain +mv wiki.yourdomain.com wiki.tss-hd.de + +# Edit and update domain names +nano wiki.tss-hd.de +``` + +### 4. Deploy + +```bash +# Return to tss-bookstack directory +cd /home/simon/source/tss-bookstack + +# Create caddynet network if needed +docker network create caddynet 2>/dev/null || true + +# Start services +docker compose up -d + +# Check logs +docker compose logs -f +``` + +### 5. Reload Caddy + +```bash +cd ../server-package/deckard/caddy +docker compose restart caddy +``` + +### 6. Access & Login + +Navigate to your domain (e.g., `https://wiki.tss-hd.de`) + +**Default credentials:** +- Email: `admin@admin.com` +- Password: `password` + +**⚠️ CHANGE THESE IMMEDIATELY!** + +## Quick Start - Local Testing + +For testing locally without Caddy reverse proxy: + +### 1. Generate APP_KEY + +```bash +docker run -it --rm --entrypoint /bin/bash lscr.io/linuxserver/bookstack:latest appkey +``` + +### 2. Configure for Testing + +```bash +# Copy testing example +cp .env.testing.example .env + +# Edit and add your APP_KEY +nano .env +``` + +### 3. Start Testing Instance + +```bash +# Start on port 8080 (default) +docker compose -f docker-compose.testing.yml up -d + +# Or use custom port +HOST_PORT=9000 docker compose -f docker-compose.testing.yml up -d +``` + +### 4. Access Locally + +Navigate to `http://localhost:8080` (or your custom HOST_PORT) + +**Default credentials:** `admin@admin.com` / `password` + +### 5. Cleanup + +```bash +# Stop and remove containers (keeps data) +docker compose -f docker-compose.testing.yml down + +# Stop and remove everything including data +docker compose -f docker-compose.testing.yml down +rm -rf bookstack_testing_data +``` + +## File Structure + +``` +tss-bookstack/ +├── docker-compose.yml # Production (with Caddy) +├── docker-compose.testing.yml # Local testing (without Caddy) +├── .env.example # Production config template +├── .env.testing.example # Testing config template +├── .env # Your actual config (not in git) +├── .gitignore # Git ignore rules +├── README.md # This file +├── QUICKSTART.md # Quick reference guide +├── TESTING.md # Local testing guide +├── VOLUMES.md # Volume management guide +└── EMAIL.md # Email configuration guide +``` + +## Data Storage + +### Production - Named Volumes + +Production uses **Docker named volumes** (managed by Docker): + +```yaml +volumes: + bookstack_data: # BookStack application data + bookstack_db: # MariaDB database +``` + +Data location: `/var/lib/docker/volumes/bookstack_data/_data/` + +```bash +# List volumes +docker volume ls | grep bookstack + +# Inspect volume +docker volume inspect bookstack_data +``` + +### Testing - Bind Mounts + +Testing uses **bind mounts** (direct folder access): + +``` +bookstack_testing_data/ +├── www/ # BookStack application files +│ ├── .env # BookStack configuration +│ ├── files/ # Uploaded files +│ ├── images/ # Uploaded images +│ └── themes/ # Custom themes +├── log/ # Application logs +├── backups/ # Database backups +└── db/ # MariaDB database +``` + +See `VOLUMES.md` for detailed information on backups and volume management + +## Configuration + +### Environment Variables + +All configuration is in `.env`: + +| Variable | Description | Example | +|----------|-------------|---------| +| `PUID` | User ID for file permissions | `1000` | +| `PGID` | Group ID for file permissions | `1000` | +| `TZ` | Timezone | `Europe/Berlin` | +| `APP_URL` | Your BookStack URL | `https://wiki.tss-hd.de` | +| `APP_KEY` | Encryption key (generate with appkey command) | `base64:xxx...` | +| `DB_DATABASE` | Database name | `bookstack` | +| `DB_USERNAME` | Database user | `bookstack` | +| `DB_PASSWORD` | Database password | `secure_password` | +| `MYSQL_ROOT_PASSWORD` | MySQL root password | `root_password` | +| `MAIL_DRIVER` | Mail driver (`log` or `smtp`) | `log` | + +### Additional BookStack Configuration + +To configure advanced features (LDAP, SMTP, etc.), edit the `.env` file inside the container: + +```bash +# Access the file via container +docker exec -it bookstack nano /config/www/.env + +# Or copy out, edit, and copy back +docker cp bookstack:/config/www/.env .env.bookstack +nano .env.bookstack +docker cp .env.bookstack bookstack:/config/www/.env +``` + +Then restart BookStack: + +```bash +docker compose restart bookstack +``` + +See [BookStack documentation](https://www.bookstackapp.com/docs/) for available options. + +## Maintenance + +### View Logs + +```bash +# All services +docker compose logs -f + +# Just BookStack +docker compose logs -f bookstack + +# Just Database +docker compose logs -f bookstack-db +``` + +### Update BookStack + +```bash +# Pull latest images +docker compose pull + +# Recreate containers +docker compose up -d + +# Clean up old images +docker image prune +``` + +### Backup + +#### Backup Database + +```bash +# Export database SQL dump +docker exec bookstack-db bash -c "mysqldump -u root -p\$MYSQL_ROOT_PASSWORD \$MYSQL_DATABASE" > backup-$(date +%Y%m%d).sql +``` + +#### Backup Named Volumes + +```bash +# Backup BookStack data volume +docker run --rm \ + -v bookstack_data:/data \ + -v $(pwd):/backup \ + alpine tar czf /backup/bookstack-data-$(date +%Y%m%d).tar.gz /data + +# Backup database volume +docker run --rm \ + -v bookstack_db:/data \ + -v $(pwd):/backup \ + alpine tar czf /backup/bookstack-db-$(date +%Y%m%d).tar.gz /data +``` + +See `VOLUMES.md` for restore procedures + +### Restore Database + +```bash +# Import database +docker exec -i bookstack-db mysql -u root -p$MYSQL_ROOT_PASSWORD $DB_DATABASE < backup-20241030.sql +``` + +### Access Container Shell + +```bash +# BookStack container +docker exec -it bookstack bash + +# Database container +docker exec -it bookstack-db bash +``` + +### Change APP_URL + +If you change `APP_URL` in `.env`, update the database: + +```bash +docker exec -it bookstack php /app/www/artisan bookstack:update-url \ + https://old-domain.com \ + https://new-domain.com +``` + +Then restart: + +```bash +docker compose restart bookstack +``` + +## Troubleshooting + +### Container won't start + +```bash +# Check logs +docker compose logs bookstack + +# Verify .env exists and is valid +cat .env + +# Check file permissions +ls -la bookstack_data/ +``` + +### Database connection failed + +```bash +# Verify database is running +docker compose ps + +# Check database logs +docker compose logs bookstack-db + +# Test database connection +docker exec -it bookstack-db mysql -u $DB_USERNAME -p$DB_PASSWORD +``` + +### Permission errors + +The linuxserver.io images handle permissions automatically using `PUID`/`PGID`. + +```bash +# Check your UID/GID +id + +# Update .env with correct PUID/PGID +nano .env + +# Recreate containers +docker compose up -d +``` + +### Can't access via domain + +```bash +# Verify container is on caddynet +docker inspect bookstack | grep caddynet + +# Check Caddy config +cat ../server-package/deckard/caddy/sites/wiki.tss-hd.de + +# Reload Caddy +cd ../server-package/deckard/caddy +docker compose restart caddy +``` + +### Clear cache + +```bash +docker exec bookstack php /app/www/artisan cache:clear +docker exec bookstack php /app/www/artisan config:clear +``` + +## Differences from DIY Setup + +Using linuxserver.io image instead of building from source: + +| Feature | DIY Build | linuxserver.io | +|---------|-----------|----------------| +| **Maintenance** | Manual updates | `docker compose pull` | +| **Setup** | Build from source | Pull pre-built image | +| **PHP/Composer** | Install on host | Included in image | +| **Permissions** | Manual `chown` | Automatic via PUID/PGID | +| **Updates** | Manual git pull + rebuild | Pull new image | +| **Support** | Self-support | linuxserver.io community | + +## Security Notes + +✅ No secrets in docker-compose files +✅ All configuration in `.env` +✅ `.env` should have restricted permissions (600) +✅ Change default admin credentials immediately +✅ Use strong passwords for DB_PASSWORD and MYSQL_ROOT_PASSWORD +✅ Regular backups recommended +✅ Keep images updated with `docker compose pull` + +## Links + +- [BookStack Documentation](https://www.bookstackapp.com/docs/) +- [linuxserver.io BookStack](https://docs.linuxserver.io/images/docker-bookstack/) +- [BookStack GitHub](https://github.com/BookStackApp/BookStack) +- [linuxserver.io](https://www.linuxserver.io/) diff --git a/deckard/bookstack/bookstack.env.example b/deckard/bookstack/bookstack.env.example new file mode 100644 index 0000000..e8862f2 --- /dev/null +++ b/deckard/bookstack/bookstack.env.example @@ -0,0 +1,33 @@ +# BookStack Application Configuration +# This file is mounted to /config/www/.env inside the container +# ONLY include BookStack-specific settings here + +# ============================================ +# Application Settings +# ============================================ + +APP_DEBUG=false +APP_ENV=production +APP_LANG=en +APP_TIMEZONE=Europe/Berlin + +# ============================================ +# Mail Settings - Microsoft 365 +# ============================================ + +MAIL_MAILER=smtp +MAIL_HOST=smtp-hve.office365.com +MAIL_PORT=587 +MAIL_ENCRYPTION=tls +MAIL_USERNAME=noreply@tss-hd.de +MAIL_PASSWORD= +MAIL_FROM=noreply@tss-hd.de +MAIL_FROM_NAME="TSS Wiki (Testing)" + +# ============================================ +# Storage & Cache +# ============================================ + +STORAGE_TYPE=local_secure +SESSION_DRIVER=file +CACHE_DRIVER=file diff --git a/deckard/bookstack/bookstack.testing.env b/deckard/bookstack/bookstack.testing.env new file mode 100644 index 0000000..e8862f2 --- /dev/null +++ b/deckard/bookstack/bookstack.testing.env @@ -0,0 +1,33 @@ +# BookStack Application Configuration +# This file is mounted to /config/www/.env inside the container +# ONLY include BookStack-specific settings here + +# ============================================ +# Application Settings +# ============================================ + +APP_DEBUG=false +APP_ENV=production +APP_LANG=en +APP_TIMEZONE=Europe/Berlin + +# ============================================ +# Mail Settings - Microsoft 365 +# ============================================ + +MAIL_MAILER=smtp +MAIL_HOST=smtp-hve.office365.com +MAIL_PORT=587 +MAIL_ENCRYPTION=tls +MAIL_USERNAME=noreply@tss-hd.de +MAIL_PASSWORD= +MAIL_FROM=noreply@tss-hd.de +MAIL_FROM_NAME="TSS Wiki (Testing)" + +# ============================================ +# Storage & Cache +# ============================================ + +STORAGE_TYPE=local_secure +SESSION_DRIVER=file +CACHE_DRIVER=file diff --git a/deckard/bookstack/docker-compose.testing.yml b/deckard/bookstack/docker-compose.testing.yml new file mode 100644 index 0000000..cfc9a33 --- /dev/null +++ b/deckard/bookstack/docker-compose.testing.yml @@ -0,0 +1,60 @@ +# Local testing configuration +# - NO Caddy reverse proxy +# - NO HTTPS +# - Uses testing env vars +# Access via http://localhost:9000 + +networks: + bookstack: + external: false + caddynet: + external: true + + +volumes: + bookstack-config: + bookstack-db-data: + +services: + bookstack: + image: lscr.io/linuxserver/bookstack:latest + container_name: bookstack + restart: unless-stopped + environment: + - PUID=${PUID} + - PGID=${PGID} + - TZ=${TZ} + - DB_HOST=bookstack-db + - DB_PORT=3306 + - DB_USERNAME=${DB_USERNAME} + - DB_PASSWORD=${DB_PASSWORD} + - DB_DATABASE=${DB_DATABASE} + - APP_URL=${APP_URL} + - APP_KEY=${APP_KEY} + networks: + - bookstack + - caddynet + ports: + - "9000:80" + volumes: + - bookstack-config:/config + - ./bookstack.testing.env:/config/www/.env:ro + depends_on: + - bookstack-db + + bookstack-db: + image: lscr.io/linuxserver/mariadb:latest + container_name: bookstack-db-testing + restart: unless-stopped + environment: + - PUID=${PUID} + - PGID=${PGID} + - TZ=${TZ} + - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} + - MYSQL_DATABASE=${DB_DATABASE} + - MYSQL_USER=${DB_USERNAME} + - MYSQL_PASSWORD=${DB_PASSWORD} + networks: + - bookstack + volumes: + - bookstack-db-data:/var/lib/mysql diff --git a/deckard/bookstack/docker-compose.yml b/deckard/bookstack/docker-compose.yml new file mode 100644 index 0000000..c5b7d9f --- /dev/null +++ b/deckard/bookstack/docker-compose.yml @@ -0,0 +1,58 @@ +# Local testing configuration +# - NO Caddy reverse proxy +# - NO HTTPS +# - Uses testing env vars +# Access via http://localhost:9000 + +networks: + bookstack: + external: false + caddynet: + external: true + + +volumes: + bookstack-config: + bookstack-db-data: + +services: + bookstack: + image: lscr.io/linuxserver/bookstack:latest + container_name: bookstack + restart: unless-stopped + environment: + - PUID=${PUID} + - PGID=${PGID} + - TZ=${TZ} + - DB_HOST=bookstack-db + - DB_PORT=3306 + - DB_USERNAME=${DB_USERNAME} + - DB_PASSWORD=${DB_PASSWORD} + - DB_DATABASE=${DB_DATABASE} + - APP_URL=${APP_URL} + - APP_KEY=${APP_KEY} + networks: + - bookstack + - caddynet + volumes: + - bookstack-config:/config + - ./bookstack.env:/config/www/.env:ro + depends_on: + - bookstack-db + + bookstack-db: + image: lscr.io/linuxserver/mariadb:latest + container_name: bookstack-db-testing + restart: unless-stopped + environment: + - PUID=${PUID} + - PGID=${PGID} + - TZ=${TZ} + - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} + - MYSQL_DATABASE=${DB_DATABASE} + - MYSQL_USER=${DB_USERNAME} + - MYSQL_PASSWORD=${DB_PASSWORD} + networks: + - bookstack + volumes: + - bookstack-db-data:/var/lib/mysql diff --git a/deckard/caddy/sites/wiki.tss-hd.de b/deckard/caddy/sites/wiki.tss-hd.de new file mode 100644 index 0000000..bcd8e15 --- /dev/null +++ b/deckard/caddy/sites/wiki.tss-hd.de @@ -0,0 +1,9 @@ +https://www.wiki.tss-hd.de { + redir https://wiki.tss-hd.de{uri} +} + +https://wiki.tss-hd.de { + reverse_proxy bookstack:9000 { + flush_interval -1 + } +}