Skip to content

Add Raspberry Pi deployment scripts and documentation#17

Closed
bbernstein wants to merge 1 commit intomainfrom
feature/rpi-deployment-scripts
Closed

Add Raspberry Pi deployment scripts and documentation#17
bbernstein wants to merge 1 commit intomainfrom
feature/rpi-deployment-scripts

Conversation

@bbernstein
Copy link
Copy Markdown
Owner

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

  • Downloads GitHub release archives (not git repos)
  • Smaller footprint and faster downloads
  • Predictable versions from tagged releases
  • No git knowledge required

🔄 Version Management

  • CLI tool for checking/updating versions
  • Integrated with backend GraphQL API
  • Web UI in Settings page
  • Update individual repos or all at once
  • Automatic backups before updates

🛠️ Production Ready

  • Systemd service with auto-restart
  • Nginx reverse proxy configuration
  • Security hardening (dedicated user, permissions)
  • Comprehensive logging and monitoring

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 setup
  • lacylights-backend.service - Systemd service unit

Documentation

  • README.md - Deployment guide with troubleshooting (300+ lines)

Testing

  • ✅ Scripts tested on current RPi at lacylights.local
  • ✅ Version management UI working
  • ✅ Update mechanism tested (versions query, available versions)
  • ✅ Nginx configuration tested with scene-board dynamic routes
  • ✅ Systemd service runs with security restrictions

Benefits

  1. Repeatable: Deploy to multiple RPis consistently
  2. Maintainable: Clear documentation and troubleshooting
  3. User-Friendly: Web UI for version management
  4. Production-Ready: Proper service management and security
  5. Future-Proof: Easy to update with new releases

Usage Examples

Fresh RPi Setup

# On new Raspberry Pi OS installation
curl -fsSL https://raw.githubusercontent.com/bbernstein/lacylights/main/rpi-deployment/setup-rpi.sh | sudo bash

Version Management (CLI)

# Check versions
/opt/lacylights/scripts/update-repos.sh versions

# Update all to latest
sudo /opt/lacylights/scripts/update-repos.sh update-all

# Update specific repo to specific version
sudo /opt/lacylights/scripts/update-repos.sh update lacylights-node 1.3.6

Version Management (Web UI)

  1. Navigate to Settings
  2. Scroll to "Version Management"
  3. Click "Update" or "Update All"

Next Steps

After merge:

  1. Test fresh deployment on a new RPi
  2. Document in main README
  3. Consider adding to release process

🤖 Generated with Claude Code

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>
Copilot AI review requested due to automatic review settings November 12, 2025 13:54
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +152 to +153
# Remove old files (except node_modules and .env)
find "$dir" -mindepth 1 -maxdepth 1 ! -name 'node_modules' ! -name '.env' ! -name 'prisma' -exec rm -rf {} +
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
# 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

Copilot uses AI. Check for mistakes.
cd "$dir"
if [ -f "package.json" ]; then
echo "Installing dependencies..."
npm install --production
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +168 to +169
npx prisma migrate deploy || true
npx prisma generate || true
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
npx prisma migrate deploy || true
npx prisma generate || true
npx prisma migrate deploy
npx prisma generate

Copilot uses AI. Check for mistakes.
Comment on lines +175 to +181
npm run build || true
fi

# For frontend, build static export
if [ "$repo" = "lacylights-fe" ]; then
echo "Building frontend..."
npm run build || true
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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

Copilot uses AI. Check for mistakes.
# For frontend, build static export
if [ "$repo" = "lacylights-fe" ]; then
echo "Building frontend..."
npm run build || true
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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

Copilot uses AI. Check for mistakes.

# Install dependencies
echo "Installing backend dependencies..."
sudo -u "$LACYLIGHTS_USER" npm install --production
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.

# Install dependencies
echo "Installing frontend dependencies..."
sudo -u "$LACYLIGHTS_USER" npm install --production
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +198 to +203
sudo -u "$LACYLIGHTS_USER" npm install --production

# Build MCP
echo "Building MCP server..."
sudo -u "$LACYLIGHTS_USER" npm run build

Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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

Copilot uses AI. Check for mistakes.
Comment on lines +77 to +82
# 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;
}

Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[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.

Suggested change
# 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;
}

Copilot uses AI. Check for mistakes.
Comment thread rpi-deployment/README.md
- Enable version management

The setup takes 10-15 minutes depending on your Pi and network speed.

Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[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.

Suggested change
**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.

Copilot uses AI. Check for mistakes.
@bbernstein
Copy link
Copy Markdown
Owner Author

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:

  • More comprehensive setup scripts and documentation
  • Better organized structure with setup/, scripts/, and docs/ directories
  • Updated version management that now uses pre-built release artifacts (PR import instruments at setup time #4)
  • Complete deployment guides and troubleshooting documentation

The lacylights repository should remain focused on documentation and references to the other repositories, while lacylights-rpi contains all RPi-specific deployment infrastructure.

Related:

@bbernstein bbernstein closed this Nov 13, 2025
@bbernstein bbernstein deleted the feature/rpi-deployment-scripts branch November 13, 2025 16:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants