@@ -51,7 +51,7 @@ info() {
5151}
5252
5353# Check root
54- if [[ $ EUID -ne 0 ]]; then
54+ if [[ " ${ EUID} " -ne 0 ]]; then
5555 error " This script must be run as root (use sudo)"
5656fi
5757
@@ -74,7 +74,7 @@ if ! command -v node &> /dev/null; then
7474 log " ✓ Node.js $( node -v) installed successfully"
7575else
7676 NODE_VERSION=$( node -v | cut -d' v' -f2 | cut -d' .' -f1)
77- if [ " $NODE_VERSION " -lt 18 ]; then
77+ if [ " ${ NODE_VERSION} " -lt 18 ]; then
7878 warn " Node.js version too old ($( node -v) ). Upgrading to 20.x..."
7979 curl -fsSL https://deb.nodesource.com/setup_20.x | bash - >> " $LOG_FILE " 2>&1
8080 apt-get install -y nodejs >> " $LOG_FILE " 2>&1 || error " Failed to upgrade Node.js"
@@ -100,7 +100,7 @@ if ! command -v pnpm &> /dev/null; then
100100 log " ✓ pnpm $( pnpm -v) installed successfully"
101101else
102102 PNPM_VERSION=$( pnpm -v | cut -d' .' -f1)
103- if [ " $PNPM_VERSION " -lt 8 ]; then
103+ if [ " ${ PNPM_VERSION} " -lt 8 ]; then
104104 warn " pnpm version too old ($( pnpm -v) ). Upgrading to 8.15.0..."
105105 npm install -g pnpm@8.15.0 >> " $LOG_FILE " 2>&1 || error " Failed to upgrade pnpm"
106106 log " ✓ pnpm upgraded to $( pnpm -v) "
154154
155155# Use pnpm for monorepo
156156PKG_MANAGER=" pnpm"
157- log " ✓ Package manager: $PKG_MANAGER "
157+ log " ✓ Package manager: ${ PKG_MANAGER} "
158158
159159# Step 2: Setup PostgreSQL with Docker
160160log " Step 2/8: Setting up PostgreSQL with Docker..."
161161
162162# Stop and remove existing container if exists
163- if docker ps -a | grep -q $ DB_CONTAINER_NAME; then
163+ if docker ps -a | grep -q " ${ DB_CONTAINER_NAME} " ; then
164164 log " Removing existing PostgreSQL container..."
165- docker stop $ DB_CONTAINER_NAME 2> /dev/null || true
166- docker rm $ DB_CONTAINER_NAME 2> /dev/null || true
165+ docker stop " ${ DB_CONTAINER_NAME} " 2> /dev/null || true
166+ docker rm " ${ DB_CONTAINER_NAME} " 2> /dev/null || true
167167fi
168168
169169# Remove old volume to ensure clean installation
181181# Start PostgreSQL container
182182log " Starting PostgreSQL container..."
183183docker run -d \
184- --name $ DB_CONTAINER_NAME \
184+ --name " ${ DB_CONTAINER_NAME} " \
185185 --network nginx-love-network \
186- -e POSTGRES_DB=$ DB_NAME \
187- -e POSTGRES_USER=$ DB_USER \
188- -e POSTGRES_PASSWORD=$ DB_PASSWORD \
189- -p 127.0.0.1:$ DB_PORT :5432 \
186+ -e POSTGRES_DB=" ${ DB_NAME} " \
187+ -e POSTGRES_USER=" ${ DB_USER} " \
188+ -e POSTGRES_PASSWORD=" ${ DB_PASSWORD} " \
189+ -p 127.0.0.1:" ${ DB_PORT} " :5432 \
190190 -v nginx-love-postgres-data:/var/lib/postgresql/data \
191191 --restart unless-stopped \
192- postgres:15-alpine >> " $LOG_FILE " 2>&1 || error " Failed to start PostgreSQL container"
192+ postgres:15-alpine >> " ${ LOG_FILE} " 2>&1 || error " Failed to start PostgreSQL container"
193193
194194# Wait for PostgreSQL to be ready
195195log " Waiting for PostgreSQL to be ready..."
196196sleep 5
197197for i in {1..30}; do
198- if docker exec $ DB_CONTAINER_NAME pg_isready -U $ DB_USER > /dev/null 2>&1 ; then
198+ if docker exec " ${ DB_CONTAINER_NAME} " pg_isready -U " ${ DB_USER} " > /dev/null 2>&1 ; then
199199 log " ✓ PostgreSQL is ready"
200200 break
201201 fi
202- if [ $i -eq 30 ]; then
202+ if [ " ${i} " -eq 30 ]; then
203203 error " PostgreSQL failed to start"
204204 fi
205205 sleep 1
206206done
207207
208208log " ✓ PostgreSQL container started successfully"
209- log " • Database: $DB_NAME "
210- log " • User: $DB_USER "
211- log " • Port: $DB_PORT "
209+ log " • Database: ${ DB_NAME} "
210+ log " • User: ${ DB_USER} "
211+ log " • Port: ${ DB_PORT} "
212212
213213# Step 3: Install Nginx + ModSecurity
214214log " Step 3/8: Installing Nginx + ModSecurity..."
215215
216216if ! command -v nginx & > /dev/null; then
217217 info " Nginx not found. Installing..."
218- bash " $PROJECT_DIR /scripts/install-nginx-modsecurity.sh" || error " Failed to install Nginx + ModSecurity"
218+ bash " ${ PROJECT_DIR} /scripts/install-nginx-modsecurity.sh" || error " Failed to install Nginx + ModSecurity"
219219 log " ✓ Nginx + ModSecurity installed"
220220else
221221 log " ✓ Nginx already installed ($( nginx -v 2>&1 | cut -d' /' -f2) )"
225225log " Step 4/8: Setting up Backend..."
226226
227227# Install root dependencies first (for monorepo)
228- cd " $PROJECT_DIR "
228+ cd " ${ PROJECT_DIR} "
229229if [ ! -d " node_modules" ]; then
230230 log " Installing monorepo dependencies..."
231- $ PKG_MANAGER install >> " $LOG_FILE " 2>&1 || error " Failed to install monorepo dependencies"
231+ " ${ PKG_MANAGER} " install >> " ${ LOG_FILE} " 2>&1 || error " Failed to install monorepo dependencies"
232232else
233233 log " ✓ Monorepo dependencies already installed"
234234fi
235235
236- cd " $BACKEND_DIR "
236+ cd " ${ BACKEND_DIR} "
237237
238238# Create backend .env from .env.example (always create fresh)
239239log " Creating fresh backend .env from .env.example..."
240240cat > " .env" << EOF
241241# Database Configuration
242- DATABASE_URL="postgresql://$DB_USER : $ DB_PASSWORD @localhost:$DB_PORT / $ DB_NAME ?schema=public"
242+ DATABASE_URL="postgresql://${ DB_USER} : ${ DB_PASSWORD} @localhost:${ DB_PORT} / ${ DB_NAME} ?schema=public"
243243
244244# Server Configuration
245245PORT=3001
246246NODE_ENV="production"
247247
248248# JWT Configuration
249- JWT_ACCESS_SECRET="$JWT_ACCESS_SECRET "
250- JWT_REFRESH_SECRET="$JWT_REFRESH_SECRET "
249+ JWT_ACCESS_SECRET="${ JWT_ACCESS_SECRET} "
250+ JWT_REFRESH_SECRET="${ JWT_REFRESH_SECRET} "
251251JWT_ACCESS_EXPIRES_IN=15m
252252JWT_REFRESH_EXPIRES_IN=7d
253253
254254# CORS Configuration (comma-separated origins)
255- CORS_ORIGIN="http://$PUBLIC_IP :8080,http://localhost:8080,http://localhost:5173,http://$PUBLIC_IP ,http://localhost"
255+ CORS_ORIGIN="http://${ PUBLIC_IP} :8080,http://localhost:8080,http://localhost:5173,http://${ PUBLIC_IP} ,http://localhost"
256256
257257# Security
258258BCRYPT_ROUNDS=10
259259
260260# Session
261- SESSION_SECRET="$SESSION_SECRET "
261+ SESSION_SECRET="${ SESSION_SECRET} "
262262
263263# 2FA
264264TWO_FACTOR_APP_NAME="Nginx Love UI"
@@ -278,7 +278,7 @@ log "✅ Created fresh backend .env"
278278
279279log " ✓ Backend .env configured with:"
280280log " • Database: PostgreSQL (Docker)"
281- log " • CORS Origins: $PUBLIC_IP , localhost"
281+ log " • CORS Origins: ${ PUBLIC_IP} , localhost"
282282log " • JWT Secrets: Generated (64 chars each)"
283283
284284# Generate Prisma Client
@@ -299,24 +299,24 @@ log "✓ Backend setup completed"
299299
300300# Step 5: Build Backend
301301log " Step 5/8: Building Backend..."
302- cd " $PROJECT_DIR "
303- pnpm --filter @nginx-love/api build >> " $LOG_FILE " 2>&1 || error " Failed to build backend"
302+ cd " ${ PROJECT_DIR} "
303+ pnpm --filter @nginx-love/api build >> " ${ LOG_FILE} " 2>&1 || error " Failed to build backend"
304304log " ✓ Backend built successfully"
305305
306306# Step 6: Setup Frontend
307307log " Step 6/8: Setting up Frontend..."
308308
309- cd " $FRONTEND_DIR "
309+ cd " ${ FRONTEND_DIR} "
310310
311311# Create frontend .env from .env.example (always create fresh)
312312log " Creating fresh frontend .env from .env.example..."
313313cat > " .env" << EOF
314- VITE_API_URL=http://$PUBLIC_IP :3001/api
314+ VITE_API_URL=http://${ PUBLIC_IP} :3001/api
315315EOF
316316
317317log " ✅ Created fresh frontend .env"
318318
319- log " ✓ Frontend .env configured with API: http://$PUBLIC_IP :3001/api"
319+ log " ✓ Frontend .env configured with API: http://${ PUBLIC_IP} :3001/api"
320320
321321# Clean previous build
322322if [ -d " dist" ]; then
326326
327327# Build frontend
328328log " Building frontend..."
329- cd " $PROJECT_DIR "
330- pnpm --filter @nginx-love/web build >> " $LOG_FILE " 2>&1 || error " Failed to build frontend"
329+ cd " ${ PROJECT_DIR} "
330+ pnpm --filter @nginx-love/web build >> " ${ LOG_FILE} " 2>&1 || error " Failed to build frontend"
331331
332332# Update CSP in built index.html to use public IP
333333log " Updating Content Security Policy with public IP..."
334- sed -i " s|__API_URL__|http://$PUBLIC_IP :3001 http://localhost:3001|g" " $FRONTEND_DIR /dist/index.html"
335- sed -i " s|__WS_URL__|ws://$PUBLIC_IP :* ws://localhost:*|g" " $FRONTEND_DIR /dist/index.html"
334+ sed -i " s|__API_URL__|http://${ PUBLIC_IP} :3001 http://localhost:3001|g" " ${ FRONTEND_DIR} /dist/index.html"
335+ sed -i " s|__WS_URL__|ws://${ PUBLIC_IP} :* ws://localhost:*|g" " ${ FRONTEND_DIR} /dist/index.html"
336336
337337log " ✓ Frontend built successfully"
338- log " ✓ CSP configured for: http://$PUBLIC_IP :3001, http://localhost:3001"
338+ log " ✓ CSP configured for: http://${ PUBLIC_IP} :3001, http://localhost:3001"
339339
340340# Step 7: Setup Nginx Configuration
341341log " Step 7/8: Configuring Nginx..."
@@ -377,7 +377,7 @@ After=network.target postgresql.service
377377[Service]
378378Type=simple
379379User=root
380- WorkingDirectory=$BACKEND_DIR
380+ WorkingDirectory=${ BACKEND_DIR}
381381Environment=NODE_ENV=production
382382ExecStart=$( which node) dist/index.js
383383Restart=always
@@ -398,7 +398,7 @@ After=network.target
398398[Service]
399399Type=simple
400400User=root
401- WorkingDirectory=$FRONTEND_DIR
401+ WorkingDirectory=${ FRONTEND_DIR}
402402Environment=NODE_ENV=production
403403ExecStart=$( which pnpm) preview --host 0.0.0.0 --port 8080
404404Restart=always
@@ -460,31 +460,31 @@ log "Deployment Completed Successfully!"
460460log " =================================="
461461log " "
462462log " 📋 Service Status:"
463- log " • PostgreSQL: Docker container '$DB_CONTAINER_NAME '"
464- log " • Backend API: http://$PUBLIC_IP :3001"
465- log " • Frontend UI: http://$PUBLIC_IP :8080"
463+ log " • PostgreSQL: Docker container '${ DB_CONTAINER_NAME} '"
464+ log " • Backend API: http://${ PUBLIC_IP} :3001"
465+ log " • Frontend UI: http://${ PUBLIC_IP} :8080"
466466log " • Nginx: Port 80/443"
467467log " "
468468log " 🔐 Database Credentials:"
469469log " • Host: localhost"
470- log " • Port: $DB_PORT "
471- log " • Database: $DB_NAME "
472- log " • Username: $DB_USER "
473- log " • Password: $DB_PASSWORD "
470+ log " • Port: ${ DB_PORT} "
471+ log " • Database: ${ DB_NAME} "
472+ log " • Username: ${ DB_USER} "
473+ log " • Password: ${ DB_PASSWORD} "
474474log " "
475475log " 🔑 Security Keys:"
476- log " • JWT Access Secret: $JWT_ACCESS_SECRET "
477- log " • JWT Refresh Secret: $JWT_REFRESH_SECRET "
478- log " • Session Secret: $SESSION_SECRET "
476+ log " • JWT Access Secret: ${ JWT_ACCESS_SECRET} "
477+ log " • JWT Refresh Secret: ${ JWT_REFRESH_SECRET} "
478+ log " • Session Secret: ${ SESSION_SECRET} "
479479log " "
480480log " 📝 Manage Services:"
481- log " PostgreSQL: docker start|stop|restart $DB_CONTAINER_NAME "
481+ log " PostgreSQL: docker start|stop|restart ${ DB_CONTAINER_NAME} "
482482log " Backend: systemctl {start|stop|restart|status} nginx-love-backend"
483483log " Frontend: systemctl {start|stop|restart|status} nginx-love-frontend"
484484log " Nginx: systemctl {start|stop|restart|status} nginx"
485485log " "
486486log " 📊 View Logs:"
487- log " PostgreSQL: docker logs -f $DB_CONTAINER_NAME "
487+ log " PostgreSQL: docker logs -f ${ DB_CONTAINER_NAME} "
488488log " Backend: tail -f /var/log/nginx-love-backend.log"
489489log " Frontend: tail -f /var/log/nginx-love-frontend.log"
490490log " Nginx: tail -f /var/log/nginx/error.log"
@@ -493,7 +493,7 @@ log "🔐 Default Credentials:"
493493log " Username: admin"
494494log " Password: admin123"
495495log " "
496- log " 🌐 Access the portal at: http://$PUBLIC_IP :8080"
496+ log " 🌐 Access the portal at: http://${ PUBLIC_IP} :8080"
497497log " "
498498
499499# Save credentials to file
@@ -502,31 +502,31 @@ cat > /root/.nginx-love-credentials <<EOF
502502# Generated: $( date)
503503
504504## Public Access
505- Frontend: http://$PUBLIC_IP :8080
506- Backend: http://$PUBLIC_IP :3001
505+ Frontend: http://${ PUBLIC_IP} :8080
506+ Backend: http://${ PUBLIC_IP} :3001
507507
508508## Database (Docker)
509- Container: $DB_CONTAINER_NAME
509+ Container: ${ DB_CONTAINER_NAME}
510510Host: localhost
511- Port: $DB_PORT
512- Database: $DB_NAME
513- Username: $DB_USER
514- Password: $DB_PASSWORD
511+ Port: ${ DB_PORT}
512+ Database: ${ DB_NAME}
513+ Username: ${ DB_USER}
514+ Password: ${ DB_PASSWORD}
515515
516516## Security Keys
517- JWT_ACCESS_SECRET=$JWT_ACCESS_SECRET
518- JWT_REFRESH_SECRET=$JWT_REFRESH_SECRET
519- SESSION_SECRET=$SESSION_SECRET
517+ JWT_ACCESS_SECRET=${ JWT_ACCESS_SECRET}
518+ JWT_REFRESH_SECRET=${ JWT_REFRESH_SECRET}
519+ SESSION_SECRET=${ SESSION_SECRET}
520520
521521## Default Login
522522Username: admin
523523Password: admin123
524524
525525## Docker Commands
526- Start: docker start $DB_CONTAINER_NAME
527- Stop: docker stop $DB_CONTAINER_NAME
528- Logs: docker logs -f $DB_CONTAINER_NAME
529- Connect: docker exec -it $DB_CONTAINER_NAME psql -U $DB_USER -d $DB_NAME
526+ Start: docker start ${ DB_CONTAINER_NAME}
527+ Stop: docker stop ${ DB_CONTAINER_NAME}
528+ Logs: docker logs -f ${ DB_CONTAINER_NAME}
529+ Connect: docker exec -it ${ DB_CONTAINER_NAME} psql -U ${ DB_USER} -d ${ DB_NAME}
530530EOF
531531
532532chmod 600 /root/.nginx-love-credentials
547547fi
548548
549549log " "
550- log " Deployment log saved to: $LOG_FILE "
550+ log " Deployment log saved to: ${ LOG_FILE} "
551551log " =================================="
0 commit comments