- Add image-fetcher module for downloading and saving images from various sources. - Create storage module for managing image files, including downloading, verifying integrity, and cleaning up orphaned files. - Develop gallery HTML page for displaying images with sorting and filtering options. - Set up RESTful API routes for image management, including fetching, adding tags, and deleting images. - Introduce setup script for initializing the database and configuring image sources. - Implement a batch process for verifying image integrity and cleaning up old images. - Add setup batch script for easy installation and configuration of the image storage system.
7.6 KiB
🐳 Docker Deployment Guide for Image Storage
This guide covers deployment of the HomeBase image storage system in Docker on your home lab.
Prerequisites
- Docker and Docker Compose installed on your home lab server (beepc)
- SSH access configured (required for deploy script)
- PowerShell 5+ or PowerShell Core for running deploy scripts
- Network access from your dev machine to the home lab
Quick Deployment
1. Deploy to Home Lab
From your local machine, run:
.\scripts\deploy.ps1
This script will:
- Copy all project files to your home lab server (spencer@beepc)
- Build the Docker image
- Create and start the container with persistent storage
- Set up systemd service for auto-start
2. After Deployment
The container will automatically:
- Create the SQLite database
- Create image storage directories
- Start the image fetcher (if configured)
- Be available at
http://homebase.sketchferret.com
Docker Setup Details
Persistent Storage
Images are stored in a Docker volume called homebase-data:
volumes:
- homebase-data:/app/data
This ensures:
- Database persists across container restarts
- Image files are not lost on container recreation
- Data survives container updates
Viewing Container Logs
# SSH into home lab
ssh spencer@beepc
# View container logs
docker compose -f ~/homebase/docker-compose.yml logs -f
# Or use systemd
journalctl -u homebase -f
Container Management
# Stop container
docker compose -f ~/homebase/docker-compose.yml down
# Rebuild and restart
docker compose -f ~/homebase/docker-compose.yml up -d --build
# Check status
docker compose -f ~/homebase/docker-compose.yml ps
# View stored images
docker exec homebase ls -lh /app/data/images/
Configuration in Docker
Image Sources (image-sources.json)
After deployment, edit the configuration on the remote server:
ssh spencer@beepc
nano ~/homebase/image-sources.json
Then restart the container:
cd ~/homebase
docker compose restart app
Environment Variables
Edit docker-compose.yml to customize:
environment:
- NODE_ENV=production
- PORT=3001
- DOMAIN=homebase.sketchferret.com
Managing Data
Backup Database
The SQLite database is stored in the Docker volume at /app/data/homebase.db
# SSH into server
ssh spencer@beepc
# Backup database
docker run --rm -v homebase-data:/data \
-v ~/backups:/backup \
alpine cp /data/homebase.db /backup/homebase.db.$(date +%Y%m%d)
# Backup images
docker run --rm -v homebase-data:/data \
-v ~/backups:/backup \
alpine tar czf /backup/images.$(date +%Y%m%d).tar.gz /data/images/
Restore Database
docker run --rm -v homebase-data:/data \
-v ~/backups:/backup \
alpine cp /backup/homebase.db.20260211 /data/homebase.db
# Restart container
docker restart homebase
Clean Up Old Images
# SSH into server
ssh spencer@beepc
# Connect to running container
docker exec -it homebase node -e "
const db = require('./lib/database');
db.initializeDatabase().then(async () => {
const deleted = await db.cleanupOldImages(30);
console.log('Deleted', deleted, 'old images');
process.exit(0);
}).catch(err => {
console.error(err);
process.exit(1);
});
"
Troubleshooting
Container won't start
ssh spencer@beepc
cd ~/homebase
# Check logs
docker compose logs app
# Rebuild
docker compose up -d --build
# Check again
docker compose ps
Permission errors
The container runs as the node user. Check logs:
docker compose exec app ls -la /app/data/
All files should be owned by node.
Can't access via domain
Check that the service is running:
ssh spencer@beepc
# Check systemd
systemctl status homebase
# Check Docker
docker ps | grep homebase
# Test port
curl -i http://localhost:3001/health
Database is locked
This usually means two processes are accessing the database simultaneously:
# Check if multiple containers are running
docker ps -a | grep homebase
# Stop all containers
docker compose down
# Verify only one is running
docker compose up -d
Updating the Deployment
Update Code
After making changes locally:
cd c:\Users\srene\Sources\HomeBase
git commit -am "Add new features"
git push
# Deploy to home lab
.\scripts\deploy.ps1
Update Dependencies
If you update package.json:
# From your local machine
.\scripts\deploy.ps1
# The deploy script will:
# 1. Copy new package.json
# 2. Rebuild the Docker image (npm install runs here)
# 3. Restart the container
Manual Updates
SSH into the server and run:
cd ~/homebase
# Pull latest code
git pull # If using git
# Or manually copy files via SCP
# Then rebuild:
docker compose up -d --build
Systemd Service
The deployment script sets up a systemd service:
# Check service
systemctl status homebase
# Start service
sudo systemctl start homebase
# Stop service
sudo systemctl stop homebase
# View logs
journalctl -u homebase -f
Service file location: /etc/systemd/system/homebase.service
Volume Management
List volumes
docker volume ls | grep homebase
Inspect volume
docker volume inspect homebase-data
Shows the mount point on the host server.
Manual mount (for recovery)
docker run -it --rm -v homebase-data:/data alpine sh
Then you can inspect files at /data/
Performance Optimization
Monitor Storage Usage
curl http://homebase.sketchferret.com/api/stats
Cleanup Recommendations
- Weekly: Run cleanup for images older than 7 days
- Monthly: Run verification to check corruption
- Quarterly: Full database optimization
# SSH into server
ssh spencer@beepc
docker exec homebase node -e "
const db = require('./lib/database');
const storage = require('./lib/storage');
db.initializeDatabase().then(async () => {
console.log('Running cleanup...');
const deleted = await db.cleanupOldImages(7);
const orphaned = await storage.cleanupOrphanedFiles(db.db);
console.log('Deleted:', deleted, 'old images');
console.log('Removed:', orphaned.cleaned, 'orphaned files');
process.exit(0);
}).catch(err => {
console.error('Error:', err);
process.exit(1);
});
"
Network & Firewall
Open Ports
Ensure port 3001 is accessible on your home lab network:
# Check if port is listening
ssh spencer@beepc
netstat -tlnp | grep 3001
# Or use Docker
docker port homebase
Domain Configuration
The app is configured to run on homebase.sketchferret.com. Ensure:
- DNS resolves to your home lab IP
- Firewall allows traffic on port 3001
- Your home lab router has port forwarding (if external access needed)
Debugging
Enable detailed logging
# SSH into server
ssh spencer@beepc
# View container logs with timestamps
docker compose logs -f --timestamps app
# Or view the last 100 lines
docker compose logs --tail=100 app
Access container shell
docker exec -it homebase sh
cd /app
node setup.js config
Database inspection
# Access SQLite directly
docker exec -it homebase sqlite3 /app/data/homebase.db
# In sqlite prompt:
sqlite> SELECT COUNT(*) FROM images;
sqlite> SELECT * FROM tags;
sqlite> .quit
Best Practices
- Regular Backups: Back up the database volume weekly
- Log Monitoring: Check logs regularly for errors
- Storage Limits: Monitor storage and clean up old images
- Configuration: Keep
image-sources.jsonupdated with working URLs - Testing: Test image fetching after configuration changes
For API usage, see IMAGE_STORAGE_GUIDE.md