Complete step-by-step installation guide for Deploy Center deployment platform.
Current version: v3.0.0 (released 2026-05-24). v3.0 adds a Redis requirement on top of the v2.1 stack — see System Requirements. For upgrading an existing v2.1 install, follow migration-v2-to-v3.md instead.
- System Requirements
- Installation Steps
- Database Setup
- Redis Setup (v3.0)
- Environment Configuration
- First Run
- Production Setup
- Docker Installation
- Troubleshooting
- Operating System: Linux, macOS, or Windows
- Node.js: Version 18.0.0 or higher
- npm: Version 9.0.0 or higher
- MariaDB: Version 11.2 or higher (or MySQL 8.0+)
- Redis: Version 7 or higher — required in v3.0 for the BullMQ queue
- RAM: 512 MB minimum (2 GB recommended)
- Disk Space: 500 MB minimum (2 GB recommended for deployments)
- Git: Version 2.0 or higher
- Node.js: Version 20.x or 22.x
- MariaDB: Version 11.x latest
- Redis: Version 7.x latest
- RAM: 4 GB or more
- CPU: 2 cores or more
- SSD Storage: For better performance
# Check Node.js version
node --version
# Should output: v18.0.0 or higher
# Check npm version
npm --version
# Should output: 9.0.0 or higher
# Check MariaDB/MySQL version
mysql --version
# Should output: mysql Ver 15.1 Distrib 11.x or higher (or MySQL 8.0+)
# Check Redis is running (v3.0)
redis-cli ping
# Should output: PONG
# Check Git version
git --version
# Should output: git version 2.x.x or higher# Install Node.js 22.x LTS
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt-get install -y nodejs
# Verify installation
node --version
npm --version# Install Node.js 22.x
curl -fsSL https://rpm.nodesource.com/setup_22.x | sudo bash -
sudo yum install -y nodejs
# Verify installation
node --version
npm --version# Using Homebrew
brew install node@22
# Verify installation
node --version
npm --version- Download installer from nodejs.org
- Run the installer
- Follow the installation wizard
- Verify installation in Command Prompt:
node --version
npm --version# Update package list
sudo apt update
# Install MariaDB
sudo apt install mariadb-server mariadb-client
# Secure installation
sudo mysql_secure_installation
# Start MariaDB service
sudo systemctl start mariadb
sudo systemctl enable mariadb
# Verify installation
mysql --version# Install MariaDB
sudo yum install mariadb-server mariadb
# Start MariaDB service
sudo systemctl start mariadb
sudo systemctl enable mariadb
# Secure installation
sudo mysql_secure_installation
# Verify installation
mysql --version# Using Homebrew
brew install mariadb
# Start MariaDB service
brew services start mariadb
# Secure installation
mysql_secure_installation
# Verify installation
mysql --version- Download MariaDB installer from mariadb.org
- Run the installer
- Set root password during installation
- Verify installation in Command Prompt:
mysql --version# Clone the repository
git clone https://github.com/FutureSolutionDev/Deploy-Center-Server.git
# Navigate to server directory
cd Deploy-Center-Server# Install all npm dependencies
npm install
# Or
yarn install
# This will install:
# - Express and middleware
# - TypeScript and ts-node
# - Sequelize ORM and MariaDB driver
# - JWT and bcrypt
# - Winston logger
# - And all other dependenciesExpected output:
added 500+ packages in 30s
# Login to MariaDB as root
sudo mysql -u root -p
# Enter your root password when prompted-- Create database with UTF-8 encoding
CREATE DATABASE deploy_center
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
-- Verify database creation
SHOW DATABASES;-- Create dedicated user for Deploy Center
CREATE USER 'deploy_user'@'localhost' IDENTIFIED BY 'YourSecurePassword123!';
-- Grant all privileges on deploy_center database
GRANT ALL PRIVILEGES ON deploy_center.* TO 'deploy_user'@'localhost';
-- If you need remote access (replace 'your-ip' with actual IP)
CREATE USER 'deploy_user'@'your-ip' IDENTIFIED BY 'YourSecurePassword123!';
GRANT ALL PRIVILEGES ON deploy_center.* TO 'deploy_user'@'your-ip';
-- Apply changes
FLUSH PRIVILEGES;
-- Verify user creation
SELECT User, Host FROM mysql.user WHERE User = 'deploy_user';
-- Exit MariaDB
EXIT;# Test connection with new user
mysql -u deploy_user -p deploy_center
# Enter password: YourSecurePassword123!
# If successful, you should see:
# MariaDB [deploy_center]>
# Exit
EXIT;v3.0 (F-001) replaced the in-memory deployment queue with BullMQ + Redis.
Redis is now a hard requirement — without it, QueueReadyMiddleware
short-circuits new deployment triggers with 503 (the server itself
does NOT crash; it retries Redis with exponential backoff and auto-recovers).
Drop this into a docker-compose.yml next to the server:
services:
redis:
image: redis:7-alpine
container_name: deploy-center-redis
ports: ["6379:6379"]
volumes: ["redis-data:/data"]
restart: unless-stopped
volumes:
redis-data:Start it:
docker compose up -d redis
docker compose logs -f redis # tail logs
redis-cli ping # → PONGUbuntu / Debian:
sudo apt update
sudo apt install -y redis-server
sudo systemctl enable --now redis-server
redis-cli ping # → PONGmacOS (Homebrew):
brew install redis
brew services start redis
redis-cli pingRHEL / CentOS / Rocky:
sudo dnf install -y redis
sudo systemctl enable --now redis
redis-cli pingOnce the server is running with Redis up, BullMQ jobs are visible at
http://localhost:9090/admin/queues — gated by AuthMiddleware +
RoleMiddleware([Admin]). Use it to inspect queued / active / failed /
delayed jobs and drain stuck queues without touching the database.
# Copy the example environment file
cp .env.example .env
# Open the file for editing
nano .env
# or
vim .env
# or use your preferred text editorEdit .env file and update the database section:
# Database Configuration
DB_HOST=localhost
DB_PORT=3306
DB_NAME=deploy_center
DB_USER=deploy_user
DB_PASSWORD=YourSecurePassword123!
DB_DIALECT=mysql # Use the mysql2 npm driver — works against both MySQL and MariaDB
# (avoids the Sequelize 6.37 + mariadb driver formatResults bug; see CLAUDE.md)# Redis Configuration — required for BullMQ persistent queue (F-001)
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0# Server Configuration
NODE_ENV=development
PORT=9090IMPORTANT: Never use default secrets in production!
# Generate random secret for JWT
node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
# Copy the output
# Generate another for refresh token
node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
# Copy the outputUpdate .env:
# JWT Configuration
JWT_SECRET=<paste-first-generated-secret-here>
JWT_EXPIRY=1h
JWT_REFRESH_SECRET=<paste-second-generated-secret-here>
JWT_REFRESH_EXPIRY=7d# Generate 32-character encryption key
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# Copy the outputUpdate .env:
# Encryption Configuration
ENCRYPTION_KEY=<paste-generated-key-here># CORS Configuration (Separate by comma Between Every Origin)
CORS_ORIGINS=http://localhost:5173,https://yourdomain.com# Paths Configuration
DEPLOYMENTS_PATH=./deployments
LOGS_PATH=./logs# Server
NODE_ENV=development
PORT=9090
# Database
DB_HOST=localhost
DB_PORT=3306
DB_NAME=deploy_center
DB_USER=deploy_user
DB_PASSWORD=YourSecurePassword123!
DB_DIALECT=mariadb
# JWT
JWT_SECRET=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6
JWT_EXPIRY=1h
JWT_REFRESH_SECRET=z6y5x4w3v2u1t0s9r8q7p6o5n4m3l2k1j0i9h8g7f6e5d4c3b2a1
JWT_REFRESH_EXPIRY=7d
# Encryption
ENCRYPTION_KEY=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
# CORS
CORS_ORIGINS=http://localhost:5173
# Paths
DEPLOYMENTS_PATH=./deployments
LOGS_PATH=./logs# Compile TypeScript to JavaScript
npm run build
# Or
yarn build
# This creates the 'dist' directory with compiled filesExpected output:
Successfully compiled TypeScript
# Start server in development mode with hot reload
npm run dev
# Or
yarn devExpected output:
╔════════════════════════════════════════════════════════╗
║ ║
║ 🚀 Deploy Center Server Started 🚀 ║
║ ║
║ Port: 3000 ║
║ Environment: development ║
║ API: http://localhost:9090/api ║
║ Health: http://localhost:9090/health ║
║ ║
╚════════════════════════════════════════════════════════╝
# Test health endpoint
curl http://localhost:9090/health
# Expected response:
# {
# "Success": true,
# "Message": "Deploy Center API is running",
# "Timestamp": "2025-01-26T..."
# }# Login to MariaDB
mysql -u deploy_user -p deploy_center
# List tables (should be auto-created on first run)
SHOW TABLES;
# Expected output:
# +---------------------------+
# | Tables_in_deploy_center |
# +---------------------------+
# | AuditLogs |
# | DeploymentSteps |
# | Deployments |
# | Projects |
# | Users |
# +---------------------------+# Using curl
curl -X POST http://localhost:9090/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"Username": "admin",
"Email": "admin@example.com",
"Password": "Admin@12345",
"Role": "admin"
}'
# Save the AccessToken from response for next requestsExpected response:
{
"Success": true,
"Message": "User registered successfully",
"Data": {
"User": {
"Id": 1,
"Username": "admin",
"Email": "admin@example.com",
"Role": "admin"
},
"Tokens": {
"AccessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"RefreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
},
"Code": 201
}# Get user profile (replace YOUR_TOKEN with actual token)
curl -X GET http://localhost:9090/api/auth/profile \
-H "Authorization: Bearer YOUR_TOKEN"
# Expected: User profile dataCreate .env.production:
NODE_ENV=production
PORT=9090
# ... rest of configuration# Clean previous builds
npm run clean
# Build TypeScript
npm run build
# Or
yarn build
# Install only production dependencies
npm ci --production# Install PM2 globally
npm install -g pm2Create ecosystem.config.js:
module.exports = {
apps: [{
name: 'deploy-center',
script: './dist/index.js',
instances: 2,
exec_mode: 'cluster',
env: {
NODE_ENV: 'production',
PORT: 9090
},
error_file: './logs/pm2-error.log',
out_file: './logs/pm2-out.log',
time: true,
autorestart: true,
max_restarts: 10,
min_uptime: '10s',
max_memory_restart: '500M',
}]
};# Start application
pm2 start ecosystem.config.js --env production
# Save PM2 configuration
pm2 save
# Setup PM2 to start on system boot
pm2 startup
# Follow the instructions from the output
# Monitor application
pm2 monit
# View logs
pm2 logs deploy-centerInstall Nginx:
sudo apt install nginx # Ubuntu/DebianCreate Nginx configuration /etc/nginx/sites-available/deploy-center:
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
# Redirect HTTP to HTTPS (after SSL setup)
# return 301 https://$server_name$request_uri;
location / {
proxy_pass http://localhost:9090;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
# Increase timeout for long deployments
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
}
}Enable the site:
# Create symbolic link
sudo ln -s /etc/nginx/sites-available/deploy-center /etc/nginx/sites-enabled/
# Test configuration
sudo nginx -t
# Restart Nginx
sudo systemctl restart nginx# Install Certbot
sudo apt install certbot python3-certbot-nginx
# Obtain SSL certificate
sudo certbot --nginx -d yourdomain.com
# Certificates will auto-renew# Allow SSH, HTTP, HTTPS
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
# Check status
sudo ufw statusCreate backup script /usr/local/bin/backup-deploy-center.sh:
#!/bin/bash
BACKUP_DIR="/var/backups/deploy-center"
DATE=$(date +%Y%m%d_%H%M%S)
DB_NAME="deploy_center"
DB_USER="deploy_user"
DB_PASS="YourSecurePassword123!"
# Create backup directory
mkdir -p $BACKUP_DIR
# Backup database
mysqldump -u $DB_USER -p$DB_PASS $DB_NAME > $BACKUP_DIR/db_backup_$DATE.sql
# Compress backup
gzip $BACKUP_DIR/db_backup_$DATE.sql
# Delete backups older than 30 days
find $BACKUP_DIR -name "*.gz" -mtime +30 -delete
echo "Backup completed: db_backup_$DATE.sql.gz"Make executable and setup cron:
# Make executable
sudo chmod +x /usr/local/bin/backup-deploy-center.sh
# Add to crontab (daily at 2 AM)
sudo crontab -e
# Add this line:
0 2 * * * /usr/local/bin/backup-deploy-center.shCreate Dockerfile:
FROM node:22-alpine
# Install git
RUN apk add --no-cache git
# Create app directory
WORKDIR /usr/src/app
# Copy package files
COPY package*.json ./
# Install dependencies
RUN npm ci --production
# Copy app source
COPY . .
# Build TypeScript
RUN npm run build
# Expose port
EXPOSE 3000
# Start application
CMD ["node", "dist/index.js"]version: '3.8'
services:
mariadb:
image: mariadb:10.11
restart: always
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: deploy_center
MYSQL_USER: deploy_user
MYSQL_PASSWORD: deploypassword
volumes:
- mariadb_data:/var/lib/mysql
ports:
- "3306:3306"
networks:
- deploy-network
app:
build: .
restart: always
ports:
- "9090:9090"
environment:
NODE_ENV: production
DB_HOST: mariadb
DB_PORT: 3306
DB_NAME: deploy_center
DB_USER: deploy_user
DB_PASSWORD: deploypassword
depends_on:
- mariadb
volumes:
- ./deployments:/usr/src/app/deployments
- ./logs:/usr/src/app/logs
networks:
- deploy-network
volumes:
mariadb_data:
networks:
deploy-network:
driver: bridge# Build and start services
docker-compose up -d
# View logs
docker-compose logs -f app
# Stop services
docker-compose down
# Stop and remove volumes
docker-compose down -vSymptom:
Error: connect ECONNREFUSED 127.0.0.1:3306
Solutions:
# Check if MariaDB is running
sudo systemctl status mariadb
# Start MariaDB if not running
sudo systemctl start mariadb
# Check MariaDB is listening on port 3306
sudo netstat -tlnp | grep 3306
# Test database credentials
mysql -u deploy_user -p deploy_center
# Check .env file configuration
cat .env | grep DB_Symptom:
Error: listen EADDRINUSE: address already in use :::9090
Solutions:
# Find process using port 9090
lsof -i :9090
# Kill the process (replace PID with actual process ID)
kill -9 PID
# Or change port in .env
PORT=9091Symptom:
Error: EACCES: permission denied
Solutions:
# Fix deployments directory permissions
sudo chown -R $USER:$USER ./deployments
chmod 755 ./deployments
# Fix logs directory permissions
sudo chown -R $USER:$USER ./logs
chmod 755 ./logsSymptom:
Error: Cannot find module '@Config/AppConfig'
Solutions:
# Reinstall dependencies
rm -rf node_modules package-lock.json
npm install
# Or
yarn install
# Rebuild TypeScript
npm run build
# Or
yarn build
# Check tsconfig.json paths configurationSolutions:
# Clean and rebuild
npm run clean
npm run build
# Or
yarn clean
yarn build
# Check TypeScript version
npx tsc --version
# Reinstall TypeScript
npm install -D typescript@latest
# Or
yarn add -D typescript@latestSolutions:
- Check webhook secret matches between GitHub and project
- Verify server is accessible from internet (use ngrok for local testing)
- Check webhook logs in GitHub settings
- Test webhook endpoint manually
- Review logs:
tail -f logs/combined-*.log
Solutions:
# Check PM2 status
pm2 status
# Delete and restart
pm2 delete deploy-center
pm2 start ecosystem.config.js
# Check logs
pm2 logs deploy-center
# Reset PM2
pm2 kill
pm2 start ecosystem.config.jsIf you encounter issues not covered here:
-
Check Logs:
# Application logs tail -f logs/combined-*.log tail -f logs/error-*.log # PM2 logs (if using PM2) pm2 logs deploy-center
-
Enable Debug Mode:
NODE_ENV=development LOG_LEVEL=debug
-
Check GitHub Issues: Search for similar issues
-
Create New Issue: Include logs and configuration (remove sensitive data)
After installation, verify everything is working:
- Node.js and npm installed (v18+)
- MariaDB installed and running
- Database created and user configured
- Dependencies installed (
npm install) -
.envfile configured with secure secrets - Server starts without errors (
npm run dev) - Health endpoint responds (
/health) - Can register user (
POST /api/auth/register) - Can login (
POST /api/auth/login) - Can create project (
POST /api/projects) - Webhook endpoint accessible (
/webhook/test/:projectName) - Logs being written to
logs/directory - PM2 running in production (if applicable)
- Nginx reverse proxy working (if applicable)
- SSL certificate installed (if applicable)
- Firewall configured (if applicable)
- Database backups configured (if applicable)
Your Deploy Center server is now installed and ready to use!
Next Steps:
- Read the Quick Start Guide
- Import the Postman Collection
- Setup your first project
- Configure GitHub webhooks
- Start deploying!
For detailed usage instructions, see README.md