diff --git a/.env.example b/.env.example index 7636892..3a1e0b0 100644 --- a/.env.example +++ b/.env.example @@ -13,11 +13,16 @@ ADMIN_URL=http://localhost:3005 FRONTEND_URL=http://localhost:3005 BACKEND_URL=http://localhost:3001 -# Database Configuration (SQLite for development) -DATABASE_CLIENT=sqlite3 -DATABASE_PATH=./data/photo_sharing.db +# Database Configuration (PostgreSQL for development) +DATABASE_CLIENT=pg +DB_HOST=db +DB_PORT=5432 +DB_NAME=picpeak +DB_USER=picpeak +DB_PASSWORD=picpeak -# Email Configuration (Mailhog for development) +# Email Configuration +# For development with docker-compose.dev.yml: # Access Mailhog UI at: http://localhost:8025 SMTP_HOST=mailhog SMTP_PORT=1025 @@ -26,6 +31,14 @@ SMTP_USER= SMTP_PASS= EMAIL_FROM=noreply@localhost +# For development without Docker, use real SMTP: +# SMTP_HOST=smtp.gmail.com +# SMTP_PORT=587 +# SMTP_SECURE=false +# SMTP_USER=your-email@gmail.com +# SMTP_PASS=your-app-password +# EMAIL_FROM=PicPeak Dev + # Backend Port Configuration PORT=3001 @@ -40,8 +53,13 @@ PORT=3001 NODE_ENV=development LOG_LEVEL=debug +# Storage Settings (optional) +DEFAULT_EXPIRATION_DAYS=30 +WARNING_DAYS_BEFORE_EXPIRY=7 + # Admin Setup Notes: -# 1. Run 'npm run migrate' in backend folder -# 2. Admin credentials will be auto-generated -# 3. Check ADMIN_CREDENTIALS.txt for login details -# 4. Change password on first login (required) \ No newline at end of file +# 1. Run 'docker-compose -f docker-compose.dev.yml up -d' +# 2. Run 'docker-compose -f docker-compose.dev.yml exec backend npm run migrate' +# 3. Admin credentials will be auto-generated +# 4. Check backend/ADMIN_CREDENTIALS.txt for login details +# 5. Change password on first login (required) \ No newline at end of file diff --git a/.env.production.example b/.env.production.example index 08246b3..f776a6b 100644 --- a/.env.production.example +++ b/.env.production.example @@ -20,7 +20,7 @@ ADMIN_URL=https://your-domain.com # PostgreSQL Configuration (Recommended for production) DATABASE_CLIENT=pg -DB_HOST=postgres # or your database host +DB_HOST=db # Use 'db' for Docker Compose, or external host DB_PORT=5432 DB_NAME=picpeak DB_USER=picpeak @@ -61,7 +61,7 @@ EMAIL_FROM=PicPeak # Primary config via Admin UI > Settings > Analytics # UMAMI_URL=https://analytics.your-domain.com # UMAMI_WEBSITE_ID=your-website-id -# UMAMI_HASH_SALT=your-hash-salt +# UMAMI_HASH_SALT=your-hash-salt # Required if using Umami # Frontend Analytics (Optional - Fallback values) # VITE_UMAMI_URL=https://analytics.your-domain.com @@ -76,6 +76,13 @@ NODE_ENV=production PORT=3001 LOG_LEVEL=info +# Backend URL (if different from frontend) +# BACKEND_URL=https://api.your-domain.com + +# Storage Settings +DEFAULT_EXPIRATION_DAYS=30 +WARNING_DAYS_BEFORE_EXPIRY=7 + # Security Settings (Defaults are secure) BCRYPT_ROUNDS=12 SESSION_TIMEOUT_MINUTES=60 diff --git a/DEPLOYMENT_GUIDE.md b/DEPLOYMENT_GUIDE.md index 091092b..4db1c94 100644 --- a/DEPLOYMENT_GUIDE.md +++ b/DEPLOYMENT_GUIDE.md @@ -32,6 +32,12 @@ This comprehensive guide covers all deployment methods for PicPeak, including Do - **PM2 method**: Node.js 18+, PostgreSQL 14+ - **Manual method**: Node.js 18+, PostgreSQL 14+, nginx (optional) +### Development Setup +For local development, use `docker-compose.dev.yml` which includes Mailhog for email testing: +```bash +docker-compose -f docker-compose.dev.yml up -d +``` + ## 🔐 Security Requirements ### Critical: JWT Secret Setup @@ -127,6 +133,9 @@ EMAIL_FROM=PicPeak NODE_ENV=production PORT=3001 LOG_LEVEL=info + +# Backend URL (if different from frontend) +# BACKEND_URL=https://api.your-domain.com ``` #### Step 2: Docker Volume Permissions @@ -479,6 +488,7 @@ app.listen(80); | `EMAIL_FROM` | From address | `PicPeak ` | | `FRONTEND_URL` | Frontend URL | `https://your-domain.com` | | `BACKEND_URL` | Backend URL | `https://your-domain.com` | +| `ADMIN_URL` | Admin panel URL | `https://your-domain.com` | ### Optional Configuration diff --git a/README.md b/README.md index 120be1a..450777c 100644 --- a/README.md +++ b/README.md @@ -182,8 +182,9 @@ We're constantly improving PicPeak and welcome contributions from our community! | **Backup & Restore** | Comprehensive backup system with S3/MinIO support, automated scheduling, and safe restore functionality | High | ✅ Implemented | | **Gallery Templates** | Additional gallery layouts and themes (masonry, slideshow, story-style) for different event types | Medium | 🔄 Open | | **Face Recognition** | AI-powered face detection to help guests find their photos and create automatic person-based albums | Low | 🔄 Open | -| **Gallery Feedback** | Allow guests to like, rate, and comment on photos with admin notifications and moderation | Medium | 🔄 Open | +| **Gallery Feedback** | Allow guests to like, rate, and comment on photos with admin notifications and moderation | Medium | ✅ Implemented (not tested) | | **Video Support** | Upload and display videos alongside photos in galleries with streaming support | Low | 🔄 Open | +| **Multiple Administrators** | Support for multiple admin accounts with role-based permissions and activity tracking | Low | 📋 Planned | **Status Legend:** ✅ Implemented | 🚧 In Progress | 🔄 Open | 📋 Planned diff --git a/backend/.env.example b/backend/.env.example index 285e541..b9ca615 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -12,6 +12,7 @@ JWT_SECRET=your-very-secure-jwt-secret-at-least-32-characters-long-example123456 # URLs (adjust for your domain) ADMIN_URL=https://photos.example.com FRONTEND_URL=https://photos.example.com +BACKEND_URL=https://photos.example.com # Or https://api.photos.example.com if separate # Database Configuration DATABASE_CLIENT=pg diff --git a/backend/wedding-photos.db b/backend/wedding-photos.db deleted file mode 100644 index e69de29..0000000 diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..68d5478 --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,100 @@ +# docker-compose.dev.yml - Development configuration with Mailhog +version: '3.8' + +services: + # PostgreSQL Database + db: + image: postgres:15-alpine + container_name: picpeak-postgres-dev + environment: + POSTGRES_DB: ${DB_NAME:-picpeak} + POSTGRES_USER: ${DB_USER:-picpeak} + POSTGRES_PASSWORD: ${DB_PASSWORD:-picpeak} + volumes: + - postgres_data_dev:/var/lib/postgresql/data + ports: + - "5432:5432" # Expose for local development tools + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-picpeak}"] + interval: 10s + timeout: 5s + retries: 5 + + # Backend API + backend: + build: ./backend + container_name: picpeak-backend-dev + depends_on: + db: + condition: service_healthy + environment: + NODE_ENV: development + PORT: 3001 + DATABASE_CLIENT: pg + DB_HOST: db + DB_PORT: 5432 + DB_NAME: ${DB_NAME:-picpeak} + DB_USER: ${DB_USER:-picpeak} + DB_PASSWORD: ${DB_PASSWORD:-picpeak} + JWT_SECRET: ${JWT_SECRET:-dev-secret-DO-NOT-USE-IN-PRODUCTION} + ADMIN_URL: ${ADMIN_URL:-http://localhost:3005} + FRONTEND_URL: ${FRONTEND_URL:-http://localhost:3005} + BACKEND_URL: ${BACKEND_URL:-http://localhost:3001} + # Email via Mailhog + SMTP_HOST: mailhog + SMTP_PORT: 1025 + SMTP_SECURE: "false" + SMTP_USER: "" + SMTP_PASS: "" + EMAIL_FROM: ${EMAIL_FROM:-noreply@localhost} + volumes: + - ./backend:/app + - /app/node_modules # Prevent node_modules from being overwritten + - ./storage:/app/storage + - ./data:/app/data + ports: + - "3001:3001" + restart: unless-stopped + command: npm run dev + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:3001/api/health"] + interval: 30s + timeout: 10s + retries: 3 + + # Frontend + frontend: + build: + context: ./frontend + dockerfile: Dockerfile.dev + container_name: picpeak-frontend-dev + depends_on: + - backend + environment: + - VITE_API_URL=${VITE_API_URL:-http://localhost:3001/api} + - VITE_UMAMI_URL=${VITE_UMAMI_URL} + - VITE_UMAMI_WEBSITE_ID=${VITE_UMAMI_WEBSITE_ID} + volumes: + - ./frontend:/app + - /app/node_modules # Prevent node_modules from being overwritten + ports: + - "3005:3005" + restart: unless-stopped + command: npm run dev -- --host 0.0.0.0 --port 3005 + + # Mailhog - Email testing for development + mailhog: + image: mailhog/mailhog:latest + container_name: picpeak-mailhog + ports: + - "1025:1025" # SMTP server + - "8025:8025" # Web UI + restart: unless-stopped + +volumes: + postgres_data_dev: + +networks: + default: + name: picpeak-dev-network \ No newline at end of file diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index d8cd1a8..f5beeec 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -12,10 +12,11 @@ services: - db environment: - NODE_ENV=production - - PORT=3000 + - PORT=3001 - JWT_SECRET=${JWT_SECRET} - ADMIN_URL=${ADMIN_URL} - FRONTEND_URL=${FRONTEND_URL} + - BACKEND_URL=${BACKEND_URL} # Database - DATABASE_CLIENT=pg - DB_HOST=db diff --git a/docker-compose.yml b/docker-compose.yml index 0ac1a65..062c993 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: '3.8' services: # PostgreSQL Database - postgres: + db: image: postgres:15-alpine container_name: picpeak-postgres environment: @@ -23,12 +23,13 @@ services: build: ./backend container_name: picpeak-backend depends_on: - postgres: + db: condition: service_healthy environment: NODE_ENV: production + PORT: 3001 DATABASE_CLIENT: pg - DB_HOST: postgres + DB_HOST: db DB_PORT: 5432 DB_NAME: ${DB_NAME:-picpeak} DB_USER: ${DB_USER:-picpeak} @@ -40,7 +41,7 @@ services: - ./data:/app/data restart: unless-stopped healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:3000/health"] + test: ["CMD", "curl", "-f", "http://localhost:3001/api/health"] interval: 30s timeout: 10s retries: 3 diff --git a/docker/postgres-init/01-create-umami-db.sql b/docker/postgres-init/01-create-umami-db.sql deleted file mode 100644 index d62d32b..0000000 --- a/docker/postgres-init/01-create-umami-db.sql +++ /dev/null @@ -1,8 +0,0 @@ --- Create umami database if it doesn't exist --- This runs as the postgres superuser during initialization - -SELECT 'CREATE DATABASE umami' -WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'umami')\gexec - --- Grant all privileges on umami database to the application user -GRANT ALL PRIVILEGES ON DATABASE umami TO "${POSTGRES_USER}"; \ No newline at end of file diff --git a/frontend/Dockerfile.dev b/frontend/Dockerfile.dev index b58da54..59c443f 100644 --- a/frontend/Dockerfile.dev +++ b/frontend/Dockerfile.dev @@ -1,45 +1,19 @@ -# Build stage -FROM node:18-alpine AS builder +# Dockerfile.dev - Development configuration for frontend +FROM node:18-alpine WORKDIR /app -# Accept build arguments -ARG VITE_API_URL -ARG VITE_UMAMI_URL -ARG VITE_UMAMI_WEBSITE_ID - -# Set environment variables for build -ENV VITE_API_URL=$VITE_API_URL -ENV VITE_UMAMI_URL=$VITE_UMAMI_URL -ENV VITE_UMAMI_WEBSITE_ID=$VITE_UMAMI_WEBSITE_ID - # Copy package files COPY package*.json ./ # Install dependencies RUN npm ci --legacy-peer-deps -# Copy source files +# Copy source code COPY . . -# Build the application -RUN npm run build +# Expose the development server port +EXPOSE 3005 -# Production stage -FROM nginx:alpine - -# Copy custom nginx config -COPY nginx.dev.conf /etc/nginx/conf.d/default.conf - -# Copy built application from builder stage -COPY --from=builder /app/dist /usr/share/nginx/html - -# Health check -HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ - CMD curl -f http://localhost/health || exit 1 - -# Expose port -EXPOSE 80 - -# Start nginx -CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file +# Start development server +CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0", "--port", "3005"] \ No newline at end of file diff --git a/frontend/README.md b/frontend/README.md deleted file mode 100644 index 7959ce4..0000000 --- a/frontend/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# React + TypeScript + Vite - -This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. - -Currently, two official plugins are available: - -- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh - -## Expanding the ESLint configuration - -If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: - -```js -export default tseslint.config([ - globalIgnores(['dist']), - { - files: ['**/*.{ts,tsx}'], - extends: [ - // Other configs... - - // Remove tseslint.configs.recommended and replace with this - ...tseslint.configs.recommendedTypeChecked, - // Alternatively, use this for stricter rules - ...tseslint.configs.strictTypeChecked, - // Optionally, add this for stylistic rules - ...tseslint.configs.stylisticTypeChecked, - - // Other configs... - ], - languageOptions: { - parserOptions: { - project: ['./tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: import.meta.dirname, - }, - // other options... - }, - }, -]) -``` - -You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: - -```js -// eslint.config.js -import reactX from 'eslint-plugin-react-x' -import reactDom from 'eslint-plugin-react-dom' - -export default tseslint.config([ - globalIgnores(['dist']), - { - files: ['**/*.{ts,tsx}'], - extends: [ - // Other configs... - // Enable lint rules for React - reactX.configs['recommended-typescript'], - // Enable lint rules for React DOM - reactDom.configs.recommended, - ], - languageOptions: { - parserOptions: { - project: ['./tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: import.meta.dirname, - }, - // other options... - }, - }, -]) -```