feat(docker): add Docker context detection, rootless support, and context-aware buildx registry handling
This commit is contained in:
@@ -5,6 +5,7 @@ import { Dockerfile } from './classes.dockerfile.js';
|
||||
import { DockerRegistry } from './classes.dockerregistry.js';
|
||||
import { RegistryStorage } from './classes.registrystorage.js';
|
||||
import { TsDockerCache } from './classes.tsdockercache.js';
|
||||
import { DockerContext } from './classes.dockercontext.js';
|
||||
import type { ITsDockerConfig, IBuildCommandOptions } from './interfaces/index.js';
|
||||
|
||||
const smartshellInstance = new plugins.smartshell.Smartshell({
|
||||
@@ -18,17 +19,27 @@ export class TsDockerManager {
|
||||
public registryStorage: RegistryStorage;
|
||||
public config: ITsDockerConfig;
|
||||
public projectInfo: any;
|
||||
public dockerContext: DockerContext;
|
||||
private dockerfiles: Dockerfile[] = [];
|
||||
|
||||
constructor(config: ITsDockerConfig) {
|
||||
this.config = config;
|
||||
this.registryStorage = new RegistryStorage();
|
||||
this.dockerContext = new DockerContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the manager by loading project info and registries
|
||||
*/
|
||||
public async prepare(): Promise<void> {
|
||||
public async prepare(contextArg?: string): Promise<void> {
|
||||
// Detect Docker context
|
||||
if (contextArg) {
|
||||
this.dockerContext.setContext(contextArg);
|
||||
}
|
||||
await this.dockerContext.detect();
|
||||
this.dockerContext.logContextInfo();
|
||||
this.dockerContext.logRootlessWarnings();
|
||||
|
||||
// Load project info
|
||||
try {
|
||||
const projectinfoInstance = new plugins.projectinfo.ProjectInfo(paths.cwd);
|
||||
@@ -169,7 +180,7 @@ export class TsDockerManager {
|
||||
const useRegistry = Dockerfile.needsLocalRegistry(toBuild, options);
|
||||
|
||||
if (useRegistry) {
|
||||
await Dockerfile.startLocalRegistry();
|
||||
await Dockerfile.startLocalRegistry(this.dockerContext.contextInfo?.isRootless);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -225,6 +236,7 @@ export class TsDockerManager {
|
||||
timeout: options?.timeout,
|
||||
noCache: options?.noCache,
|
||||
verbose: options?.verbose,
|
||||
isRootless: this.dockerContext.contextInfo?.isRootless,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -254,30 +266,32 @@ export class TsDockerManager {
|
||||
* Ensures Docker buildx is set up for multi-architecture builds
|
||||
*/
|
||||
private async ensureBuildx(): Promise<void> {
|
||||
const builderName = this.dockerContext.getBuilderName();
|
||||
const platforms = this.config.platforms?.join(', ') || 'default';
|
||||
logger.log('info', `Setting up Docker buildx for multi-platform builds [${platforms}]...`);
|
||||
const inspectResult = await smartshellInstance.exec('docker buildx inspect tsdocker-builder 2>/dev/null');
|
||||
logger.log('info', `Setting up Docker buildx [${platforms}]...`);
|
||||
logger.log('info', `Builder: ${builderName}`);
|
||||
const inspectResult = await smartshellInstance.exec(`docker buildx inspect ${builderName} 2>/dev/null`);
|
||||
|
||||
if (inspectResult.exitCode !== 0) {
|
||||
logger.log('info', 'Creating new buildx builder with host network...');
|
||||
await smartshellInstance.exec(
|
||||
'docker buildx create --name tsdocker-builder --driver docker-container --driver-opt network=host --use'
|
||||
`docker buildx create --name ${builderName} --driver docker-container --driver-opt network=host --use`
|
||||
);
|
||||
await smartshellInstance.exec('docker buildx inspect --bootstrap');
|
||||
} else {
|
||||
const inspectOutput = inspectResult.stdout || '';
|
||||
if (!inspectOutput.includes('network=host')) {
|
||||
logger.log('info', 'Recreating buildx builder with host network (migration)...');
|
||||
await smartshellInstance.exec('docker buildx rm tsdocker-builder 2>/dev/null');
|
||||
await smartshellInstance.exec(`docker buildx rm ${builderName} 2>/dev/null`);
|
||||
await smartshellInstance.exec(
|
||||
'docker buildx create --name tsdocker-builder --driver docker-container --driver-opt network=host --use'
|
||||
`docker buildx create --name ${builderName} --driver docker-container --driver-opt network=host --use`
|
||||
);
|
||||
await smartshellInstance.exec('docker buildx inspect --bootstrap');
|
||||
} else {
|
||||
await smartshellInstance.exec('docker buildx use tsdocker-builder');
|
||||
await smartshellInstance.exec(`docker buildx use ${builderName}`);
|
||||
}
|
||||
}
|
||||
logger.log('ok', `Docker buildx ready (platforms: ${platforms})`);
|
||||
logger.log('ok', `Docker buildx ready (builder: ${builderName}, platforms: ${platforms})`);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user