Files
Goa-gel-fullstack/backend/scripts/docker-entrypoint.sh
Mahi d9de183e51 feat: Runtime configuration and Docker deployment improvements
Frontend:
- Add runtime configuration service for deployment-time API URL injection
- Create docker-entrypoint.sh to generate config.json from environment variables
- Update ApiService, ApprovalService, and DocumentViewer to use RuntimeConfigService
- Add APP_INITIALIZER to load runtime config before app starts

Backend:
- Fix init-blockchain.js to properly quote mnemonic phrases in .env file
- Improve docker-entrypoint.sh with health checks and better error handling

Docker:
- Add API_BASE_URL environment variable to frontend container
- Update docker-compose.yml with clear documentation for remote deployment
- Reorganize .env.example with clear categories (REQUIRED FOR REMOTE, PRODUCTION, AUTO-GENERATED)

Workflow fixes:
- Fix DepartmentApproval interface to match backend schema
- Fix stage transformation for 0-indexed stageOrder
- Fix workflow list to show correct stage count from definition.stages

Cleanup:
- Move development artifacts to .trash directory
- Remove root-level package.json (was only for utility scripts)
- Add .trash/ to .gitignore
2026-02-08 18:45:01 -04:00

206 lines
5.9 KiB
Bash
Executable File

#!/bin/bash
set -e
echo "========================================"
echo " Goa-GEL Backend Initialization"
echo "========================================"
echo ""
# Function to check if this is first boot
is_first_boot() {
if [ ! -f "/app/data/.initialized" ]; then
return 0 # true
else
return 1 # false
fi
}
# Function to check if database has data
db_has_data() {
local count
count=$(PGPASSWORD=$DATABASE_PASSWORD psql -h "$DATABASE_HOST" -U "$DATABASE_USER" -d "$DATABASE_NAME" -tAc "SELECT COUNT(*) FROM users;" 2>/dev/null || echo "0")
if [ "$count" -gt "0" ]; then
return 0 # true - has data
else
return 1 # false - empty
fi
}
# Function to check if migrations table exists
migrations_table_exists() {
local exists
exists=$(PGPASSWORD=$DATABASE_PASSWORD psql -h "$DATABASE_HOST" -U "$DATABASE_USER" -d "$DATABASE_NAME" -tAc "SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'knex_migrations');" 2>/dev/null || echo "f")
if [ "$exists" = "t" ]; then
return 0 # true
else
return 1 # false
fi
}
# Ensure data directory exists
mkdir -p /app/data
# Ensure .env file exists
touch /app/.env
# ========================================
# Step 1: Wait for PostgreSQL
# ========================================
echo "[1/4] Waiting for PostgreSQL to be ready..."
retries=30
until PGPASSWORD=$DATABASE_PASSWORD psql -h "$DATABASE_HOST" -U "$DATABASE_USER" -d "$DATABASE_NAME" -c '\q' 2>/dev/null; do
retries=$((retries - 1))
if [ $retries -le 0 ]; then
echo "ERROR: PostgreSQL is not available after 30 retries"
exit 1
fi
echo " - PostgreSQL is unavailable - sleeping (${retries} retries left)"
sleep 2
done
echo " - PostgreSQL is up and accepting connections"
# ========================================
# Step 2: Run Database Migrations
# ========================================
echo ""
echo "[2/4] Running database migrations..."
# Change to database directory for Knex
cd /app/src/database
# Run migrations using the compiled knexfile
if node -e "
const knex = require('knex');
const config = require('./knexfile.js').default || require('./knexfile.js');
const env = process.env.NODE_ENV || 'production';
const db = knex(config[env]);
db.migrate.latest()
.then(([batchNo, migrations]) => {
if (migrations.length === 0) {
console.log(' - All migrations already applied');
} else {
console.log(' - Applied ' + migrations.length + ' migration(s)');
migrations.forEach(m => console.log(' * ' + m));
}
process.exit(0);
})
.catch(err => {
console.error(' - Migration failed:', err.message);
process.exit(1);
})
.finally(() => db.destroy());
"; then
echo " - Migrations completed successfully"
else
echo "ERROR: Migration failed"
exit 1
fi
# ========================================
# Step 3: Run Database Seeds (if needed)
# ========================================
echo ""
echo "[3/4] Checking if database seeding is needed..."
cd /app/src/database
# Check if we should run seeds
SHOULD_SEED="false"
if ! db_has_data; then
echo " - Database is empty, seeding required"
SHOULD_SEED="true"
elif [ "$FORCE_RESEED" = "true" ]; then
echo " - FORCE_RESEED is set, reseeding database"
SHOULD_SEED="true"
else
echo " - Database already has data, skipping seed"
fi
if [ "$SHOULD_SEED" = "true" ]; then
echo " - Running database seeds..."
if node -e "
const knex = require('knex');
const config = require('./knexfile.js').default || require('./knexfile.js');
const env = process.env.NODE_ENV || 'production';
const db = knex(config[env]);
db.seed.run()
.then(() => {
console.log(' - Seeds completed successfully');
process.exit(0);
})
.catch(err => {
console.error(' - Seed failed:', err.message);
process.exit(1);
})
.finally(() => db.destroy());
"; then
echo " - Database seeded successfully"
else
echo "ERROR: Seeding failed"
exit 1
fi
fi
# ========================================
# Step 4: Initialize Blockchain (if needed)
# ========================================
echo ""
echo "[4/4] Checking blockchain initialization..."
cd /app
if is_first_boot || [ -z "$CONTRACT_ADDRESS_LICENSE_NFT" ] || [ "$CONTRACT_ADDRESS_LICENSE_NFT" = "0x0000000000000000000000000000000000000000" ]; then
echo " - Blockchain not initialized, deploying contracts..."
node /app/scripts/init-blockchain.js
# Mark as initialized
touch /app/data/.initialized
echo " - Blockchain initialization complete"
# Reload environment variables
if [ -f "/app/.env" ]; then
set -a
source /app/.env
set +a
fi
else
echo " - Blockchain already initialized, skipping"
fi
# ========================================
# Final Health Check
# ========================================
echo ""
echo "========================================"
echo " Performing Health Checks"
echo "========================================"
# Verify database has expected data
USER_COUNT=$(PGPASSWORD=$DATABASE_PASSWORD psql -h "$DATABASE_HOST" -U "$DATABASE_USER" -d "$DATABASE_NAME" -tAc "SELECT COUNT(*) FROM users;" 2>/dev/null || echo "0")
DEPT_COUNT=$(PGPASSWORD=$DATABASE_PASSWORD psql -h "$DATABASE_HOST" -U "$DATABASE_USER" -d "$DATABASE_NAME" -tAc "SELECT COUNT(*) FROM departments;" 2>/dev/null || echo "0")
WORKFLOW_COUNT=$(PGPASSWORD=$DATABASE_PASSWORD psql -h "$DATABASE_HOST" -U "$DATABASE_USER" -d "$DATABASE_NAME" -tAc "SELECT COUNT(*) FROM workflows;" 2>/dev/null || echo "0")
echo " - Users: $USER_COUNT"
echo " - Departments: $DEPT_COUNT"
echo " - Workflows: $WORKFLOW_COUNT"
if [ "$USER_COUNT" -eq "0" ] || [ "$DEPT_COUNT" -eq "0" ]; then
echo ""
echo "WARNING: Database appears to be empty!"
echo "You may need to run: docker compose exec api npm run db:reset"
fi
# ========================================
# Start Application
# ========================================
echo ""
echo "========================================"
echo " Starting NestJS Application"
echo "========================================"
echo ""
exec npm run start:prod