Add Raspberry Pi deployment scripts and documentation#17
Add Raspberry Pi deployment scripts and documentation#17bbernstein wants to merge 1 commit intomainfrom
Conversation
Adds comprehensive deployment system for LacyLights on Raspberry Pi: ## New Files ### Scripts - `setup-rpi.sh` - Complete initial setup for fresh Raspberry Pi - Downloads latest releases from GitHub (no git repos) - Installs all dependencies (Node.js, nginx, SQLite) - Creates lacylights user with proper permissions - Sets up database and runs migrations - Builds backend, frontend, and MCP server - Configures nginx and systemd service - Enables version management - `update-repos.sh` - Version management script - Checks installed vs latest versions - Downloads release archives from GitHub - Updates individual repositories or all at once - Backs up before updating - Runs migrations and rebuilds automatically - Integrated with backend GraphQL API ### Configuration Files - `nginx-lacylights.conf` - Nginx reverse proxy configuration - Serves frontend static files - Proxies /graphql to backend - Handles WebSocket connections for subscriptions - Configures dynamic route fallbacks - `lacylights-backend.service` - Systemd service unit - Runs backend as lacylights user - Auto-restart on failure - Security hardening (ProtectSystem, ProtectHome, etc.) - Journal logging integration ### Documentation - `README.md` - Complete deployment guide - Quick start for fresh RPi - Version management instructions - Service management commands - Troubleshooting section - Security considerations - Network configuration ## Deployment Approach Uses **GitHub release archives** instead of git repositories: - Simpler for end users (no git knowledge required) - Smaller footprint (no .git directories) - Faster downloads (tarballs vs git clone) - Predictable versions (tagged releases only) - Works with web UI version management ## Usage ### Fresh Raspberry Pi: ```bash curl -fsSL https://raw.githubusercontent.com/bbernstein/lacylights/main/rpi-deployment/setup-rpi.sh | sudo bash ``` ### Update to latest: ```bash sudo /opt/lacylights/scripts/update-repos.sh update-all ``` ### Web UI: Settings → Version Management → Update All ## Benefits - **Turnkey solution**: One command sets up complete system - **Version management**: Built-in update mechanism with UI - **Production ready**: Systemd service, nginx, proper permissions - **Maintainable**: Clear documentation and troubleshooting - **Repeatable**: Can deploy to multiple Raspberry Pis consistently 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Pull Request Overview
This PR adds a comprehensive deployment system for LacyLights on Raspberry Pi, enabling single-command setup and version management through both CLI and web UI using GitHub release archives.
- One-command setup script that fully configures a fresh Raspberry Pi
- CLI-based version management tool for checking and updating repository versions
- Production-ready configuration with systemd service, nginx reverse proxy, and security hardening
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
update-repos.sh |
Version management script for checking installed/latest versions and updating repositories from GitHub releases |
setup-rpi.sh |
Initial setup script that installs dependencies, downloads releases, configures services, and sets up the complete LacyLights stack |
nginx-lacylights.conf |
Nginx configuration for serving static frontend and proxying GraphQL/WebSocket requests to the backend |
lacylights-backend.service |
Systemd service unit file for running the backend server with security restrictions |
README.md |
Comprehensive deployment documentation including setup instructions, version management, troubleshooting, and security considerations |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Remove old files (except node_modules and .env) | ||
| find "$dir" -mindepth 1 -maxdepth 1 ! -name 'node_modules' ! -name '.env' ! -name 'prisma' -exec rm -rf {} + |
There was a problem hiding this comment.
The exclusion of 'prisma' directory may not work as intended. The backend's prisma directory should be preserved to avoid losing schema and migration files, but this find command will fail to exclude it if there are spaces in filenames. Additionally, this could accidentally delete the prisma directory if any file operations fail. Consider using a more explicit deletion pattern that only removes known directories/files.
| # Remove old files (except node_modules and .env) | |
| find "$dir" -mindepth 1 -maxdepth 1 ! -name 'node_modules' ! -name '.env' ! -name 'prisma' -exec rm -rf {} + | |
| # Remove old files (except node_modules, .env, and prisma) | |
| for item in "$dir"/* "$dir"/.*; do | |
| basename="$(basename "$item")" | |
| # Skip . (current dir), .. (parent dir), node_modules, .env, and prisma | |
| if [ "$basename" = "." ] || [ "$basename" = ".." ] || [ "$basename" = "node_modules" ] || [ "$basename" = ".env" ] || [ "$basename" = "prisma" ]; then | |
| continue | |
| fi | |
| rm -rf -- "$item" | |
| done |
| cd "$dir" | ||
| if [ -f "package.json" ]; then | ||
| echo "Installing dependencies..." | ||
| npm install --production |
There was a problem hiding this comment.
Installing with --production flag will skip devDependencies, but the build steps that follow (lines 175, 181) may require dev dependencies for TypeScript compilation. Consider installing all dependencies before build, then pruning devDependencies after build completes with npm prune --production.
| npx prisma migrate deploy || true | ||
| npx prisma generate || true |
There was a problem hiding this comment.
Using || true suppresses errors from database migrations and Prisma client generation, which could lead to runtime failures if migrations fail. These operations are critical and should fail loudly. Consider removing || true or at least logging a warning when these commands fail.
| npx prisma migrate deploy || true | |
| npx prisma generate || true | |
| npx prisma migrate deploy | |
| npx prisma generate |
| npm run build || true | ||
| fi | ||
|
|
||
| # For frontend, build static export | ||
| if [ "$repo" = "lacylights-fe" ]; then | ||
| echo "Building frontend..." | ||
| npm run build || true |
There was a problem hiding this comment.
Using || true suppresses build errors which could result in deploying broken code. Build failures should halt the update process. Consider removing || true or implementing proper error handling with rollback to the backup directory.
| npm run build || true | |
| fi | |
| # For frontend, build static export | |
| if [ "$repo" = "lacylights-fe" ]; then | |
| echo "Building frontend..." | |
| npm run build || true | |
| if ! npm run build; then | |
| echo "Build failed for ${repo}. Rolling back to backup." | |
| rm -rf "$dir" | |
| mv "$backup_dir" "$dir" | |
| rm -rf "/tmp/lacylights-update-${repo}" | |
| echo "Update failed. Rolled back to previous version." | |
| return 1 | |
| fi | |
| fi | |
| # For frontend, build static export | |
| if [ "$repo" = "lacylights-fe" ]; then | |
| echo "Building frontend..." | |
| if ! npm run build; then | |
| echo "Frontend build failed for ${repo}. Rolling back to backup." | |
| rm -rf "$dir" | |
| mv "$backup_dir" "$dir" | |
| rm -rf "/tmp/lacylights-update-${repo}" | |
| echo "Update failed. Rolled back to previous version." | |
| return 1 | |
| fi |
| # For frontend, build static export | ||
| if [ "$repo" = "lacylights-fe" ]; then | ||
| echo "Building frontend..." | ||
| npm run build || true |
There was a problem hiding this comment.
Using || true suppresses build errors which could result in deploying broken code. Build failures should halt the update process. Consider removing || true or implementing proper error handling with rollback to the backup directory.
| npm run build || true | |
| if ! npm run build; then | |
| echo "Frontend build failed. Restoring backup..." | |
| rm -rf "$dir" | |
| cp -r "$backup_dir" "$dir" | |
| echo "Update failed. Backup restored." | |
| return 1 | |
| fi |
|
|
||
| # Install dependencies | ||
| echo "Installing backend dependencies..." | ||
| sudo -u "$LACYLIGHTS_USER" npm install --production |
There was a problem hiding this comment.
Installing with --production flag will skip devDependencies, but the build step at line 169 may require dev dependencies for TypeScript compilation. Consider installing all dependencies before build, then pruning devDependencies after with npm prune --production.
|
|
||
| # Install dependencies | ||
| echo "Installing frontend dependencies..." | ||
| sudo -u "$LACYLIGHTS_USER" npm install --production |
There was a problem hiding this comment.
Installing with --production flag will skip devDependencies, but the build step at line 184 may require dev dependencies for Next.js build tooling. Consider installing all dependencies before build, then pruning devDependencies after with npm prune --production.
| sudo -u "$LACYLIGHTS_USER" npm install --production | ||
|
|
||
| # Build MCP | ||
| echo "Building MCP server..." | ||
| sudo -u "$LACYLIGHTS_USER" npm run build | ||
|
|
There was a problem hiding this comment.
Installing with --production flag will skip devDependencies, but the build step at line 202 may require dev dependencies for TypeScript compilation. Consider installing all dependencies before build, then pruning devDependencies after with npm prune --production.
| sudo -u "$LACYLIGHTS_USER" npm install --production | |
| # Build MCP | |
| echo "Building MCP server..." | |
| sudo -u "$LACYLIGHTS_USER" npm run build | |
| sudo -u "$LACYLIGHTS_USER" npm install | |
| # Build MCP | |
| echo "Building MCP server..." | |
| sudo -u "$LACYLIGHTS_USER" npm run build | |
| # Prune devDependencies after build | |
| sudo -u "$LACYLIGHTS_USER" npm prune --production |
| # Explicitly handle index pages (must come before regex dynamic routes) | ||
| # This prevents try_files $uri/ from accidentally serving wrong files | ||
| location = /cue-lists/ { | ||
| try_files /cue-lists/index.html =404; | ||
| } | ||
|
|
There was a problem hiding this comment.
[nitpick] The comment on line 78 states 'This prevents try_files $uri/ from accidentally serving wrong files', but the generic SPA routing at line 106 uses try_files $uri $uri/ $uri.html /index.html which includes $uri/. This explicit location block may be unnecessary if the main location already handles it correctly. Consider clarifying the purpose or removing if redundant.
| # Explicitly handle index pages (must come before regex dynamic routes) | |
| # This prevents try_files $uri/ from accidentally serving wrong files | |
| location = /cue-lists/ { | |
| try_files /cue-lists/index.html =404; | |
| } |
| - Enable version management | ||
|
|
||
| The setup takes 10-15 minutes depending on your Pi and network speed. | ||
|
|
There was a problem hiding this comment.
[nitpick] The estimated setup time may be inaccurate if the script installs with --production flag but still needs to build (which requires dev dependencies). If builds fail due to missing dev dependencies, the actual setup time and success rate could differ. This should be verified after fixing the npm install issues.
| **Note:** If the setup script installs Node.js dependencies with the `--production` flag but still needs to build the project (which requires dev dependencies), the build may fail due to missing dev dependencies. In such cases, troubleshooting and additional installation steps may be required, which can increase the actual setup time. |
|
Closing this PR as the RPi deployment work has been moved to a dedicated repository: https://github.com/bbernstein/lacylights-rpi The lacylights-rpi repository contains:
The Related:
|
Summary
Adds comprehensive deployment system for LacyLights on Raspberry Pi, enabling easy setup of fresh devices and version management through both CLI and web UI.
New Features
🚀 One-Command Setup
Fresh Raspberry Pi can be set up with a single command:
curl -fsSL https://raw.githubusercontent.com/bbernstein/lacylights/main/rpi-deployment/setup-rpi.sh | sudo bash📦 Release-Based Deployment
🔄 Version Management
🛠️ Production Ready
Files Added
Scripts
setup-rpi.sh- Complete initial setup (240 lines)update-repos.sh- Version management (220 lines)Configuration
nginx-lacylights.conf- Nginx reverse proxy setuplacylights-backend.service- Systemd service unitDocumentation
README.md- Deployment guide with troubleshooting (300+ lines)Testing
Benefits
Usage Examples
Fresh RPi Setup
Version Management (CLI)
Version Management (Web UI)
Next Steps
After merge:
🤖 Generated with Claude Code