vps-initializer.ts•9.69 kB
import { SSHService } from '../services/ssh-service.js';
import { logger } from '../utils/logger.js';
export interface VPSInitResult {
service: string;
success: boolean;
message: string;
}
export interface VPSServices {
nodejs?: boolean;
pm2?: boolean;
rust?: boolean;
nginx?: boolean;
redis?: boolean;
}
export class VPSInitializer {
constructor(private sshService: SSHService) {}
async initializeVPS(services: VPSServices): Promise<VPSInitResult[]> {
const results: VPSInitResult[] = [];
// Always start with system updates
results.push(await this.updateSystem());
// Install requested services
if (services.nodejs) {
results.push(await this.installNodeJS());
}
if (services.pm2) {
results.push(await this.installPM2());
}
if (services.rust) {
results.push(await this.installRust());
}
if (services.nginx) {
results.push(await this.installNginx());
}
if (services.redis) {
results.push(await this.installRedis());
}
return results;
}
private async updateSystem(): Promise<VPSInitResult> {
logger.info('Starting system update');
try {
// Update package lists
const updateResult = await this.sshService.executeCommand('apt update');
if (!updateResult.success) {
return {
service: 'system-update',
success: false,
message: `Failed to update package lists: ${updateResult.stderr}`,
};
}
// Upgrade packages
const upgradeResult = await this.sshService.executeCommand(
'DEBIAN_FRONTEND=noninteractive apt upgrade -y'
);
if (!upgradeResult.success) {
return {
service: 'system-update',
success: false,
message: `Failed to upgrade packages: ${upgradeResult.stderr}`,
};
}
// Install essential packages
const essentialPackages = [
'curl',
'wget',
'git',
'unzip',
'software-properties-common',
'apt-transport-https',
'ca-certificates',
'gnupg',
'lsb-release',
'ufw',
];
const installResult = await this.sshService.executeCommand(
`DEBIAN_FRONTEND=noninteractive apt install -y ${essentialPackages.join(' ')}`
);
if (!installResult.success) {
return {
service: 'system-update',
success: false,
message: `Failed to install essential packages: ${installResult.stderr}`,
};
}
return {
service: 'system-update',
success: true,
message: 'System updated and essential packages installed',
};
} catch (error) {
logger.error('System update failed', { error });
return {
service: 'system-update',
success: false,
message: `System update failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
};
}
}
private async installNodeJS(): Promise<VPSInitResult> {
logger.info('Installing Node.js');
try {
// Install Node.js via NodeSource repository
const commands = [
'curl -fsSL https://deb.nodesource.com/setup_lts.x | bash -',
'DEBIAN_FRONTEND=noninteractive apt install -y nodejs',
'npm install -g npm@latest',
];
for (const command of commands) {
const result = await this.sshService.executeCommand(command);
if (!result.success) {
return {
service: 'nodejs',
success: false,
message: `Failed to install Node.js: ${result.stderr}`,
};
}
}
// Verify installation
const versionResult = await this.sshService.executeCommand('node --version && npm --version');
if (!versionResult.success) {
return {
service: 'nodejs',
success: false,
message: 'Node.js installation failed verification',
};
}
return {
service: 'nodejs',
success: true,
message: `Node.js installed successfully: ${versionResult.stdout.trim()}`,
};
} catch (error) {
logger.error('Node.js installation failed', { error });
return {
service: 'nodejs',
success: false,
message: `Node.js installation failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
};
}
}
private async installPM2(): Promise<VPSInitResult> {
logger.info('Installing PM2');
try {
const installResult = await this.sshService.executeCommand('npm install -g pm2');
if (!installResult.success) {
return {
service: 'pm2',
success: false,
message: `Failed to install PM2: ${installResult.stderr}`,
};
}
// Setup PM2 startup script
await this.sshService.executeCommand('pm2 startup');
// Note: startup command may require manual execution, but we log it
return {
service: 'pm2',
success: true,
message: 'PM2 installed successfully. Run the startup command if needed.',
};
} catch (error) {
logger.error('PM2 installation failed', { error });
return {
service: 'pm2',
success: false,
message: `PM2 installation failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
};
}
}
private async installRust(): Promise<VPSInitResult> {
logger.info('Installing Rust');
try {
const installResult = await this.sshService.executeCommand(
'curl --proto "=https" --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y'
);
if (!installResult.success) {
return {
service: 'rust',
success: false,
message: `Failed to install Rust: ${installResult.stderr}`,
};
}
// Source the cargo environment
await this.sshService.executeCommand('source ~/.cargo/env');
// Verify installation
const versionResult = await this.sshService.executeCommand('~/.cargo/bin/rustc --version');
if (!versionResult.success) {
return {
service: 'rust',
success: false,
message: 'Rust installation failed verification',
};
}
return {
service: 'rust',
success: true,
message: `Rust installed successfully: ${versionResult.stdout.trim()}`,
};
} catch (error) {
logger.error('Rust installation failed', { error });
return {
service: 'rust',
success: false,
message: `Rust installation failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
};
}
}
private async installNginx(): Promise<VPSInitResult> {
logger.info('Installing Nginx');
try {
const installResult = await this.sshService.executeCommand(
'DEBIAN_FRONTEND=noninteractive apt install -y nginx'
);
if (!installResult.success) {
return {
service: 'nginx',
success: false,
message: `Failed to install Nginx: ${installResult.stderr}`,
};
}
// Enable and start Nginx
const enableResult = await this.sshService.executeCommand('systemctl enable nginx');
const startResult = await this.sshService.executeCommand('systemctl start nginx');
if (!enableResult.success || !startResult.success) {
return {
service: 'nginx',
success: false,
message: 'Failed to enable or start Nginx service',
};
}
// Configure firewall
await this.sshService.executeCommand('ufw allow "Nginx Full"');
return {
service: 'nginx',
success: true,
message: 'Nginx installed and configured successfully',
};
} catch (error) {
logger.error('Nginx installation failed', { error });
return {
service: 'nginx',
success: false,
message: `Nginx installation failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
};
}
}
private async installRedis(): Promise<VPSInitResult> {
logger.info('Installing Redis');
try {
const installResult = await this.sshService.executeCommand(
'DEBIAN_FRONTEND=noninteractive apt install -y redis-server'
);
if (!installResult.success) {
return {
service: 'redis',
success: false,
message: `Failed to install Redis: ${installResult.stderr}`,
};
}
// Configure Redis to start on boot
const enableResult = await this.sshService.executeCommand('systemctl enable redis-server');
const startResult = await this.sshService.executeCommand('systemctl start redis-server');
if (!enableResult.success || !startResult.success) {
return {
service: 'redis',
success: false,
message: 'Failed to enable or start Redis service',
};
}
// Test Redis connection
const testResult = await this.sshService.executeCommand('redis-cli ping');
if (!testResult.success || !testResult.stdout.includes('PONG')) {
return {
service: 'redis',
success: false,
message: 'Redis installation failed verification',
};
}
return {
service: 'redis',
success: true,
message: 'Redis installed and configured successfully',
};
} catch (error) {
logger.error('Redis installation failed', { error });
return {
service: 'redis',
success: false,
message: `Redis installation failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
};
}
}
}