4.7 KiB
Docker Module - Development Hints
OOP Refactoring - Clean Architecture (2025-11-24)
Architecture Changes
The module has been restructured to follow a clean OOP Facade pattern:
- DockerHost is now the single entry point for all Docker operations
- All resource classes extend abstract
DockerResourcebase class - Static methods are prefixed with
_to indicate internal use - Public API is exclusively through DockerHost methods
Key Changes
1. Factory Pattern
- All resource creation/retrieval goes through DockerHost:
// Old (deprecated): const container = await DockerContainer.getContainers(dockerHost); const network = await DockerNetwork.createNetwork(dockerHost, descriptor); // New (clean API): const containers = await dockerHost.getContainers(); const network = await dockerHost.createNetwork(descriptor);
2. Container Management Methods Added The DockerContainer class now has full CRUD and streaming operations:
Lifecycle:
container.start()- Start containercontainer.stop(options?)- Stop containercontainer.remove(options?)- Remove containercontainer.refresh()- Reload state
Information:
container.inspect()- Get detailed infocontainer.logs(options)- Get logs as string (one-shot)container.stats(options)- Get stats
Streaming & Interactive:
container.streamLogs(options)- Stream logs continuously (follow mode)container.attach(options)- Attach to main process (PID 1) with bidirectional streamcontainer.exec(command, options)- Execute commands in container interactively
Example - Stream Logs:
const container = await dockerHost.getContainerById('abc123');
const logStream = await container.streamLogs({ timestamps: true });
logStream.on('data', (chunk) => {
console.log(chunk.toString());
});
Example - Attach to Container:
const { stream, close } = await container.attach({
stdin: true,
stdout: true,
stderr: true
});
// Pipe to/from process
process.stdin.pipe(stream);
stream.pipe(process.stdout);
// Later: detach
await close();
Example - Execute Command:
const { stream, close } = await container.exec('ls -la /app', {
tty: true
});
stream.on('data', (chunk) => {
console.log(chunk.toString());
});
stream.on('end', async () => {
await close();
});
3. DockerResource Base Class
All resource classes now extend DockerResource:
- Consistent
dockerHostproperty (notdockerHostRef) - Required
refresh()method - Standardized constructor pattern
4. ImageStore Encapsulation
dockerHost.imageStoreis now private- Use
dockerHost.storeImage(name, stream)instead - Use
dockerHost.retrieveImage(name)instead
5. Creation Descriptors Support Both Primitives and Instances Interfaces now accept both strings and class instances:
// Both work:
await dockerHost.createService({
image: 'nginx:latest', // String
networks: ['my-network'], // String array
secrets: ['my-secret'] // String array
});
await dockerHost.createService({
image: imageInstance, // DockerImage instance
networks: [networkInstance], // DockerNetwork array
secrets: [secretInstance] // DockerSecret array
});
Migration Guide
Replace all static method calls with dockerHost methods:
DockerContainer.getContainers(host)→dockerHost.getContainers()DockerImage.createFromRegistry(host, opts)→dockerHost.createImageFromRegistry(opts)DockerService.createService(host, desc)→dockerHost.createService(desc)dockerHost.imageStore.storeImage(...)→dockerHost.storeImage(...)
smartrequest v5+ Migration (2025-11-17)
Breaking Change
smartrequest v5.0.0+ returns web ReadableStream objects (Web Streams API) instead of Node.js streams.
Solution Implemented
All streaming methods now convert web ReadableStreams to Node.js streams using:
plugins.smartstream.nodewebhelpers.convertWebReadableToNodeReadable(webStream)
Files Modified
-
ts/classes.host.ts:requestStreaming()- Converts web stream to Node.js stream before returninggetEventObservable()- Works with converted Node.js stream
-
ts/classes.image.ts:createFromTarStream()- Uses converted Node.js stream for event handlingexportToTarStream()- Uses converted Node.js stream for backpressure management
Testing
- Build: All 11 type errors resolved
- Tests: Node.js tests pass (DockerHost, DockerContainer, DockerImage, DockerImageStore)
Notes
- The conversion maintains backward compatibility with existing code expecting Node.js stream methods (
.on(),.emit(),.pause(),.resume()) - smartstream's
nodewebhelpersmodule provides bidirectional conversion utilities between web and Node.js streams