Fix deployment issues found during end-to-end testing
- install.sh: Use tar --strip-components=1 instead of mv for robust extraction when install dir partially exists (root-owned Docker artifacts) - config.sh: Add --non-interactive mode (--domain, --admin-password, --enable-all flags) for CI/CD and automated deployments - docker-entrypoint.sh: Validate critical env vars on startup, fail early with clear messages instead of silent failures - docker-compose.yml: Change Redis eviction policy from allkeys-lru to noeviction (required by BullMQ job queues) - Prisma: Add missing petitions.coverVideoId migration (schema had the column but migration omitted it, causing 500 on public endpoint) - Add scripts/uninstall.sh for clean removal including root-owned files - Add scripts/test-deployment.sh for automated post-install verification Bunker Admin
This commit is contained in:
@@ -7,6 +7,36 @@ if [ "$NODE_ENV" = "production" ] && [ "$NODE_TLS_REJECT_UNAUTHORIZED" = "0" ];
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate critical environment variables
|
||||
ENV_ERRORS=0
|
||||
check_env() {
|
||||
if [ -z "$2" ] || echo "$2" | grep -q "REQUIRED_STRONG_PASSWORD\|GENERATE_WITH_openssl"; then
|
||||
echo "FATAL: $1 is not set or contains a placeholder value"
|
||||
ENV_ERRORS=$((ENV_ERRORS + 1))
|
||||
fi
|
||||
}
|
||||
|
||||
check_env "DATABASE_URL" "$DATABASE_URL"
|
||||
check_env "REDIS_URL" "$REDIS_URL"
|
||||
check_env "JWT_ACCESS_SECRET" "$JWT_ACCESS_SECRET"
|
||||
check_env "JWT_REFRESH_SECRET" "$JWT_REFRESH_SECRET"
|
||||
check_env "ENCRYPTION_KEY" "$ENCRYPTION_KEY"
|
||||
check_env "INITIAL_ADMIN_PASSWORD" "$INITIAL_ADMIN_PASSWORD"
|
||||
|
||||
if [ "$ENV_ERRORS" -gt 0 ]; then
|
||||
echo ""
|
||||
echo "FATAL: $ENV_ERRORS required environment variable(s) missing or invalid."
|
||||
echo "Run the configuration wizard: bash config.sh"
|
||||
echo "Or set them manually in .env and restart."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Fix permissions for mounted volumes (host dirs may be root-owned on first run)
|
||||
if [ "$(id -u)" = "0" ]; then
|
||||
mkdir -p /app/logs /data/geoip /app/uploads 2>/dev/null || true
|
||||
chown -R node:node /app/logs /data/geoip /app/uploads 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Wait for PostgreSQL to be ready before running migrations
|
||||
echo "Waiting for database..."
|
||||
MAX_WAIT=30
|
||||
@@ -43,6 +73,7 @@ if [ -n "$MAXMIND_ACCOUNT_ID" ] && [ -n "$MAXMIND_LICENSE_KEY" ]; then
|
||||
if node -e "
|
||||
const https = require('https');
|
||||
const fs = require('fs');
|
||||
setTimeout(() => { console.error('GeoIP download timed out after 60s'); process.exit(1); }, 60000).unref();
|
||||
const auth = Buffer.from('$MAXMIND_ACCOUNT_ID:$MAXMIND_LICENSE_KEY').toString('base64');
|
||||
const get = (url, cb) => https.get(url, { headers: url.includes('maxmind.com') ? { Authorization: 'Basic ' + auth } : {} }, (res) => {
|
||||
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) return get(res.headers.location, cb);
|
||||
@@ -51,7 +82,7 @@ if [ -n "$MAXMIND_ACCOUNT_ID" ] && [ -n "$MAXMIND_LICENSE_KEY" ]; then
|
||||
res.pipe(out);
|
||||
out.on('close', () => cb(null));
|
||||
}).on('error', cb);
|
||||
get('$DOWNLOAD_URL', (err) => { if (err) { console.error(err.message); process.exit(1); } });
|
||||
get('$DOWNLOAD_URL', (err) => { if (err) { console.error(err.message); process.exit(1); } else { process.exit(0); } });
|
||||
"; then
|
||||
tar -xzf /tmp/geolite2.tar.gz -C /tmp/ 2>/dev/null
|
||||
MMDB_FILE=$(find /tmp -name 'GeoLite2-City.mmdb' -type f 2>/dev/null | head -1)
|
||||
@@ -82,4 +113,9 @@ if [ -f "src/server.ts" ] && echo "$@" | grep -q "npm.*start\|node.*dist"; then
|
||||
fi
|
||||
|
||||
echo "Starting server..."
|
||||
exec "$@"
|
||||
# Drop to node user if running as root (production image uses su-exec)
|
||||
if [ "$(id -u)" = "0" ] && command -v su-exec >/dev/null 2>&1; then
|
||||
exec su-exec node "$@"
|
||||
else
|
||||
exec "$@"
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
-- AlterTable: Add missing coverVideoId column to petitions table
|
||||
-- This column was present in the Prisma schema but omitted from the original
|
||||
-- 20260402200000_add_petitions migration.
|
||||
ALTER TABLE "petitions" ADD COLUMN "coverVideoId" INTEGER;
|
||||
Reference in New Issue
Block a user