Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 840b8870ec | |||
| ad495a92c4 | |||
| b428543452 | |||
| 6492cb9ec8 | |||
| 0e0a0b91d1 | |||
| f8fb1c3f4b |
@@ -1,40 +0,0 @@
|
||||
# Development Environment with PostgreSQL
|
||||
# Copy this to .env for PostgreSQL development with Docker Compose
|
||||
|
||||
# JWT Secret (development only)
|
||||
JWT_SECRET=dev-secret-key-do-not-use-in-production
|
||||
|
||||
# Database Configuration (PostgreSQL)
|
||||
DATABASE_CLIENT=pg
|
||||
DB_USER=picpeak_dev
|
||||
DB_PASSWORD=dev_password_123
|
||||
DB_NAME=picpeak_dev
|
||||
|
||||
# Redis Configuration
|
||||
REDIS_PASSWORD=dev_redis_pass
|
||||
|
||||
# Admin Account (initial setup)
|
||||
ADMIN_USERNAME=admin
|
||||
ADMIN_EMAIL=admin@localhost
|
||||
|
||||
# Email Configuration (Disabled for development)
|
||||
# To enable email, configure a real SMTP server
|
||||
SMTP_HOST=
|
||||
SMTP_PORT=
|
||||
SMTP_SECURE=false
|
||||
SMTP_USER=
|
||||
SMTP_PASS=
|
||||
EMAIL_FROM=noreply@picpeak.local
|
||||
|
||||
# Application URLs
|
||||
FRONTEND_URL=http://localhost:3000
|
||||
ADMIN_URL=http://localhost:3001
|
||||
VITE_API_URL=http://localhost:3001/api
|
||||
|
||||
# Timezone
|
||||
TZ=UTC
|
||||
|
||||
# Analytics (Optional - leave empty for development)
|
||||
VITE_UMAMI_URL=
|
||||
VITE_UMAMI_WEBSITE_ID=
|
||||
VITE_UMAMI_SHARE_URL=
|
||||
+38
-53
@@ -1,65 +1,50 @@
|
||||
# PicPeak Development Environment Configuration
|
||||
# Copy this file to .env for local development
|
||||
# PicPeak Environment Configuration
|
||||
# Copy this file to .env and update with your values
|
||||
|
||||
# SECURITY WARNING: This configuration is for development only!
|
||||
# For production, use .env.production.example
|
||||
# Environment
|
||||
NODE_ENV=production
|
||||
|
||||
# JWT Secret (Change in production!)
|
||||
# Generate secure secret with: openssl rand -base64 32
|
||||
JWT_SECRET=dev-secret-DO-NOT-USE-IN-PRODUCTION
|
||||
# JWT Secret (generate with: openssl rand -base64 64)
|
||||
JWT_SECRET=your_very_long_random_jwt_secret_here
|
||||
|
||||
# Application URLs (Docker Compose development setup)
|
||||
ADMIN_URL=http://localhost:3005
|
||||
FRONTEND_URL=http://localhost:3005
|
||||
BACKEND_URL=http://localhost:3001
|
||||
|
||||
# Database Configuration (PostgreSQL for development)
|
||||
# Database Configuration (PostgreSQL)
|
||||
DATABASE_CLIENT=pg
|
||||
DB_HOST=db
|
||||
DB_PORT=5432
|
||||
DB_NAME=picpeak
|
||||
DB_USER=picpeak
|
||||
DB_PASSWORD=picpeak
|
||||
DB_PASSWORD=your_secure_postgres_password_here
|
||||
DB_NAME=picpeak_prod
|
||||
|
||||
# Redis Configuration
|
||||
REDIS_PASSWORD=your_secure_redis_password_here
|
||||
|
||||
# Admin Account (initial setup)
|
||||
ADMIN_USERNAME=admin
|
||||
ADMIN_EMAIL=admin@yourdomain.com
|
||||
|
||||
# Email Configuration
|
||||
# For development with docker-compose.dev.yml:
|
||||
# Access Mailhog UI at: http://localhost:8025
|
||||
SMTP_HOST=mailhog
|
||||
SMTP_PORT=1025
|
||||
# For Gmail: use app-specific password
|
||||
# For SendGrid: SMTP_USER=apikey, SMTP_PASS=your-api-key
|
||||
SMTP_HOST=smtp.gmail.com
|
||||
SMTP_PORT=587
|
||||
SMTP_SECURE=false
|
||||
SMTP_USER=
|
||||
SMTP_PASS=
|
||||
EMAIL_FROM=noreply@localhost
|
||||
SMTP_USER=your-email@gmail.com
|
||||
SMTP_PASS=your-app-specific-password
|
||||
EMAIL_FROM=noreply@yourdomain.com
|
||||
|
||||
# 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 <your-email@gmail.com>
|
||||
# Application URLs
|
||||
FRONTEND_URL=https://yourdomain.com
|
||||
ADMIN_URL=https://yourdomain.com:3001
|
||||
VITE_API_URL=https://yourdomain.com:3001/api
|
||||
|
||||
# Backend Port Configuration
|
||||
PORT=3001
|
||||
# Port Configuration (optional)
|
||||
# BACKEND_PORT=3001
|
||||
# FRONTEND_PORT=3000
|
||||
# DB_PORT=5432
|
||||
# REDIS_PORT=6379
|
||||
|
||||
# Optional: Umami Analytics Backend Config
|
||||
# NOTE: Primary configuration through Admin UI > Settings > Analytics
|
||||
# These are fallback values for server-side tracking
|
||||
# UMAMI_URL=https://analytics.example.com
|
||||
# UMAMI_WEBSITE_ID=your-website-id
|
||||
# UMAMI_HASH_SALT=your-hash-salt
|
||||
# Timezone
|
||||
TZ=UTC
|
||||
|
||||
# Development Features
|
||||
NODE_ENV=development
|
||||
LOG_LEVEL=debug
|
||||
|
||||
# Storage Settings (optional)
|
||||
DEFAULT_EXPIRATION_DAYS=30
|
||||
WARNING_DAYS_BEFORE_EXPIRY=7
|
||||
|
||||
# Admin Setup Notes:
|
||||
# 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)
|
||||
# Analytics (Optional - Umami)
|
||||
VITE_UMAMI_URL=
|
||||
VITE_UMAMI_WEBSITE_ID=
|
||||
VITE_UMAMI_SHARE_URL=
|
||||
@@ -1,107 +0,0 @@
|
||||
# PicPeak Production Configuration
|
||||
# Copy this file to .env and update with your production values
|
||||
|
||||
# ============================================
|
||||
# CRITICAL SECURITY - MUST CHANGE ALL VALUES!
|
||||
# ============================================
|
||||
|
||||
# JWT Secret - REQUIRED (minimum 32 characters)
|
||||
# Generate with: openssl rand -base64 32
|
||||
JWT_SECRET=CHANGE-THIS-PRODUCTION-SECRET-USE-OPENSSL-COMMAND
|
||||
|
||||
# Application URLs - REQUIRED (your actual domain)
|
||||
FRONTEND_URL=https://your-domain.com
|
||||
BACKEND_URL=https://your-domain.com
|
||||
ADMIN_URL=https://your-domain.com
|
||||
|
||||
# ============================================
|
||||
# DATABASE CONFIGURATION - REQUIRED
|
||||
# ============================================
|
||||
|
||||
# PostgreSQL Configuration (Recommended for production)
|
||||
DATABASE_CLIENT=pg
|
||||
DB_HOST=db # Use 'db' for Docker Compose, or external host
|
||||
DB_PORT=5432
|
||||
DB_NAME=picpeak
|
||||
DB_USER=picpeak
|
||||
DB_PASSWORD=CHANGE-THIS-SECURE-DATABASE-PASSWORD
|
||||
|
||||
# ============================================
|
||||
# EMAIL CONFIGURATION - REQUIRED
|
||||
# ============================================
|
||||
|
||||
# Example: Gmail with App Password
|
||||
# SMTP_HOST=smtp.gmail.com
|
||||
# SMTP_PORT=587
|
||||
# SMTP_SECURE=false
|
||||
# SMTP_USER=your-email@gmail.com
|
||||
# SMTP_PASS=your-16-char-app-password
|
||||
# EMAIL_FROM=Your Name <your-email@gmail.com>
|
||||
|
||||
# Example: SendGrid
|
||||
SMTP_HOST=smtp.sendgrid.net
|
||||
SMTP_PORT=587
|
||||
SMTP_SECURE=false
|
||||
SMTP_USER=apikey
|
||||
SMTP_PASS=YOUR-SENDGRID-API-KEY
|
||||
EMAIL_FROM=PicPeak <noreply@your-domain.com>
|
||||
|
||||
# ============================================
|
||||
# ADMIN SETUP - AUTO-GENERATED
|
||||
# ============================================
|
||||
# NOTE: Admin credentials are automatically generated during setup
|
||||
# DO NOT set ADMIN_EMAIL or ADMIN_PASSWORD anymore!
|
||||
# Run 'npm run migrate' and check ADMIN_CREDENTIALS.txt
|
||||
|
||||
# ============================================
|
||||
# OPTIONAL CONFIGURATION
|
||||
# ============================================
|
||||
|
||||
# Umami Analytics (Optional - Fallback values)
|
||||
# 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 # Required if using Umami
|
||||
|
||||
# Frontend Analytics (Optional - Fallback values)
|
||||
# VITE_UMAMI_URL=https://analytics.your-domain.com
|
||||
# VITE_UMAMI_WEBSITE_ID=your-website-id
|
||||
# VITE_UMAMI_SHARE_URL=https://analytics.your-domain.com/share/xyz/gallery
|
||||
|
||||
# ============================================
|
||||
# PERFORMANCE & SECURITY TUNING
|
||||
# ============================================
|
||||
|
||||
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
|
||||
RATE_LIMIT_WINDOW_MS=900000 # 15 minutes
|
||||
RATE_LIMIT_MAX_REQUESTS=100 # per window
|
||||
|
||||
# Connection Pool (Adjust based on load)
|
||||
DB_POOL_MIN=5
|
||||
DB_POOL_MAX=25
|
||||
|
||||
# ============================================
|
||||
# DOCKER COMPOSE SPECIFIC
|
||||
# ============================================
|
||||
|
||||
# Traefik Configuration (if using Traefik)
|
||||
DOMAIN=your-domain.com
|
||||
LETSENCRYPT_EMAIL=admin@your-domain.com
|
||||
|
||||
# Volume Paths (Docker)
|
||||
STORAGE_PATH=/app/storage
|
||||
EVENTS_PATH=/app/storage/events
|
||||
ARCHIVE_PATH=/app/storage/events/archived
|
||||
+325
-642
File diff suppressed because it is too large
Load Diff
@@ -18,9 +18,13 @@ exports.up = async function(knex) {
|
||||
const generatedPassword = generateReadablePassword();
|
||||
const passwordHash = await bcrypt.hash(generatedPassword, 12); // Increased rounds for better security
|
||||
|
||||
// Get admin credentials from environment or use defaults
|
||||
const adminUsername = process.env.ADMIN_USERNAME || 'admin';
|
||||
const adminEmail = process.env.ADMIN_EMAIL || 'admin@example.com';
|
||||
|
||||
await knex('admin_users').insert({
|
||||
username: 'admin',
|
||||
email: 'admin@example.com',
|
||||
username: adminUsername,
|
||||
email: adminEmail,
|
||||
password_hash: passwordHash,
|
||||
created_at: new Date()
|
||||
});
|
||||
@@ -36,7 +40,7 @@ PicPeak Admin Credentials
|
||||
|
||||
Your admin account has been created with these credentials:
|
||||
|
||||
Username: admin
|
||||
Email: ${adminEmail}
|
||||
Password: ${generatedPassword}
|
||||
|
||||
IMPORTANT SECURITY NOTES:
|
||||
@@ -47,6 +51,8 @@ IMPORTANT SECURITY NOTES:
|
||||
|
||||
Login URL: ${process.env.ADMIN_URL || 'http://localhost:3001'}/admin
|
||||
|
||||
Login with the email address shown above
|
||||
|
||||
Generated on: ${new Date().toISOString()}
|
||||
========================================
|
||||
`;
|
||||
@@ -65,7 +71,7 @@ Generated on: ${new Date().toISOString()}
|
||||
console.log('\n========================================');
|
||||
console.log('✅ Admin user created successfully!');
|
||||
console.log('========================================');
|
||||
console.log('Username: admin');
|
||||
console.log(`Email: ${adminEmail}`);
|
||||
console.log(`Password: ${generatedPassword}`);
|
||||
console.log('\n⚠️ IMPORTANT:');
|
||||
console.log('1. Save these credentials securely');
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "picpeak-backend",
|
||||
"version": "1.0.96",
|
||||
"version": "1.0.99",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "picpeak-backend",
|
||||
"version": "1.0.96",
|
||||
"version": "1.0.99",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.850.0",
|
||||
"@aws-sdk/lib-storage": "^3.850.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "picpeak-backend",
|
||||
"version": "1.0.96",
|
||||
"version": "1.0.99",
|
||||
"description": "Backend for PicPeak event photo sharing platform",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -20,6 +20,12 @@ const ATTEMPT_WINDOW = 15 * 60 * 1000; // 15 minutes window for counting attempt
|
||||
*/
|
||||
async function trackFailedAttempt(identifier, ipAddress, userAgent) {
|
||||
try {
|
||||
// Check if table exists first
|
||||
const tableExists = await db.schema.hasTable('login_attempts');
|
||||
if (!tableExists) {
|
||||
return;
|
||||
}
|
||||
|
||||
await db('login_attempts').insert({
|
||||
identifier,
|
||||
ip_address: ipAddress,
|
||||
@@ -48,6 +54,12 @@ async function trackFailedAttempt(identifier, ipAddress, userAgent) {
|
||||
*/
|
||||
async function trackSuccessfulLogin(identifier, ipAddress, userAgent) {
|
||||
try {
|
||||
// Check if table exists first
|
||||
const tableExists = await db.schema.hasTable('login_attempts');
|
||||
if (!tableExists) {
|
||||
return;
|
||||
}
|
||||
|
||||
await db('login_attempts').insert({
|
||||
identifier,
|
||||
ip_address: ipAddress,
|
||||
@@ -75,6 +87,12 @@ async function trackSuccessfulLogin(identifier, ipAddress, userAgent) {
|
||||
*/
|
||||
async function checkAccountLockout(identifier) {
|
||||
try {
|
||||
// Check if table exists first
|
||||
const tableExists = await db.schema.hasTable('login_attempts');
|
||||
if (!tableExists) {
|
||||
return { isLocked: false };
|
||||
}
|
||||
|
||||
const recentWindow = new Date(Date.now() - ATTEMPT_WINDOW);
|
||||
|
||||
// Get recent failed attempts
|
||||
@@ -114,6 +132,12 @@ async function checkAccountLockout(identifier) {
|
||||
*/
|
||||
async function checkSuspiciousActivity(identifier, ipAddress) {
|
||||
try {
|
||||
// Check if table exists first
|
||||
const tableExists = await db.schema.hasTable('login_attempts');
|
||||
if (!tableExists) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for rapid attempts from different IPs
|
||||
const recentWindow = new Date(Date.now() - 5 * 60 * 1000); // 5 minutes
|
||||
|
||||
@@ -153,6 +177,13 @@ function getGenericAuthError() {
|
||||
*/
|
||||
async function cleanupOldAttempts() {
|
||||
try {
|
||||
// Check if table exists first
|
||||
const tableExists = await db.schema.hasTable('login_attempts');
|
||||
if (!tableExists) {
|
||||
// Table doesn't exist, skip cleanup
|
||||
return;
|
||||
}
|
||||
|
||||
const cutoffDate = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000); // 7 days
|
||||
|
||||
const deleted = await db('login_attempts')
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
backend:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: Dockerfile
|
||||
container_name: picpeak-backend-dev
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
- PORT=3001
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- ADMIN_USERNAME=${ADMIN_USERNAME:-admin}
|
||||
- ADMIN_EMAIL=${ADMIN_EMAIL:-admin@example.com}
|
||||
- DATABASE_CLIENT=pg
|
||||
- DATABASE_URL=postgresql://${DB_USER}:${DB_PASSWORD}@postgres:5432/${DB_NAME}
|
||||
- DB_TYPE=postgresql
|
||||
- DB_HOST=postgres
|
||||
- DB_PORT=5432
|
||||
- DB_USER=${DB_USER}
|
||||
- DB_PASSWORD=${DB_PASSWORD}
|
||||
- DB_NAME=${DB_NAME}
|
||||
- SMTP_HOST=${SMTP_HOST}
|
||||
- SMTP_PORT=${SMTP_PORT}
|
||||
- SMTP_SECURE=${SMTP_SECURE:-false}
|
||||
- SMTP_USER=${SMTP_USER}
|
||||
- SMTP_PASS=${SMTP_PASS}
|
||||
- EMAIL_FROM=${EMAIL_FROM:-noreply@picpeak.local}
|
||||
- FRONTEND_URL=${FRONTEND_URL:-http://localhost:3000}
|
||||
- ADMIN_URL=${ADMIN_URL:-http://localhost:3001}
|
||||
- TZ=${TZ:-UTC}
|
||||
volumes:
|
||||
- ./events:/app/events
|
||||
- ./data:/app/data
|
||||
- ./logs:/app/logs
|
||||
- ./backup:/backup
|
||||
- ./storage:/app/storage
|
||||
ports:
|
||||
- "3001:3001"
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3001/api/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
networks:
|
||||
- picpeak-network
|
||||
|
||||
postgres:
|
||||
image: postgres:15-alpine
|
||||
container_name: picpeak-postgres-dev
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- POSTGRES_USER=${DB_USER}
|
||||
- POSTGRES_PASSWORD=${DB_PASSWORD}
|
||||
- POSTGRES_DB=${DB_NAME}
|
||||
- PGDATA=/var/lib/postgresql/data/pgdata
|
||||
- TZ=${TZ:-UTC}
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
ports:
|
||||
- "5432:5432"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 20s
|
||||
networks:
|
||||
- picpeak-network
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: picpeak-redis-dev
|
||||
restart: unless-stopped
|
||||
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD:-picpeak_redis_pass}
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
ports:
|
||||
- "6379:6379"
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
networks:
|
||||
- picpeak-network
|
||||
|
||||
frontend:
|
||||
build:
|
||||
context: ./frontend
|
||||
dockerfile: Dockerfile.dev
|
||||
args:
|
||||
- VITE_API_URL=${VITE_API_URL:-http://localhost:3001/api}
|
||||
- VITE_UMAMI_URL=${VITE_UMAMI_URL:-}
|
||||
- VITE_UMAMI_WEBSITE_ID=${VITE_UMAMI_WEBSITE_ID:-}
|
||||
- VITE_UMAMI_SHARE_URL=${VITE_UMAMI_SHARE_URL:-}
|
||||
container_name: picpeak-frontend-dev
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
volumes:
|
||||
- ./frontend:/app
|
||||
- /app/node_modules
|
||||
ports:
|
||||
- "3000:3005"
|
||||
depends_on:
|
||||
- backend
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3005"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
networks:
|
||||
- picpeak-network
|
||||
|
||||
volumes:
|
||||
postgres-data:
|
||||
driver: local
|
||||
redis-data:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
picpeak-network:
|
||||
driver: bridge
|
||||
+91
-91
@@ -1,125 +1,125 @@
|
||||
# docker-compose.yml - Production configuration
|
||||
#
|
||||
# For development, use: docker-compose -f docker-compose.dev.yml up -d
|
||||
# For local customizations, create docker-compose.override.yml (see docker-compose.override.yml.example)
|
||||
#
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
backend:
|
||||
image: picpeak-backend:latest
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: Dockerfile
|
||||
container_name: picpeak-backend
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- db
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- NODE_ENV=${NODE_ENV:-production}
|
||||
- PORT=3001
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- ADMIN_URL=${ADMIN_URL}
|
||||
- FRONTEND_URL=${FRONTEND_URL}
|
||||
- BACKEND_URL=${BACKEND_URL}
|
||||
# Database
|
||||
- ADMIN_USERNAME=${ADMIN_USERNAME:-admin}
|
||||
- ADMIN_EMAIL=${ADMIN_EMAIL:-admin@example.com}
|
||||
- DATABASE_CLIENT=pg
|
||||
- DB_HOST=db
|
||||
- DATABASE_URL=postgresql://${DB_USER}:${DB_PASSWORD}@postgres:5432/${DB_NAME}
|
||||
- DB_TYPE=postgresql
|
||||
- DB_HOST=postgres
|
||||
- DB_PORT=5432
|
||||
- DB_USER=${DB_USER:-picpeak}
|
||||
- DB_USER=${DB_USER}
|
||||
- DB_PASSWORD=${DB_PASSWORD}
|
||||
- DB_NAME=${DB_NAME:-picpeak}
|
||||
# Email
|
||||
- DB_NAME=${DB_NAME}
|
||||
- SMTP_HOST=${SMTP_HOST}
|
||||
- SMTP_PORT=${SMTP_PORT}
|
||||
- SMTP_SECURE=${SMTP_SECURE}
|
||||
- SMTP_SECURE=${SMTP_SECURE:-false}
|
||||
- SMTP_USER=${SMTP_USER}
|
||||
- SMTP_PASS=${SMTP_PASS}
|
||||
- EMAIL_FROM=${EMAIL_FROM}
|
||||
# Analytics
|
||||
- UMAMI_URL=${UMAMI_URL}
|
||||
- UMAMI_WEBSITE_ID=${UMAMI_WEBSITE_ID}
|
||||
# Storage paths
|
||||
- EMAIL_FROM=${EMAIL_FROM:-noreply@picpeak.local}
|
||||
- FRONTEND_URL=${FRONTEND_URL:-http://localhost:3000}
|
||||
- ADMIN_URL=${ADMIN_URL:-http://localhost:3001}
|
||||
- TZ=${TZ:-UTC}
|
||||
- STORAGE_PATH=/app/storage
|
||||
- EVENTS_PATH=/app/storage/events
|
||||
- ARCHIVE_PATH=/app/storage/events/archived
|
||||
volumes:
|
||||
- ./storage:/app/storage
|
||||
- ./events:/app/events
|
||||
- ./data:/app/data
|
||||
- ./logs:/app/logs
|
||||
- ./backup:/backup
|
||||
- ./storage:/app/storage
|
||||
ports:
|
||||
- "${BACKEND_PORT:-3001}:3001"
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3001/api/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
networks:
|
||||
- picpeak
|
||||
- picpeak-network
|
||||
|
||||
postgres:
|
||||
image: postgres:15-alpine
|
||||
container_name: picpeak-postgres
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- POSTGRES_USER=${DB_USER}
|
||||
- POSTGRES_PASSWORD=${DB_PASSWORD}
|
||||
- POSTGRES_DB=${DB_NAME}
|
||||
- PGDATA=/var/lib/postgresql/data/pgdata
|
||||
- TZ=${TZ:-UTC}
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
ports:
|
||||
- "${DB_PORT:-5432}:5432"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 20s
|
||||
networks:
|
||||
- picpeak-network
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: picpeak-redis
|
||||
restart: unless-stopped
|
||||
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD:-picpeak_redis_pass}
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
ports:
|
||||
- "${REDIS_PORT:-6379}:6379"
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
networks:
|
||||
- picpeak-network
|
||||
|
||||
frontend:
|
||||
image: picpeak-frontend:latest
|
||||
build:
|
||||
context: ./frontend
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
- VITE_API_URL=/api
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- backend
|
||||
networks:
|
||||
- picpeak
|
||||
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
- VITE_API_URL=${VITE_API_URL:-http://localhost:3001/api}
|
||||
- VITE_UMAMI_URL=${VITE_UMAMI_URL:-}
|
||||
- VITE_UMAMI_WEBSITE_ID=${VITE_UMAMI_WEBSITE_ID:-}
|
||||
- VITE_UMAMI_SHARE_URL=${VITE_UMAMI_SHARE_URL:-}
|
||||
container_name: picpeak-frontend
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- NODE_ENV=${NODE_ENV:-production}
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./nginx/sites-enabled:/etc/nginx/sites-enabled
|
||||
- ./certbot/conf:/etc/letsencrypt
|
||||
- ./certbot/www:/var/www/certbot
|
||||
- "${FRONTEND_PORT:-3000}:80"
|
||||
depends_on:
|
||||
- frontend
|
||||
- backend
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:80"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
networks:
|
||||
- picpeak
|
||||
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
|
||||
|
||||
certbot:
|
||||
image: certbot/certbot
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./certbot/conf:/etc/letsencrypt
|
||||
- ./certbot/www:/var/www/certbot
|
||||
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
|
||||
|
||||
db:
|
||||
image: postgres:15-alpine
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- POSTGRES_USER=${DB_USER:-picpeak}
|
||||
- POSTGRES_PASSWORD=${DB_PASSWORD}
|
||||
- POSTGRES_DB=${DB_NAME:-picpeak}
|
||||
# Allow connections from any host with password authentication
|
||||
- POSTGRES_HOST_AUTH_METHOD=scram-sha-256
|
||||
- POSTGRES_INITDB_ARGS=--auth-host=scram-sha-256 --auth-local=trust
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
networks:
|
||||
- picpeak
|
||||
# Allow connections without SSL requirement from Docker network
|
||||
command: postgres -c ssl=off
|
||||
|
||||
umami:
|
||||
image: ghcr.io/umami-software/umami:postgresql-latest
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
DATABASE_URL: postgresql://${DB_USER:-picpeak}:${DB_PASSWORD}@db:5432/umami
|
||||
DATABASE_TYPE: postgresql
|
||||
HASH_SALT: ${UMAMI_HASH_SALT}
|
||||
depends_on:
|
||||
- db
|
||||
networks:
|
||||
- picpeak
|
||||
|
||||
networks:
|
||||
picpeak:
|
||||
driver: bridge
|
||||
- picpeak-network
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
postgres-data:
|
||||
driver: local
|
||||
redis-data:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
picpeak-network:
|
||||
driver: bridge
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "picpeak-frontend",
|
||||
"version": "1.0.96",
|
||||
"version": "1.0.99",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "picpeak-frontend",
|
||||
"version": "1.0.96",
|
||||
"version": "1.0.99",
|
||||
"dependencies": {
|
||||
"@tanstack/react-query": "^5.0.0",
|
||||
"@tiptap/extension-character-count": "^2.26.1",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "picpeak-frontend",
|
||||
"private": true,
|
||||
"version": "1.0.96",
|
||||
"version": "1.0.99",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
Reference in New Issue
Block a user