Add NextSnap PWA with photo gallery viewer and continuous capture
Offline-first photo capture app for Nextcloud with: - Camera capture with continuous mode (auto-reopens after each photo) - File browser with fullscreen image gallery, swipe navigation, and rename - Upload queue with background sync engine - Admin panel for Nextcloud user management - Service worker for offline-first caching (v13) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
336
DEPLOYMENT.md
Normal file
336
DEPLOYMENT.md
Normal file
@@ -0,0 +1,336 @@
|
||||
# NextSnap Deployment Guide
|
||||
|
||||
This guide covers deploying NextSnap using Docker and Docker Compose.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Docker 20.10 or later
|
||||
- Docker Compose 2.0 or later
|
||||
- A Nextcloud instance with admin access
|
||||
- HTTPS setup (required for PWA features)
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Clone the Repository
|
||||
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd nextsnap
|
||||
```
|
||||
|
||||
### 2. Configure Environment Variables
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Edit `.env` and set your values:
|
||||
|
||||
```bash
|
||||
# Generate a secure secret key
|
||||
python -c "import secrets; print(secrets.token_hex(32))"
|
||||
|
||||
# Update .env with:
|
||||
SECRET_KEY=<generated-key>
|
||||
NEXTCLOUD_URL=https://your-nextcloud-instance.com
|
||||
PORT=8000
|
||||
TZ=America/New_York
|
||||
```
|
||||
|
||||
### 3. Build and Run
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
The application will be available at `http://localhost:8000`
|
||||
|
||||
### 4. Verify Deployment
|
||||
|
||||
```bash
|
||||
# Check container status
|
||||
docker-compose ps
|
||||
|
||||
# Check logs
|
||||
docker-compose logs -f nextsnap
|
||||
|
||||
# Test health endpoint
|
||||
curl http://localhost:8000/api/health
|
||||
```
|
||||
|
||||
## Production Deployment
|
||||
|
||||
### HTTPS Setup (Required)
|
||||
|
||||
NextSnap requires HTTPS for PWA features and secure cookies. Use a reverse proxy:
|
||||
|
||||
#### Option 1: Nginx
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name nextsnap.example.com;
|
||||
|
||||
ssl_certificate /path/to/cert.pem;
|
||||
ssl_certificate_key /path/to/key.pem;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:8000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# WebSocket support
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
||||
# Timeouts for large uploads
|
||||
proxy_read_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
client_max_body_size 50M;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Option 2: Caddy
|
||||
|
||||
```
|
||||
nextsnap.example.com {
|
||||
reverse_proxy localhost:8000
|
||||
}
|
||||
```
|
||||
|
||||
#### Option 3: Traefik
|
||||
|
||||
Update `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
nextsnap:
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.nextsnap.rule=Host(`nextsnap.example.com`)"
|
||||
- "traefik.http.routers.nextsnap.entrypoints=websecure"
|
||||
- "traefik.http.routers.nextsnap.tls.certresolver=myresolver"
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Required | Default | Description |
|
||||
|----------|----------|---------|-------------|
|
||||
| `SECRET_KEY` | Yes | - | Flask secret key for sessions |
|
||||
| `NEXTCLOUD_URL` | Yes | - | URL of your Nextcloud instance |
|
||||
| `PORT` | No | 8000 | Port to expose the application |
|
||||
| `TZ` | No | UTC | Container timezone |
|
||||
| `FLASK_ENV` | No | production | Flask environment |
|
||||
|
||||
### Security Recommendations
|
||||
|
||||
1. **Use a Strong Secret Key**
|
||||
```bash
|
||||
python -c "import secrets; print(secrets.token_hex(32))"
|
||||
```
|
||||
|
||||
2. **Enable HTTPS**
|
||||
- Required for PWA installation
|
||||
- Required for secure cookies
|
||||
|
||||
3. **Keep Docker Images Updated**
|
||||
```bash
|
||||
docker-compose pull
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
4. **Restrict Network Access**
|
||||
- Only expose port 8000 to reverse proxy
|
||||
- Use firewall rules to limit access
|
||||
|
||||
5. **Monitor Logs**
|
||||
```bash
|
||||
docker-compose logs -f --tail=100 nextsnap
|
||||
```
|
||||
|
||||
### Backup and Restore
|
||||
|
||||
#### Backup Session Data
|
||||
|
||||
```bash
|
||||
# Create backup
|
||||
docker run --rm -v nextsnap_flask_sessions:/data -v $(pwd):/backup \
|
||||
alpine tar czf /backup/sessions_backup.tar.gz -C /data .
|
||||
```
|
||||
|
||||
#### Restore Session Data
|
||||
|
||||
```bash
|
||||
# Restore backup
|
||||
docker run --rm -v nextsnap_flask_sessions:/data -v $(pwd):/backup \
|
||||
alpine tar xzf /backup/sessions_backup.tar.gz -C /data
|
||||
```
|
||||
|
||||
## Updating
|
||||
|
||||
### Pull Latest Changes
|
||||
|
||||
```bash
|
||||
git pull origin main
|
||||
```
|
||||
|
||||
### Rebuild and Restart
|
||||
|
||||
```bash
|
||||
docker-compose down
|
||||
docker-compose build --no-cache
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### Check for Breaking Changes
|
||||
|
||||
Review `CHANGELOG.md` and update your `.env` if new variables are required.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Container Won't Start
|
||||
|
||||
```bash
|
||||
# Check logs
|
||||
docker-compose logs nextsnap
|
||||
|
||||
# Check environment variables
|
||||
docker-compose config
|
||||
```
|
||||
|
||||
### Connection to Nextcloud Fails
|
||||
|
||||
1. Verify `NEXTCLOUD_URL` is correct
|
||||
2. Test Nextcloud connectivity:
|
||||
```bash
|
||||
curl -I https://your-nextcloud-instance.com
|
||||
```
|
||||
3. Check Nextcloud CORS settings
|
||||
4. Verify user credentials
|
||||
|
||||
### PWA Not Installing
|
||||
|
||||
1. Ensure HTTPS is enabled
|
||||
2. Check manifest is accessible: `https://your-domain.com/static/manifest.json`
|
||||
3. Check service worker: `https://your-domain.com/static/sw.js`
|
||||
4. Open browser DevTools → Application → Service Workers
|
||||
|
||||
### Session Issues
|
||||
|
||||
```bash
|
||||
# Clear session data
|
||||
docker-compose down
|
||||
docker volume rm nextsnap_flask_sessions
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### Large Upload Failures
|
||||
|
||||
1. Check `MAX_CONTENT_LENGTH` in `config.py` (default: 50MB)
|
||||
2. Increase nginx/proxy timeout values
|
||||
3. Check Nextcloud upload limits
|
||||
|
||||
## Performance Tuning
|
||||
|
||||
### Gunicorn Workers
|
||||
|
||||
Edit `Dockerfile` CMD to adjust workers:
|
||||
|
||||
```dockerfile
|
||||
CMD ["gunicorn", \
|
||||
"--workers", "8", \ # Increase for more traffic
|
||||
"--bind", "0.0.0.0:8000", \
|
||||
...
|
||||
```
|
||||
|
||||
Rule of thumb: `workers = (2 * CPU_cores) + 1`
|
||||
|
||||
### Resource Limits
|
||||
|
||||
Add to `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
nextsnap:
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2'
|
||||
memory: 1G
|
||||
reservations:
|
||||
cpus: '0.5'
|
||||
memory: 256M
|
||||
```
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Health Checks
|
||||
|
||||
```bash
|
||||
# Built-in health endpoint
|
||||
curl http://localhost:8000/api/health
|
||||
|
||||
# Container health status
|
||||
docker inspect --format='{{.State.Health.Status}}' nextsnap
|
||||
```
|
||||
|
||||
### Logs
|
||||
|
||||
```bash
|
||||
# Follow logs
|
||||
docker-compose logs -f nextsnap
|
||||
|
||||
# Last 100 lines
|
||||
docker-compose logs --tail=100 nextsnap
|
||||
|
||||
# Filter by timestamp
|
||||
docker-compose logs --since 30m nextsnap
|
||||
```
|
||||
|
||||
### Metrics
|
||||
|
||||
Consider adding:
|
||||
- Prometheus metrics
|
||||
- Grafana dashboards
|
||||
- Alert manager for errors
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
### Custom Port
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
ports:
|
||||
- "3000:8000" # Expose on port 3000
|
||||
```
|
||||
|
||||
### External Session Storage
|
||||
|
||||
For multi-instance deployments, consider Redis for sessions:
|
||||
|
||||
```python
|
||||
# config.py
|
||||
SESSION_TYPE = 'redis'
|
||||
SESSION_REDIS = redis.from_url('redis://redis:6379')
|
||||
```
|
||||
|
||||
### Development Mode
|
||||
|
||||
```bash
|
||||
# Use development compose file
|
||||
docker-compose -f docker-compose.dev.yml up
|
||||
```
|
||||
|
||||
## Support
|
||||
|
||||
- GitHub Issues: <repository-url>/issues
|
||||
- Documentation: README.md
|
||||
- Nextcloud Docs: https://docs.nextcloud.com
|
||||
|
||||
## License
|
||||
|
||||
See LICENSE file for details.
|
||||
Reference in New Issue
Block a user