Files
nextsnap/DEPLOYMENT.md
kamaji cad4118f72 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>
2026-02-07 04:53:13 -06:00

6.3 KiB

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

git clone <repository-url>
cd nextsnap

2. Configure Environment Variables

cp .env.example .env

Edit .env and set your values:

# 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

docker-compose up -d

The application will be available at http://localhost:8000

4. Verify Deployment

# 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

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:

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

    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

    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

    docker-compose logs -f --tail=100 nextsnap
    

Backup and Restore

Backup Session Data

# 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

# 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

git pull origin main

Rebuild and Restart

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

# 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:
    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

# 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:

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:

services:
  nextsnap:
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 256M

Monitoring

Health Checks

# Built-in health endpoint
curl http://localhost:8000/api/health

# Container health status
docker inspect --format='{{.State.Health.Status}}' nextsnap

Logs

# 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

# docker-compose.yml
ports:
  - "3000:8000"  # Expose on port 3000

External Session Storage

For multi-instance deployments, consider Redis for sessions:

# config.py
SESSION_TYPE = 'redis'
SESSION_REDIS = redis.from_url('redis://redis:6379')

Development Mode

# Use development compose file
docker-compose -f docker-compose.dev.yml up

Support

License

See LICENSE file for details.