fix(systemd): move Docker installation and swarm initialization to systemd enable flow
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## 2026-03-16 - 1.15.1 - fix(systemd)
|
||||
move Docker installation and swarm initialization to systemd enable flow
|
||||
|
||||
- Ensures Docker is installed before writing and enabling the systemd unit that depends on docker.service.
|
||||
- Removes Docker auto-installation from Onebox initialization so setup happens in the service management path.
|
||||
|
||||
## 2026-03-16 - 1.15.0 - feat(systemd)
|
||||
replace smartdaemon-based service management with native systemd commands
|
||||
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@serve.zone/onebox',
|
||||
version: '1.15.0',
|
||||
version: '1.15.1',
|
||||
description: 'Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers'
|
||||
}
|
||||
|
||||
@@ -100,9 +100,6 @@ export class Onebox {
|
||||
// Ensure default admin user exists
|
||||
await this.ensureDefaultUser();
|
||||
|
||||
// Ensure Docker is installed (auto-install on fresh servers)
|
||||
await this.ensureDocker();
|
||||
|
||||
// Initialize Docker
|
||||
await this.docker.init();
|
||||
|
||||
@@ -227,59 +224,6 @@ export class Onebox {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure Docker is installed, installing it if necessary
|
||||
*/
|
||||
private async ensureDocker(): Promise<void> {
|
||||
try {
|
||||
const cmd = new Deno.Command('docker', {
|
||||
args: ['--version'],
|
||||
stdout: 'piped',
|
||||
stderr: 'piped',
|
||||
});
|
||||
const result = await cmd.output();
|
||||
if (result.success) {
|
||||
const version = new TextDecoder().decode(result.stdout).trim();
|
||||
logger.info(`Docker found: ${version}`);
|
||||
return;
|
||||
}
|
||||
} catch {
|
||||
// docker command not found
|
||||
}
|
||||
|
||||
logger.info('Docker not found. Installing Docker...');
|
||||
const installCmd = new Deno.Command('bash', {
|
||||
args: ['-c', 'curl -fsSL https://get.docker.com | sh'],
|
||||
stdin: 'inherit',
|
||||
stdout: 'inherit',
|
||||
stderr: 'inherit',
|
||||
});
|
||||
const installResult = await installCmd.output();
|
||||
if (!installResult.success) {
|
||||
throw new Error('Failed to install Docker. Please install it manually: curl -fsSL https://get.docker.com | sh');
|
||||
}
|
||||
logger.success('Docker installed successfully');
|
||||
|
||||
// Initialize Docker Swarm
|
||||
logger.info('Initializing Docker Swarm...');
|
||||
const swarmCmd = new Deno.Command('docker', {
|
||||
args: ['swarm', 'init'],
|
||||
stdout: 'piped',
|
||||
stderr: 'piped',
|
||||
});
|
||||
const swarmResult = await swarmCmd.output();
|
||||
if (swarmResult.success) {
|
||||
logger.success('Docker Swarm initialized');
|
||||
} else {
|
||||
const stderr = new TextDecoder().decode(swarmResult.stderr);
|
||||
if (stderr.includes('already part of a swarm')) {
|
||||
logger.info('Docker Swarm already initialized');
|
||||
} else {
|
||||
logger.warn(`Docker Swarm init warning: ${stderr.trim()}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Onebox is initialized
|
||||
*/
|
||||
|
||||
@@ -36,6 +36,9 @@ export class OneboxSystemd {
|
||||
*/
|
||||
async enable(): Promise<void> {
|
||||
try {
|
||||
// Ensure Docker is installed before writing unit file (it requires docker.service)
|
||||
await this.ensureDocker();
|
||||
|
||||
// Write the unit file
|
||||
logger.info('Writing systemd unit file...');
|
||||
await Deno.writeTextFile(SERVICE_FILE_PATH, SERVICE_UNIT_TEMPLATE);
|
||||
@@ -163,6 +166,59 @@ export class OneboxSystemd {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure Docker is installed, installing it if necessary
|
||||
*/
|
||||
private async ensureDocker(): Promise<void> {
|
||||
try {
|
||||
const cmd = new Deno.Command('docker', {
|
||||
args: ['--version'],
|
||||
stdout: 'piped',
|
||||
stderr: 'piped',
|
||||
});
|
||||
const result = await cmd.output();
|
||||
if (result.success) {
|
||||
const version = new TextDecoder().decode(result.stdout).trim();
|
||||
logger.info(`Docker found: ${version}`);
|
||||
return;
|
||||
}
|
||||
} catch {
|
||||
// docker command not found
|
||||
}
|
||||
|
||||
logger.info('Docker not found. Installing Docker...');
|
||||
const installCmd = new Deno.Command('bash', {
|
||||
args: ['-c', 'curl -fsSL https://get.docker.com | sh'],
|
||||
stdin: 'inherit',
|
||||
stdout: 'inherit',
|
||||
stderr: 'inherit',
|
||||
});
|
||||
const installResult = await installCmd.output();
|
||||
if (!installResult.success) {
|
||||
throw new Error('Failed to install Docker. Please install it manually: curl -fsSL https://get.docker.com | sh');
|
||||
}
|
||||
logger.success('Docker installed successfully');
|
||||
|
||||
// Initialize Docker Swarm
|
||||
logger.info('Initializing Docker Swarm...');
|
||||
const swarmCmd = new Deno.Command('docker', {
|
||||
args: ['swarm', 'init'],
|
||||
stdout: 'piped',
|
||||
stderr: 'piped',
|
||||
});
|
||||
const swarmResult = await swarmCmd.output();
|
||||
if (swarmResult.success) {
|
||||
logger.success('Docker Swarm initialized');
|
||||
} else {
|
||||
const stderr = new TextDecoder().decode(swarmResult.stderr);
|
||||
if (stderr.includes('already part of a swarm')) {
|
||||
logger.info('Docker Swarm already initialized');
|
||||
} else {
|
||||
logger.warn(`Docker Swarm init warning: ${stderr.trim()}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a systemctl command and return results
|
||||
*/
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@serve.zone/onebox',
|
||||
version: '1.15.0',
|
||||
version: '1.15.1',
|
||||
description: 'Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user