feat(services): Add Docker port mapping sync and reconfigure workflow for local services
This commit is contained in:
@@ -26,6 +26,9 @@ export class ServiceManager {
|
||||
// Load or create configuration
|
||||
await this.config.loadOrCreate();
|
||||
logger.log('info', `📋 Project: ${this.config.getConfig().PROJECT_NAME}`);
|
||||
|
||||
// Validate and update ports if needed
|
||||
await this.config.validateAndUpdatePorts();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,10 +52,42 @@ export class ServiceManager {
|
||||
break;
|
||||
|
||||
case 'stopped':
|
||||
if (await this.docker.start(containers.mongo)) {
|
||||
logger.log('ok', ' Started ✓');
|
||||
// Check if port mapping matches config
|
||||
const mongoPortMappings = await this.docker.getPortMappings(containers.mongo);
|
||||
if (mongoPortMappings && mongoPortMappings['27017'] !== config.MONGODB_PORT) {
|
||||
logger.log('note', ' Port configuration changed, recreating container...');
|
||||
await this.docker.remove(containers.mongo, true);
|
||||
// Fall through to create new container
|
||||
const success = await this.docker.run({
|
||||
name: containers.mongo,
|
||||
image: 'mongo:7.0',
|
||||
ports: {
|
||||
[`0.0.0.0:${config.MONGODB_PORT}`]: '27017'
|
||||
},
|
||||
volumes: {
|
||||
[directories.mongo]: '/data/db'
|
||||
},
|
||||
environment: {
|
||||
MONGO_INITDB_ROOT_USERNAME: config.MONGODB_USER,
|
||||
MONGO_INITDB_ROOT_PASSWORD: config.MONGODB_PASS,
|
||||
MONGO_INITDB_DATABASE: config.MONGODB_NAME
|
||||
},
|
||||
restart: 'unless-stopped',
|
||||
command: '--bind_ip_all'
|
||||
});
|
||||
|
||||
if (success) {
|
||||
logger.log('ok', ' Recreated with new port ✓');
|
||||
} else {
|
||||
logger.log('error', ' Failed to recreate container');
|
||||
}
|
||||
} else {
|
||||
logger.log('error', ' Failed to start');
|
||||
// Ports match, just start the container
|
||||
if (await this.docker.start(containers.mongo)) {
|
||||
logger.log('ok', ' Started ✓');
|
||||
} else {
|
||||
logger.log('error', ' Failed to start');
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -116,10 +151,60 @@ export class ServiceManager {
|
||||
break;
|
||||
|
||||
case 'stopped':
|
||||
if (await this.docker.start(containers.minio)) {
|
||||
logger.log('ok', ' Started ✓');
|
||||
// Check if port mapping matches config
|
||||
const minioPortMappings = await this.docker.getPortMappings(containers.minio);
|
||||
if (minioPortMappings &&
|
||||
(minioPortMappings['9000'] !== config.S3_PORT ||
|
||||
minioPortMappings['9001'] !== config.S3_CONSOLE_PORT)) {
|
||||
logger.log('note', ' Port configuration changed, recreating container...');
|
||||
await this.docker.remove(containers.minio, true);
|
||||
// Fall through to create new container
|
||||
const success = await this.docker.run({
|
||||
name: containers.minio,
|
||||
image: 'minio/minio',
|
||||
ports: {
|
||||
[config.S3_PORT]: '9000',
|
||||
[config.S3_CONSOLE_PORT]: '9001'
|
||||
},
|
||||
volumes: {
|
||||
[directories.minio]: '/data'
|
||||
},
|
||||
environment: {
|
||||
MINIO_ROOT_USER: config.S3_ACCESSKEY,
|
||||
MINIO_ROOT_PASSWORD: config.S3_SECRETKEY
|
||||
},
|
||||
restart: 'unless-stopped',
|
||||
command: 'server /data --console-address ":9001"'
|
||||
});
|
||||
|
||||
if (success) {
|
||||
logger.log('ok', ' Recreated with new ports ✓');
|
||||
|
||||
// Wait for MinIO to be ready
|
||||
await plugins.smartdelay.delayFor(3000);
|
||||
|
||||
// Create default bucket
|
||||
await this.docker.exec(
|
||||
containers.minio,
|
||||
`mc alias set local http://localhost:9000 ${config.S3_ACCESSKEY} ${config.S3_SECRETKEY}`
|
||||
);
|
||||
|
||||
await this.docker.exec(
|
||||
containers.minio,
|
||||
`mc mb local/${config.S3_BUCKET}`
|
||||
);
|
||||
|
||||
logger.log('ok', ` Bucket '${config.S3_BUCKET}' created ✓`);
|
||||
} else {
|
||||
logger.log('error', ' Failed to recreate container');
|
||||
}
|
||||
} else {
|
||||
logger.log('error', ' Failed to start');
|
||||
// Ports match, just start the container
|
||||
if (await this.docker.start(containers.minio)) {
|
||||
logger.log('ok', ' Started ✓');
|
||||
} else {
|
||||
logger.log('error', ' Failed to start');
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -233,6 +318,7 @@ export class ServiceManager {
|
||||
case 'running':
|
||||
logger.log('ok', '📦 MongoDB: 🟢 Running');
|
||||
logger.log('info', ` ├─ Container: ${containers.mongo}`);
|
||||
logger.log('info', ` ├─ Port: ${config.MONGODB_PORT}`);
|
||||
logger.log('info', ` ├─ Connection: ${this.config.getMongoConnectionString()}`);
|
||||
|
||||
// Show Compass connection string
|
||||
@@ -242,10 +328,19 @@ export class ServiceManager {
|
||||
break;
|
||||
case 'stopped':
|
||||
logger.log('note', '📦 MongoDB: 🟡 Stopped');
|
||||
logger.log('info', ` └─ Container: ${containers.mongo}`);
|
||||
logger.log('info', ` ├─ Container: ${containers.mongo}`);
|
||||
logger.log('info', ` └─ Port: ${config.MONGODB_PORT}`);
|
||||
break;
|
||||
case 'not_exists':
|
||||
logger.log('info', '📦 MongoDB: ⚪ Not installed');
|
||||
// Check port availability
|
||||
const mongoPort = parseInt(config.MONGODB_PORT);
|
||||
const mongoAvailable = await helpers.isPortAvailable(mongoPort);
|
||||
if (!mongoAvailable) {
|
||||
logger.log('error', ` └─ ⚠️ Port ${mongoPort} is in use by another process`);
|
||||
} else {
|
||||
logger.log('info', ` └─ Port ${mongoPort} is available`);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -261,10 +356,33 @@ export class ServiceManager {
|
||||
break;
|
||||
case 'stopped':
|
||||
logger.log('note', '📦 S3/MinIO: 🟡 Stopped');
|
||||
logger.log('info', ` └─ Container: ${containers.minio}`);
|
||||
logger.log('info', ` ├─ Container: ${containers.minio}`);
|
||||
logger.log('info', ` ├─ API Port: ${config.S3_PORT}`);
|
||||
logger.log('info', ` └─ Console Port: ${config.S3_CONSOLE_PORT}`);
|
||||
break;
|
||||
case 'not_exists':
|
||||
logger.log('info', '📦 S3/MinIO: ⚪ Not installed');
|
||||
// Check port availability
|
||||
const s3Port = parseInt(config.S3_PORT);
|
||||
const s3ConsolePort = parseInt(config.S3_CONSOLE_PORT);
|
||||
const s3Available = await helpers.isPortAvailable(s3Port);
|
||||
const consoleAvailable = await helpers.isPortAvailable(s3ConsolePort);
|
||||
|
||||
if (!s3Available || !consoleAvailable) {
|
||||
if (!s3Available) {
|
||||
logger.log('error', ` ├─ ⚠️ API Port ${s3Port} is in use`);
|
||||
} else {
|
||||
logger.log('info', ` ├─ API Port ${s3Port} is available`);
|
||||
}
|
||||
if (!consoleAvailable) {
|
||||
logger.log('error', ` └─ ⚠️ Console Port ${s3ConsolePort} is in use`);
|
||||
} else {
|
||||
logger.log('info', ` └─ Console Port ${s3ConsolePort} is available`);
|
||||
}
|
||||
} else {
|
||||
logger.log('info', ` ├─ API Port ${s3Port} is available`);
|
||||
logger.log('info', ` └─ Console Port ${s3ConsolePort} is available`);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -422,4 +540,44 @@ export class ServiceManager {
|
||||
logger.log('note', ' No data to clean');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconfigure services with new ports
|
||||
*/
|
||||
public async reconfigure(): Promise<void> {
|
||||
helpers.printHeader('Reconfiguring Services');
|
||||
|
||||
const containers = this.config.getContainerNames();
|
||||
|
||||
// Stop existing containers
|
||||
logger.log('note', '🛑 Stopping existing containers...');
|
||||
|
||||
if (await this.docker.exists(containers.mongo)) {
|
||||
await this.docker.stop(containers.mongo);
|
||||
logger.log('ok', ' MongoDB stopped ✓');
|
||||
}
|
||||
|
||||
if (await this.docker.exists(containers.minio)) {
|
||||
await this.docker.stop(containers.minio);
|
||||
logger.log('ok', ' S3/MinIO stopped ✓');
|
||||
}
|
||||
|
||||
// Reconfigure ports
|
||||
await this.config.reconfigurePorts();
|
||||
|
||||
// Ask if user wants to restart services
|
||||
const smartinteract = new plugins.smartinteract.SmartInteract();
|
||||
const response = await smartinteract.askQuestion({
|
||||
name: 'restart',
|
||||
type: 'confirm',
|
||||
message: 'Do you want to start services with new ports?',
|
||||
default: true
|
||||
});
|
||||
|
||||
if (response.value) {
|
||||
console.log();
|
||||
await this.startMongoDB();
|
||||
await this.startMinIO();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user