diff --git a/apps/docs/content/docs/3.0-beta/quick-start.mdx b/apps/docs/content/docs/3.0-beta/quick-start.mdx index 6354797..76076ba 100644 --- a/apps/docs/content/docs/3.0-beta/quick-start.mdx +++ b/apps/docs/content/docs/3.0-beta/quick-start.mdx @@ -57,6 +57,8 @@ services: - ENABLE_S3=false - ENCRYPTION_KEY=change-this-key-in-production-min-32-chars # CHANGE THIS KEY FOR SECURITY # - SECURE_SITE=false # Set to true if you are using a reverse proxy + - PALMR_UID=1000 # UID for the container processes (default is 1001) + - PALMR_GID=1000 # GID for the container processes (default is 1001) ports: - "5487:5487" # Web interface - "3333:3333" # API port (OPTIONAL EXPOSED - ONLY IF YOU WANT TO ACCESS THE API DIRECTLY) @@ -93,9 +95,8 @@ services: - ENABLE_S3=false - ENCRYPTION_KEY=change-this-key-in-production-min-32-chars # CHANGE THIS KEY FOR SECURITY # - SECURE_SITE=false # Set to true if you are using a reverse proxy - # Optional: Set custom UID/GID for file permissions - # - PALMR_UID=1000 - # - PALMR_GID=1000 + - PALMR_UID=1000 # UID for the container processes (default is 1001) + - PALMR_GID=1000 # GID for the container processes (default is 1001) ports: - "5487:5487" # Web port - "3333:3333" # API port (OPTIONAL EXPOSED - ONLY IF YOU WANT TO ACCESS THE API DIRECTLY) diff --git a/docker-compose-bind-mount-example.yaml b/docker-compose-bind-mount-example.yaml index afd789f..809084f 100644 --- a/docker-compose-bind-mount-example.yaml +++ b/docker-compose-bind-mount-example.yaml @@ -5,9 +5,8 @@ services: environment: - ENABLE_S3=false - ENCRYPTION_KEY=change-this-key-in-production-min-32-chars # CHANGE THIS KEY FOR SECURITY - # Optional: Set custom UID/GID for file permissions - # - PALMR_UID=1000 - # - PALMR_GID=1000 + - PALMR_UID=1000 # UID for the container processes (default is 1001) + - PALMR_GID=1000 # GID for the container processes (default is 1001) ports: - "5487:5487" # Web port - "3333:3333" # API port (OPTIONAL EXPOSED - ONLY IF YOU WANT TO ACCESS THE API DIRECTLY) diff --git a/docker-compose-minio.yaml b/docker-compose-minio.yaml index 0e00cbe..7002c3e 100644 --- a/docker-compose-minio.yaml +++ b/docker-compose-minio.yaml @@ -12,6 +12,8 @@ services: - S3_REGION=${S3_REGION:-us-east-1} # S3 region (us-east-1 is the default region) but it depends on your s3 server region - S3_BUCKET_NAME=${S3_BUCKET_NAME:-palmr-files} # Bucket name for the S3 storage (here we are using palmr-files as the bucket name to understand that this is the bucket for palmr) - S3_FORCE_PATH_STYLE=true # For MinIO compatibility we have to set this to true + - PALMR_UID=1000 # UID for the container processes (default is 1001) + - PALMR_GID=1000 # GID for the container processes (default is 1001) ports: - "5487:5487" # Web port - "3333:3333" # API port (OPTIONAL EXPOSED - ONLY IF YOU WANT TO ACCESS THE API DIRECTLY) diff --git a/docker-compose-s3.yaml b/docker-compose-s3.yaml index c8d30e9..437b9ab 100644 --- a/docker-compose-s3.yaml +++ b/docker-compose-s3.yaml @@ -12,6 +12,8 @@ services: - S3_REGION=${S3_REGION:-us-east-1} # S3 region (us-east-1 is the default region) but it depends on your s3 server region - S3_BUCKET_NAME=${S3_BUCKET_NAME:-palmr-files} # Bucket name for the S3 storage (here we are using palmr-files as the bucket name to understand that this is the bucket for palmr) - S3_FORCE_PATH_STYLE=false # For S3 compatibility we have to set this to false + - PALMR_UID=1000 # UID for the container processes (default is 1001) + - PALMR_GID=1000 # GID for the container processes (default is 1001) ports: - "5487:5487" # Web port - "3333:3333" # API port (OPTIONAL EXPOSED - ONLY IF YOU WANT TO ACCESS THE API DIRECTLY) diff --git a/docker-compose.yaml b/docker-compose.yaml index 7dd7be2..d246b75 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -8,6 +8,8 @@ services: ports: - "5487:5487" # Web port - "3333:3333" # API port (OPTIONAL EXPOSED - ONLY IF YOU WANT TO ACCESS THE API DIRECTLY) + - PALMR_UID=1000 # UID for the container processes (default is 1001) + - PALMR_GID=1000 # GID for the container processes (default is 1001) volumes: - palmr_data:/app/server # Volume for the application data (changed from /data to /app/server) restart: unless-stopped # Restart the container unless it is stopped diff --git a/infra/SCRIPTS.md b/infra/SCRIPTS.md index 863646d..2e2e039 100644 --- a/infra/SCRIPTS.md +++ b/infra/SCRIPTS.md @@ -20,6 +20,9 @@ make stop # Clean up containers and images make clean + +# Update apps version +make update-version ``` ### Available Commands: @@ -29,5 +32,6 @@ make clean - `make logs` - Show application logs - `make clean` - Clean up containers and images - `make shell` - Access the application container shell +- `make update-version` - Update all apps version in package.json All infrastructure scripts are organized in the `./infra/` directory for better project organization. \ No newline at end of file diff --git a/infra/build-docker.sh b/infra/build-docker.sh index f316602..3a35c5b 100755 --- a/infra/build-docker.sh +++ b/infra/build-docker.sh @@ -1,10 +1,8 @@ #!/bin/bash -# Ask for tag interactively echo "🏷️ Please enter a tag for the build (e.g., v1.0.0, production, beta):" read -p "Tag: " TAG -# Check if tag was provided if [ -z "$TAG" ]; then echo "❌ Error: Tag cannot be empty" echo "Please run the script again and provide a valid tag" @@ -14,10 +12,8 @@ fi echo "🚀 Building Palmr Unified Image for AMD64 and ARM..." echo "📦 Building tags: latest and $TAG" -# Ensure buildx is available and create/use a builder instance docker buildx create --name palmr-builder --use 2>/dev/null || docker buildx use palmr-builder -# Build the unified image for multiple platforms without cache docker buildx build \ --platform linux/amd64,linux/arm64 \ --no-cache \ diff --git a/infra/server-start.sh b/infra/server-start.sh index f40a517..3777d30 100644 --- a/infra/server-start.sh +++ b/infra/server-start.sh @@ -10,12 +10,10 @@ TARGET_GID=${PALMR_GID:-1001} if [ -n "$PALMR_UID" ] || [ -n "$PALMR_GID" ]; then echo "🔧 Runtime UID/GID: $TARGET_UID:$TARGET_GID" - # Update ownership of critical directories to match target UID/GID echo "🔐 Updating file ownership..." chown -R $TARGET_UID:$TARGET_GID /app/palmr-app 2>/dev/null || echo "⚠️ Some ownership changes may have failed" chown -R $TARGET_UID:$TARGET_GID /home/palmr 2>/dev/null || echo "⚠️ Some home directory ownership changes may have failed" - # Update ownership of data directory if it exists if [ -d "/app/server" ]; then chown -R $TARGET_UID:$TARGET_GID /app/server 2>/dev/null || echo "⚠️ Some data directory ownership changes may have failed" fi @@ -23,30 +21,24 @@ if [ -n "$PALMR_UID" ] || [ -n "$PALMR_GID" ]; then echo "✅ UID/GID configuration completed" fi -# Ensure we're in the correct directory cd /app/palmr-app -# Set the database URL export DATABASE_URL="file:/app/server/prisma/palmr.db" echo "📂 Data directory: /app/server" echo "💾 Database: $DATABASE_URL" -# Create all necessary directories echo "📁 Creating data directories..." mkdir -p /app/server/prisma /app/server/uploads /app/server/temp-chunks /app/server/uploads/logo -# Fix ownership of database directory BEFORE database operations if [ "$(id -u)" = "0" ]; then echo "🔐 Ensuring proper ownership before database operations..." chown -R $TARGET_UID:$TARGET_GID /app/server/prisma 2>/dev/null || true fi -# Check if it's a first run (no database file exists) if [ ! -f "/app/server/prisma/palmr.db" ]; then echo "🚀 First run detected - setting up database..." - # Create database with proper schema path - run as target user to avoid permission issues echo "🗄️ Creating database schema..." if [ "$(id -u)" = "0" ]; then su-exec $TARGET_UID:$TARGET_GID npx prisma db push --schema=./prisma/schema.prisma --skip-generate @@ -66,7 +58,6 @@ if [ ! -f "/app/server/prisma/palmr.db" ]; then else echo "♻️ Existing database found" - # Always run migrations to ensure schema is up to date - as target user echo "🔧 Checking for schema updates..." if [ "$(id -u)" = "0" ]; then su-exec $TARGET_UID:$TARGET_GID npx prisma db push --schema=./prisma/schema.prisma --skip-generate @@ -74,60 +65,91 @@ else npx prisma db push --schema=./prisma/schema.prisma --skip-generate fi - # Check if configurations exist - as target user - echo "🔍 Verifying database configurations..." - CONFIG_COUNT=$( + echo "🔍 Checking if new tables need seeding..." + NEEDS_SEEDING=$( if [ "$(id -u)" = "0" ]; then su-exec $TARGET_UID:$TARGET_GID node -e " const { PrismaClient } = require('@prisma/client'); const prisma = new PrismaClient(); - prisma.appConfig.count() - .then(count => { - console.log(count); - process.exit(0); - }) - .catch(() => { - console.log(0); - process.exit(0); - }); - " 2>/dev/null || echo "0" + + async function checkSeedingNeeded() { + try { + const appConfigCount = await prisma.appConfig.count(); + const userCount = await prisma.user.count(); + const authProviderCount = await prisma.authProvider.count(); + + if (appConfigCount === 0 || userCount === 0) { + console.log('true'); + return; + } + + if (authProviderCount === 0) { + console.log('true'); + return; + } + + console.log('false'); + } catch (error) { + console.log('true'); + } finally { + await prisma.\$disconnect(); + } + } + + checkSeedingNeeded(); + " 2>/dev/null || echo "true" else node -e " const { PrismaClient } = require('@prisma/client'); const prisma = new PrismaClient(); - prisma.appConfig.count() - .then(count => { - console.log(count); - process.exit(0); - }) - .catch(() => { - console.log(0); - process.exit(0); - }); - " 2>/dev/null || echo "0" + + async function checkSeedingNeeded() { + try { + const appConfigCount = await prisma.appConfig.count(); + const userCount = await prisma.user.count(); + const authProviderCount = await prisma.authProvider.count(); + + if (appConfigCount === 0 || userCount === 0) { + console.log('true'); + return; + } + + if (authProviderCount === 0) { + console.log('true'); + return; + } + + console.log('false'); + } catch (error) { + console.log('true'); + } finally { + await prisma.\$disconnect(); + } + } + + checkSeedingNeeded(); + " 2>/dev/null || echo "true" fi ) - if [ "$CONFIG_COUNT" -eq "0" ]; then - echo "🌱 No configurations found, running seed..." - # Always run seed from application directory where node_modules is available - as target user + if [ "$NEEDS_SEEDING" = "true" ]; then + echo "🌱 New tables detected or missing data, running seed..." if [ "$(id -u)" = "0" ]; then su-exec $TARGET_UID:$TARGET_GID node ./prisma/seed.js else node ./prisma/seed.js fi + echo "✅ Seeding completed!" else - echo "✅ Found $CONFIG_COUNT configurations" + echo "✅ All tables have data, no seeding needed" fi fi echo "🚀 Starting Palmr server..." -# Drop privileges using su-exec with specific UID/GID if [ "$(id -u)" = "0" ]; then echo "🔽 Dropping privileges to UID:GID $TARGET_UID:$TARGET_GID" exec su-exec $TARGET_UID:$TARGET_GID node dist/server.js else - # We're already running as non-root exec node dist/server.js fi \ No newline at end of file diff --git a/infra/update-versions.sh b/infra/update-versions.sh index 2285077..91508f7 100755 --- a/infra/update-versions.sh +++ b/infra/update-versions.sh @@ -1,8 +1,5 @@ #!/bin/bash -# Script to update version numbers in all package.json files -# Usage: ./update-versions.sh - VERSION=$1 if [ -z "$VERSION" ]; then @@ -14,18 +11,14 @@ fi echo "🔄 Updating version to $VERSION in all package.json files..." -# Function to update version in package.json update_package_json() { local file=$1 local app_name=$2 if [ -f "$file" ]; then - # Use sed to update the version line if [[ "$OSTYPE" == "darwin"* ]]; then - # macOS requires different sed syntax sed -i '' "s/\"version\": \".*\"/\"version\": \"$VERSION\"/" "$file" else - # Linux sed syntax sed -i "s/\"version\": \".*\"/\"version\": \"$VERSION\"/" "$file" fi @@ -35,7 +28,6 @@ update_package_json() { fi } -# Update all three package.json files update_package_json "apps/web/package.json" "Web App" update_package_json "apps/docs/package.json" "Documentation" update_package_json "apps/server/package.json" "API Server"