Skip to content

Commit e47167e

Browse files
author
Manus AI
committed
feat: Add install-fleetbase command (merged with register command)
This commit adds the install-fleetbase command functionality on top of the dev-v0.0.4 branch which includes the register command. Both commands now coexist: - register: Register a new Registry Developer Account - install-fleetbase: Install Fleetbase using Docker The install command includes: - Interactive prompts for host, environment, and directory - Automatic APP_KEY generation - Docker compose configuration - Console environment file updates - Deployment automation
1 parent e5fa44a commit e47167e

1 file changed

Lines changed: 201 additions & 0 deletions

File tree

index.js

100755100644
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,199 @@ async function registerCommand(options) {
817817
}
818818
}
819819

820+
// Command to install Fleetbase via Docker
821+
async function installFleetbaseCommand(options) {
822+
const crypto = require('crypto');
823+
const os = require('os');
824+
825+
console.log('\n🚀 Fleetbase Installation\n');
826+
827+
try {
828+
// Collect installation parameters
829+
const answers = await prompt([
830+
{
831+
type: 'input',
832+
name: 'host',
833+
message: 'Enter host or IP address to bind to:',
834+
initial: options.host || 'localhost',
835+
validate: (value) => {
836+
if (!value) {
837+
return 'Host is required';
838+
}
839+
return true;
840+
}
841+
},
842+
{
843+
type: 'select',
844+
name: 'environment',
845+
message: 'Choose environment:',
846+
initial: options.environment === 'production' ? 1 : 0,
847+
choices: [
848+
{ title: 'Development', value: 'development' },
849+
{ title: 'Production', value: 'production' }
850+
]
851+
},
852+
{
853+
type: 'input',
854+
name: 'directory',
855+
message: 'Installation directory:',
856+
initial: options.directory || process.cwd(),
857+
validate: (value) => {
858+
if (!value) {
859+
return 'Directory is required';
860+
}
861+
return true;
862+
}
863+
}
864+
]);
865+
866+
const host = options.host || answers.host;
867+
const environment = options.environment || answers.environment;
868+
const directory = options.directory || answers.directory;
869+
870+
// Determine configuration based on environment
871+
const useHttps = environment === 'production';
872+
const appDebug = environment === 'development';
873+
const scSecure = environment === 'production';
874+
const schemeApi = useHttps ? 'https' : 'http';
875+
const schemeConsole = useHttps ? 'https' : 'http';
876+
877+
console.log(`\n📋 Configuration:`);
878+
console.log(` Host: ${host}`);
879+
console.log(` Environment: ${environment}`);
880+
console.log(` Directory: ${directory}`);
881+
console.log(` HTTPS: ${useHttps}`);
882+
883+
// Check if directory exists and has Fleetbase files
884+
if (!await fs.pathExists(directory)) {
885+
console.error(`\n✖ Directory does not exist: ${directory}`);
886+
console.log('\nℹ️ Please clone the Fleetbase repository first:');
887+
console.log(' git clone https://github.com/fleetbase/fleetbase.git');
888+
process.exit(1);
889+
}
890+
891+
const dockerComposePath = path.join(directory, 'docker-compose.yml');
892+
if (!await fs.pathExists(dockerComposePath)) {
893+
console.error(`\n✖ docker-compose.yml not found in ${directory}`);
894+
console.log('\nℹ️ Please ensure you are in the Fleetbase root directory.');
895+
process.exit(1);
896+
}
897+
898+
// Generate APP_KEY
899+
console.log('\n⏳ Generating APP_KEY...');
900+
const appKey = 'base64:' + crypto.randomBytes(32).toString('base64');
901+
console.log('✔ APP_KEY generated');
902+
903+
// Create docker-compose.override.yml
904+
console.log('⏳ Creating docker-compose.override.yml...');
905+
const overrideContent = `services:
906+
application:
907+
environment:
908+
APP_KEY: "${appKey}"
909+
CONSOLE_HOST: "${schemeConsole}://${host}:4200"
910+
ENVIRONMENT: "${environment}"
911+
APP_DEBUG: "${appDebug}"
912+
`;
913+
const overridePath = path.join(directory, 'docker-compose.override.yml');
914+
await fs.writeFile(overridePath, overrideContent);
915+
console.log('✔ docker-compose.override.yml created');
916+
917+
// Create console/fleetbase.config.json (for development runtime config)
918+
console.log('⏳ Creating console/fleetbase.config.json...');
919+
const configDir = path.join(directory, 'console');
920+
await fs.ensureDir(configDir);
921+
const configContent = {
922+
API_HOST: `${schemeApi}://${host}:8000`,
923+
SOCKETCLUSTER_HOST: host,
924+
SOCKETCLUSTER_PORT: '38000',
925+
SOCKETCLUSTER_SECURE: scSecure
926+
};
927+
const configPath = path.join(configDir, 'fleetbase.config.json');
928+
await fs.writeJson(configPath, configContent, { spaces: 2 });
929+
console.log('✔ console/fleetbase.config.json created');
930+
931+
// Update console environment files (.env.development and .env.production)
932+
console.log('⏳ Updating console environment files...');
933+
const environmentsDir = path.join(configDir, 'environments');
934+
935+
// Update .env.development
936+
const envDevelopmentContent = `API_HOST=http://${host}:8000
937+
API_NAMESPACE=int/v1
938+
SOCKETCLUSTER_PATH=/socketcluster/
939+
SOCKETCLUSTER_HOST=${host}
940+
SOCKETCLUSTER_SECURE=false
941+
SOCKETCLUSTER_PORT=38000
942+
OSRM_HOST=https://router.project-osrm.org
943+
`;
944+
const envDevelopmentPath = path.join(environmentsDir, '.env.development');
945+
await fs.writeFile(envDevelopmentPath, envDevelopmentContent);
946+
947+
// Update .env.production
948+
const envProductionContent = `API_HOST=https://${host}:8000
949+
API_NAMESPACE=int/v1
950+
API_SECURE=true
951+
SOCKETCLUSTER_PATH=/socketcluster/
952+
SOCKETCLUSTER_HOST=${host}
953+
SOCKETCLUSTER_SECURE=true
954+
SOCKETCLUSTER_PORT=38000
955+
OSRM_HOST=https://router.project-osrm.org
956+
`;
957+
const envProductionPath = path.join(environmentsDir, '.env.production');
958+
await fs.writeFile(envProductionPath, envProductionContent);
959+
960+
console.log('✔ Console environment files updated');
961+
962+
// Start Docker containers
963+
console.log('\n⏳ Starting Fleetbase containers...');
964+
console.log(' This may take a few minutes on first run...\n');
965+
966+
exec('docker compose up -d', { cwd: directory, maxBuffer: maxBuffer }, async (error, stdout, stderr) => {
967+
if (error) {
968+
console.error(`\n✖ Error starting containers: ${error.message}`);
969+
if (stderr) console.error(stderr);
970+
process.exit(1);
971+
}
972+
973+
console.log(stdout);
974+
console.log('✔ Containers started');
975+
976+
// Wait for database
977+
console.log('\n⏳ Waiting for database to be ready...');
978+
await new Promise(resolve => setTimeout(resolve, 15000)); // Wait 15 seconds
979+
console.log('✔ Database should be ready');
980+
981+
// Run deploy script
982+
console.log('\n⏳ Running deployment script...');
983+
exec('docker compose exec -T application bash -c "./deploy.sh"', { cwd: directory, maxBuffer: maxBuffer }, (deployError, deployStdout, deployStderr) => {
984+
if (deployError) {
985+
console.error(`\n✖ Error during deployment: ${deployError.message}`);
986+
if (deployStderr) console.error(deployStderr);
987+
console.log('\nℹ️ You may need to run the deployment manually:');
988+
console.log(' docker compose exec application bash -c "./deploy.sh"');
989+
} else {
990+
console.log(deployStdout);
991+
console.log('✔ Deployment complete');
992+
}
993+
994+
// Restart containers to ensure all changes are applied
995+
exec('docker compose up -d', { cwd: directory }, () => {
996+
console.log('\n🏁 Fleetbase is up!');
997+
console.log(` API → ${schemeApi}://${host}:8000`);
998+
console.log(` Console → ${schemeConsole}://${host}:4200\n`);
999+
console.log('ℹ️ Default credentials:');
1000+
console.log(' Email: admin@fleetbase.io');
1001+
console.log(' Password: password\n');
1002+
});
1003+
});
1004+
});
1005+
} catch (error) {
1006+
console.error('\n✖ Installation failed:', error.message);
1007+
process.exit(1);
1008+
}
1009+
}
1010+
1011+
1012+
8201013
function loginCommand (options) {
8211014
const npmLogin = require('npm-cli-login');
8221015
const username = options.username;
@@ -979,6 +1172,14 @@ program
9791172
.option('-n, --name <name>', 'Your full name (optional)')
9801173
.action(registerCommand);
9811174

1175+
program
1176+
.command('install-fleetbase')
1177+
.description('Install Fleetbase using Docker')
1178+
.option('--host <host>', 'Host or IP address to bind to (default: localhost)')
1179+
.option('--environment <environment>', 'Environment: development or production (default: development)')
1180+
.option('--directory <directory>', 'Installation directory (default: current directory)')
1181+
.action(installFleetbaseCommand);
1182+
9821183
program
9831184
.command('login')
9841185
.description('Log in to the Fleetbase registry')

0 commit comments

Comments
 (0)