Skip to content

Commit 9a9c1a6

Browse files
author
Manus AI
committed
feat: Add install-fleetbase command
This commit adds a new 'install-fleetbase' command to the CLI that automates the Fleetbase Docker installation process. ## Features - Interactive prompts for host, environment, and directory - Command-line options for non-interactive usage - Automatic APP_KEY generation using crypto - Creates docker-compose.override.yml with environment configuration - Creates console/fleetbase.config.json with API and SocketCluster settings - Starts Docker containers and waits for database readiness - Runs deployment script automatically - Provides clear status messages and error handling ## Usage Interactive mode: flb install-fleetbase Non-interactive mode: flb install-fleetbase --host localhost --environment development --directory ./fleetbase ## Options --host <host> Host or IP address to bind to (default: localhost) --environment <env> Environment: development or production (default: development) --directory <directory> Installation directory (default: current directory) ## Implementation The command replicates the functionality of scripts/docker-install.sh but provides a better user experience through: - Interactive prompts with validation - Clear progress indicators - Better error messages - Cross-platform compatibility (Node.js vs Bash) - Integration with the CLI ecosystem ## Benefits - Easier onboarding for new users - Consistent installation experience - No need to navigate to scripts directory - Better error handling and validation - Works on Windows, macOS, and Linux
1 parent 1afcb97 commit 9a9c1a6

1 file changed

Lines changed: 168 additions & 1 deletion

File tree

index.js

Lines changed: 168 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,166 @@ async function versionBump (options) {
721721
}
722722
}
723723

724-
// Command to handle login
724+
// Command to install Fleetbase via Docker
725+
async function installFleetbaseCommand(options) {
726+
const crypto = require('crypto');
727+
const os = require('os');
728+
729+
console.log('\n🚀 Fleetbase Installation\n');
730+
731+
try {
732+
// Collect installation parameters
733+
const answers = await prompt([
734+
{
735+
type: 'input',
736+
name: 'host',
737+
message: 'Enter host or IP address to bind to:',
738+
initial: options.host || 'localhost',
739+
validate: (value) => {
740+
if (!value) {
741+
return 'Host is required';
742+
}
743+
return true;
744+
}
745+
},
746+
{
747+
type: 'select',
748+
name: 'environment',
749+
message: 'Choose environment:',
750+
initial: options.environment === 'production' ? 1 : 0,
751+
choices: [
752+
{ title: 'Development', value: 'development' },
753+
{ title: 'Production', value: 'production' }
754+
]
755+
},
756+
{
757+
type: 'input',
758+
name: 'directory',
759+
message: 'Installation directory:',
760+
initial: options.directory || process.cwd(),
761+
validate: (value) => {
762+
if (!value) {
763+
return 'Directory is required';
764+
}
765+
return true;
766+
}
767+
}
768+
]);
769+
770+
const host = options.host || answers.host;
771+
const environment = options.environment || answers.environment;
772+
const directory = options.directory || answers.directory;
773+
774+
// Determine configuration based on environment
775+
const useHttps = environment === 'production';
776+
const appDebug = environment === 'development';
777+
const scSecure = environment === 'production';
778+
const schemeApi = useHttps ? 'https' : 'http';
779+
const schemeConsole = useHttps ? 'https' : 'http';
780+
781+
console.log(`\n📋 Configuration:`);
782+
console.log(` Host: ${host}`);
783+
console.log(` Environment: ${environment}`);
784+
console.log(` Directory: ${directory}`);
785+
console.log(` HTTPS: ${useHttps}`);
786+
787+
// Check if directory exists and has Fleetbase files
788+
if (!await fs.pathExists(directory)) {
789+
console.error(`\n✖ Directory does not exist: ${directory}`);
790+
console.log('\nℹ️ Please clone the Fleetbase repository first:');
791+
console.log(' git clone https://github.com/fleetbase/fleetbase.git');
792+
process.exit(1);
793+
}
794+
795+
const dockerComposePath = path.join(directory, 'docker-compose.yml');
796+
if (!await fs.pathExists(dockerComposePath)) {
797+
console.error(`\n✖ docker-compose.yml not found in ${directory}`);
798+
console.log('\nℹ️ Please ensure you are in the Fleetbase root directory.');
799+
process.exit(1);
800+
}
801+
802+
// Generate APP_KEY
803+
console.log('\n⏳ Generating APP_KEY...');
804+
const appKey = 'base64:' + crypto.randomBytes(32).toString('base64');
805+
console.log('✔ APP_KEY generated');
806+
807+
// Create docker-compose.override.yml
808+
console.log('⏳ Creating docker-compose.override.yml...');
809+
const overrideContent = `services:
810+
application:
811+
environment:
812+
APP_KEY: "${appKey}"
813+
CONSOLE_HOST: "${schemeConsole}://${host}:4200"
814+
ENVIRONMENT: "${environment}"
815+
APP_DEBUG: "${appDebug}"
816+
`;
817+
const overridePath = path.join(directory, 'docker-compose.override.yml');
818+
await fs.writeFile(overridePath, overrideContent);
819+
console.log('✔ docker-compose.override.yml created');
820+
821+
// Create console/fleetbase.config.json
822+
console.log('⏳ Creating console/fleetbase.config.json...');
823+
const configDir = path.join(directory, 'console');
824+
await fs.ensureDir(configDir);
825+
const configContent = {
826+
API_HOST: `${schemeApi}://${host}:8000`,
827+
SOCKETCLUSTER_HOST: host,
828+
SOCKETCLUSTER_PORT: '38000',
829+
SOCKETCLUSTER_SECURE: scSecure
830+
};
831+
const configPath = path.join(configDir, 'fleetbase.config.json');
832+
await fs.writeJson(configPath, configContent, { spaces: 2 });
833+
console.log('✔ console/fleetbase.config.json created');
834+
835+
// Start Docker containers
836+
console.log('\n⏳ Starting Fleetbase containers...');
837+
console.log(' This may take a few minutes on first run...\n');
838+
839+
exec('docker compose up -d', { cwd: directory, maxBuffer: maxBuffer }, async (error, stdout, stderr) => {
840+
if (error) {
841+
console.error(`\n✖ Error starting containers: ${error.message}`);
842+
if (stderr) console.error(stderr);
843+
process.exit(1);
844+
}
845+
846+
console.log(stdout);
847+
console.log('✔ Containers started');
848+
849+
// Wait for database
850+
console.log('\n⏳ Waiting for database to be ready...');
851+
await new Promise(resolve => setTimeout(resolve, 15000)); // Wait 15 seconds
852+
console.log('✔ Database should be ready');
853+
854+
// Run deploy script
855+
console.log('\n⏳ Running deployment script...');
856+
exec('docker compose exec -T application bash -c "./deploy.sh"', { cwd: directory, maxBuffer: maxBuffer }, (deployError, deployStdout, deployStderr) => {
857+
if (deployError) {
858+
console.error(`\n✖ Error during deployment: ${deployError.message}`);
859+
if (deployStderr) console.error(deployStderr);
860+
console.log('\nℹ️ You may need to run the deployment manually:');
861+
console.log(' docker compose exec application bash -c "./deploy.sh"');
862+
} else {
863+
console.log(deployStdout);
864+
console.log('✔ Deployment complete');
865+
}
866+
867+
// Restart containers to ensure all changes are applied
868+
exec('docker compose up -d', { cwd: directory }, () => {
869+
console.log('\n🏁 Fleetbase is up!');
870+
console.log(` API → ${schemeApi}://${host}:8000`);
871+
console.log(` Console → ${schemeConsole}://${host}:4200\n`);
872+
console.log('ℹ️ Default credentials:');
873+
console.log(' Email: admin@fleetbase.io');
874+
console.log(' Password: password\n');
875+
});
876+
});
877+
});
878+
} catch (error) {
879+
console.error('\n✖ Installation failed:', error.message);
880+
process.exit(1);
881+
}
882+
}
883+
725884
function loginCommand (options) {
726885
const npmLogin = require('npm-cli-login');
727886
const username = options.username;
@@ -875,6 +1034,14 @@ program
8751034
.option('--pre-release [identifier]', 'Add pre-release identifier')
8761035
.action(versionBump);
8771036

1037+
program
1038+
.command('install-fleetbase')
1039+
.description('Install Fleetbase using Docker')
1040+
.option('--host <host>', 'Host or IP address to bind to (default: localhost)')
1041+
.option('--environment <environment>', 'Environment: development or production (default: development)')
1042+
.option('--directory <directory>', 'Installation directory (default: current directory)')
1043+
.action(installFleetbaseCommand);
1044+
8781045
program
8791046
.command('login')
8801047
.description('Log in to the Fleetbase registry')

0 commit comments

Comments
 (0)