749 lines
20 KiB
Markdown
749 lines
20 KiB
Markdown
# @apiclient.xyz/docker 🐳
|
|
|
|
> **Powerful TypeScript client for Docker Remote API** - Build, manage, and orchestrate Docker containers, images, networks, and swarm services with type-safe elegance.
|
|
|
|
## 🚀 Features
|
|
|
|
- 🎯 **Full TypeScript Support** - Complete type definitions for all Docker API entities
|
|
- 🔄 **Async/Await Ready** - Modern promise-based architecture for seamless async operations
|
|
- 📦 **Container Management** - Create, list, inspect, and manage containers effortlessly
|
|
- 🖼️ **Image Handling** - Pull from registries, build from tarballs, export, and manage tags
|
|
- 🌐 **Network Operations** - Create and manage Docker networks with full IPAM support
|
|
- 🔐 **Secrets Management** - Handle Docker secrets securely in swarm mode
|
|
- 🎭 **Service Orchestration** - Deploy and manage services in Docker Swarm
|
|
- 💾 **S3 Image Storage** - Built-in support for storing/retrieving images from S3-compatible storage
|
|
- 📊 **Event Streaming** - Real-time Docker event monitoring with RxJS observables
|
|
- 🔧 **Registry Authentication** - Seamless authentication with Docker registries including private registries
|
|
- 🐝 **Swarm Mode** - Full support for Docker Swarm initialization and management
|
|
|
|
## 📦 Installation
|
|
|
|
```bash
|
|
# Using pnpm (recommended)
|
|
pnpm add @apiclient.xyz/docker
|
|
|
|
# Using npm
|
|
npm install @apiclient.xyz/docker --save
|
|
|
|
# Using yarn
|
|
yarn add @apiclient.xyz/docker
|
|
```
|
|
|
|
## 🎯 Quick Start
|
|
|
|
```typescript
|
|
import { DockerHost } from '@apiclient.xyz/docker';
|
|
|
|
// Connect to local Docker daemon (default: /var/run/docker.sock)
|
|
const docker = new DockerHost({});
|
|
await docker.start();
|
|
|
|
// Check if Docker is accessible
|
|
await docker.ping();
|
|
console.log('✅ Docker is running');
|
|
|
|
// List all containers
|
|
const containers = await docker.getContainers();
|
|
console.log(`Found ${containers.length} containers`);
|
|
|
|
// Don't forget to clean up
|
|
await docker.stop();
|
|
```
|
|
|
|
## 🔌 Socket Path Configuration
|
|
|
|
The library determines which Docker socket to use in the following priority order:
|
|
|
|
1. **Constructor option** - `socketPath` parameter (highest priority)
|
|
2. **Environment variable** - `DOCKER_HOST` environment variable
|
|
3. **CI environment** - If `CI` env var is set, uses `http://docker:2375/`
|
|
4. **Default** - Falls back to `http://unix:/var/run/docker.sock:`
|
|
|
|
```typescript
|
|
// Explicit socket path (highest priority)
|
|
const docker1 = new DockerHost({
|
|
socketPath: 'tcp://remote-host:2375',
|
|
});
|
|
|
|
// Uses DOCKER_HOST environment variable if set
|
|
const docker2 = new DockerHost({});
|
|
|
|
// Custom image store directory
|
|
const docker3 = new DockerHost({
|
|
imageStoreDir: '/custom/path/to/image-store',
|
|
});
|
|
```
|
|
|
|
## 📚 Complete API Guide
|
|
|
|
### 🐳 DockerHost - Your Gateway to Docker
|
|
|
|
The `DockerHost` class is your primary interface to interact with the Docker daemon.
|
|
|
|
```typescript
|
|
import { DockerHost } from '@apiclient.xyz/docker';
|
|
|
|
// Initialize with options
|
|
const docker = new DockerHost({
|
|
socketPath: '/var/run/docker.sock', // Optional: custom socket path
|
|
imageStoreDir: './docker-images', // Optional: custom image store location
|
|
});
|
|
|
|
// Start the docker host (initializes image store)
|
|
await docker.start();
|
|
|
|
// ... perform operations ...
|
|
|
|
// Stop and clean up
|
|
await docker.stop();
|
|
```
|
|
|
|
#### Health Check / Ping Docker
|
|
|
|
Check if the Docker daemon is running and accessible:
|
|
|
|
```typescript
|
|
// Ping Docker daemon
|
|
try {
|
|
await docker.ping();
|
|
console.log('✅ Docker is running and accessible');
|
|
} catch (error) {
|
|
console.error('❌ Docker is not accessible:', error.message);
|
|
}
|
|
|
|
// Use in health check function
|
|
async function isDockerHealthy(): Promise<boolean> {
|
|
try {
|
|
await docker.ping();
|
|
return true;
|
|
} catch (error) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Example: Wait for Docker to be ready
|
|
async function waitForDocker(timeoutMs = 10000): Promise<void> {
|
|
const startTime = Date.now();
|
|
|
|
while (Date.now() - startTime < timeoutMs) {
|
|
try {
|
|
await docker.ping();
|
|
console.log('✅ Docker is ready');
|
|
return;
|
|
} catch (error) {
|
|
console.log('⏳ Waiting for Docker...');
|
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
}
|
|
}
|
|
|
|
throw new Error('Docker did not become available within timeout');
|
|
}
|
|
```
|
|
|
|
### 📦 Container Management
|
|
|
|
#### List All Containers
|
|
|
|
```typescript
|
|
// Get all containers (running and stopped)
|
|
const containers = await docker.getContainers();
|
|
|
|
containers.forEach((container) => {
|
|
console.log(`Container: ${container.Names[0]}`);
|
|
console.log(` ID: ${container.Id}`);
|
|
console.log(` Status: ${container.Status}`);
|
|
console.log(` Image: ${container.Image}`);
|
|
console.log(` State: ${container.State}`);
|
|
});
|
|
```
|
|
|
|
#### Get Container by ID
|
|
|
|
```typescript
|
|
import { DockerContainer } from '@apiclient.xyz/docker';
|
|
|
|
const container = await DockerContainer.getContainerById(docker, 'abc123');
|
|
if (container) {
|
|
console.log(`Found: ${container.Names[0]}`);
|
|
console.log(`Running: ${container.State === 'running'}`);
|
|
}
|
|
```
|
|
|
|
### 🖼️ Image Management
|
|
|
|
#### Pull Images from Registry
|
|
|
|
```typescript
|
|
import { DockerImage } from '@apiclient.xyz/docker';
|
|
|
|
// Pull from Docker Hub
|
|
const image = await DockerImage.createFromRegistry(docker, {
|
|
creationObject: {
|
|
imageUrl: 'nginx',
|
|
imageTag: 'alpine', // Optional, defaults to 'latest'
|
|
},
|
|
});
|
|
|
|
console.log(`Image pulled: ${image.RepoTags[0]}`);
|
|
console.log(`Size: ${(image.Size / 1024 / 1024).toFixed(2)} MB`);
|
|
|
|
// Pull from private registry
|
|
const privateImage = await DockerImage.createFromRegistry(docker, {
|
|
creationObject: {
|
|
imageUrl: 'registry.example.com/my-app',
|
|
imageTag: 'v2.0.0',
|
|
},
|
|
});
|
|
```
|
|
|
|
#### Import Images from Tar Stream
|
|
|
|
```typescript
|
|
import * as fs from 'fs';
|
|
import { DockerImage } from '@apiclient.xyz/docker';
|
|
|
|
// Import from a tar file
|
|
const tarStream = fs.createReadStream('./my-image.tar');
|
|
const importedImage = await DockerImage.createFromTarStream(docker, {
|
|
tarStream,
|
|
creationObject: {
|
|
imageUrl: 'my-app',
|
|
imageTag: 'v1.0.0',
|
|
},
|
|
});
|
|
|
|
console.log(`Imported: ${importedImage.RepoTags[0]}`);
|
|
```
|
|
|
|
#### Export Images to Tar Stream
|
|
|
|
```typescript
|
|
// Get image by name
|
|
const image = await DockerImage.getImageByName(docker, 'nginx:alpine');
|
|
|
|
// Export to tar stream
|
|
const exportStream = await image.exportToTarStream();
|
|
|
|
// Save to file
|
|
const writeStream = fs.createWriteStream('./nginx-export.tar');
|
|
exportStream.pipe(writeStream);
|
|
|
|
writeStream.on('finish', () => {
|
|
console.log('Image exported successfully');
|
|
});
|
|
```
|
|
|
|
#### Tag Images
|
|
|
|
```typescript
|
|
// Tag an existing image
|
|
await DockerImage.tagImageByIdOrName(docker, 'nginx:alpine', {
|
|
registry: 'myregistry.com',
|
|
imageName: 'web-server',
|
|
imageTag: 'v1.0.0',
|
|
});
|
|
// Result: myregistry.com/web-server:v1.0.0
|
|
```
|
|
|
|
#### List All Images
|
|
|
|
```typescript
|
|
const images = await docker.getImages();
|
|
|
|
images.forEach((img) => {
|
|
console.log(`Image: ${img.RepoTags ? img.RepoTags.join(', ') : '<none>'}`);
|
|
console.log(` ID: ${img.Id}`);
|
|
console.log(` Size: ${(img.Size / 1024 / 1024).toFixed(2)} MB`);
|
|
console.log(` Created: ${new Date(img.Created * 1000).toISOString()}`);
|
|
});
|
|
```
|
|
|
|
### 🌐 Network Management
|
|
|
|
#### Create Custom Networks
|
|
|
|
```typescript
|
|
import { DockerNetwork } from '@apiclient.xyz/docker';
|
|
|
|
// Create a bridge network
|
|
const network = await DockerNetwork.createNetwork(docker, {
|
|
Name: 'my-app-network',
|
|
Driver: 'bridge',
|
|
EnableIPv6: false,
|
|
IPAM: {
|
|
Driver: 'default',
|
|
Config: [
|
|
{
|
|
Subnet: '172.28.0.0/16',
|
|
Gateway: '172.28.0.1',
|
|
},
|
|
],
|
|
},
|
|
Labels: {
|
|
project: 'my-app',
|
|
environment: 'production',
|
|
},
|
|
});
|
|
|
|
console.log(`Network created: ${network.Name} (${network.Id})`);
|
|
```
|
|
|
|
#### List and Inspect Networks
|
|
|
|
```typescript
|
|
// Get all networks
|
|
const networks = await docker.getNetworks();
|
|
|
|
networks.forEach((net) => {
|
|
console.log(`Network: ${net.Name} (${net.Driver})`);
|
|
console.log(` Scope: ${net.Scope}`);
|
|
console.log(` Internal: ${net.Internal}`);
|
|
});
|
|
|
|
// Get specific network by name
|
|
const appNetwork = await DockerNetwork.getNetworkByName(docker, 'my-app-network');
|
|
|
|
// Get containers connected to this network
|
|
const containers = await appNetwork.getContainersOnNetwork();
|
|
console.log(`Containers on network: ${containers.length}`);
|
|
```
|
|
|
|
#### Remove a Network
|
|
|
|
```typescript
|
|
const network = await DockerNetwork.getNetworkByName(docker, 'my-app-network');
|
|
await network.remove();
|
|
console.log('Network removed');
|
|
```
|
|
|
|
### 🎭 Service Management (Swarm Mode)
|
|
|
|
#### Activate Swarm Mode
|
|
|
|
```typescript
|
|
// Initialize swarm mode first
|
|
await docker.activateSwarm('192.168.1.100'); // Optional: advertisement IP
|
|
console.log('Swarm mode activated');
|
|
```
|
|
|
|
#### Deploy Services
|
|
|
|
```typescript
|
|
import { DockerService, DockerImage, DockerNetwork, DockerSecret } from '@apiclient.xyz/docker';
|
|
|
|
// Create prerequisites
|
|
const network = await DockerNetwork.createNetwork(docker, {
|
|
Name: 'app-network',
|
|
Driver: 'overlay', // Use overlay for swarm
|
|
});
|
|
|
|
const image = await DockerImage.createFromRegistry(docker, {
|
|
creationObject: {
|
|
imageUrl: 'nginx',
|
|
imageTag: 'latest',
|
|
},
|
|
});
|
|
|
|
const secret = await DockerSecret.createSecret(docker, {
|
|
name: 'api-key',
|
|
version: '1.0.0',
|
|
contentArg: 'super-secret-key',
|
|
labels: { app: 'my-app' },
|
|
});
|
|
|
|
// Create a service
|
|
const service = await DockerService.createService(docker, {
|
|
name: 'web-api',
|
|
image: image,
|
|
labels: {
|
|
app: 'api',
|
|
version: '1.0.0',
|
|
},
|
|
networks: [network],
|
|
networkAlias: 'api',
|
|
secrets: [secret],
|
|
ports: ['80:3000'], // host:container
|
|
resources: {
|
|
memorySizeMB: 512,
|
|
},
|
|
});
|
|
|
|
console.log(`Service deployed: ${service.ID}`);
|
|
```
|
|
|
|
#### List and Manage Services
|
|
|
|
```typescript
|
|
// List all services
|
|
const services = await docker.getServices();
|
|
|
|
services.forEach((service) => {
|
|
console.log(`Service: ${service.Spec.Name}`);
|
|
console.log(` Image: ${service.Spec.TaskTemplate.ContainerSpec.Image}`);
|
|
if (service.Spec.Mode.Replicated) {
|
|
console.log(` Replicas: ${service.Spec.Mode.Replicated.Replicas}`);
|
|
}
|
|
});
|
|
|
|
// Get service by name
|
|
const myService = await DockerService.getServiceByName(docker, 'web-api');
|
|
|
|
// Check if service needs update
|
|
const needsUpdate = await myService.needsUpdate();
|
|
if (needsUpdate) {
|
|
console.log('⚠️ Service configuration has changed, update needed');
|
|
}
|
|
|
|
// Remove service
|
|
await myService.remove();
|
|
console.log('Service removed');
|
|
```
|
|
|
|
### 🔐 Secrets Management
|
|
|
|
Secrets are only available in Docker Swarm mode.
|
|
|
|
```typescript
|
|
import { DockerSecret } from '@apiclient.xyz/docker';
|
|
|
|
// Create a secret
|
|
const secret = await DockerSecret.createSecret(docker, {
|
|
name: 'database-password',
|
|
version: '1.0.0',
|
|
contentArg: 'my-super-secret-password',
|
|
labels: {
|
|
app: 'my-app',
|
|
type: 'credential',
|
|
},
|
|
});
|
|
|
|
console.log(`Secret created: ${secret.ID}`);
|
|
|
|
// List all secrets
|
|
const secrets = await DockerSecret.getSecrets(docker);
|
|
secrets.forEach((s) => {
|
|
console.log(`Secret: ${s.Spec.Name}`);
|
|
console.log(` Labels:`, s.Spec.Labels);
|
|
});
|
|
|
|
// Get secret by name
|
|
const dbSecret = await DockerSecret.getSecretByName(docker, 'database-password');
|
|
|
|
// Update secret content
|
|
await dbSecret.update('new-password-value');
|
|
|
|
// Remove secret
|
|
await dbSecret.remove();
|
|
console.log('Secret removed');
|
|
```
|
|
|
|
### 💾 S3 Image Storage
|
|
|
|
Store and retrieve Docker images from S3-compatible storage:
|
|
|
|
```typescript
|
|
// Configure S3 storage for the image store
|
|
await docker.addS3Storage({
|
|
endpoint: 's3.amazonaws.com',
|
|
accessKey: 'AKIAIOSFODNN7EXAMPLE',
|
|
accessSecret: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
|
|
bucketName: 'my-docker-images',
|
|
});
|
|
|
|
// Store an image to S3
|
|
const imageStream = fs.createReadStream('./my-app.tar');
|
|
await docker.imageStore.storeImage('my-app-v1', imageStream);
|
|
|
|
console.log('Image stored to S3');
|
|
```
|
|
|
|
### 📊 Event Monitoring
|
|
|
|
Monitor Docker events in real-time using RxJS observables:
|
|
|
|
```typescript
|
|
// Subscribe to Docker events
|
|
const eventObservable = await docker.getEventObservable();
|
|
|
|
const subscription = eventObservable.subscribe({
|
|
next: (event) => {
|
|
console.log(`📡 Event: ${event.Type} - ${event.Action}`);
|
|
console.log(` Actor: ${event.Actor.ID}`);
|
|
console.log(` Time: ${new Date(event.time * 1000).toISOString()}`);
|
|
|
|
if (event.Type === 'container') {
|
|
console.log(` Container: ${event.Actor.Attributes.name}`);
|
|
}
|
|
},
|
|
error: (err) => console.error('❌ Event stream error:', err),
|
|
complete: () => console.log('Event stream completed'),
|
|
});
|
|
|
|
// Unsubscribe when done
|
|
// subscription.unsubscribe();
|
|
```
|
|
|
|
### 🔧 Registry Authentication
|
|
|
|
Authenticate with Docker registries to pull private images:
|
|
|
|
```typescript
|
|
// Authenticate with a registry
|
|
await docker.auth({
|
|
username: 'your-username',
|
|
password: 'your-password',
|
|
serveraddress: 'https://index.docker.io/v1/', // Docker Hub
|
|
});
|
|
|
|
console.log('✅ Authenticated with registry');
|
|
|
|
// Or read credentials from Docker config file
|
|
const authToken = await docker.getAuthTokenFromDockerConfig('registry.example.com');
|
|
|
|
// Now you can pull private images
|
|
const privateImage = await DockerImage.createFromRegistry(docker, {
|
|
creationObject: {
|
|
imageUrl: 'registry.example.com/private/app',
|
|
imageTag: 'latest',
|
|
},
|
|
});
|
|
```
|
|
|
|
## 🏗️ Advanced Examples
|
|
|
|
### Complete Application Stack with Swarm
|
|
|
|
Deploy a complete multi-service application stack:
|
|
|
|
```typescript
|
|
import { DockerHost, DockerNetwork, DockerSecret, DockerService, DockerImage } from '@apiclient.xyz/docker';
|
|
|
|
async function deployStack() {
|
|
const docker = new DockerHost({});
|
|
await docker.start();
|
|
|
|
// Initialize swarm
|
|
await docker.activateSwarm();
|
|
console.log('✅ Swarm initialized');
|
|
|
|
// Create overlay network for service communication
|
|
const network = await DockerNetwork.createNetwork(docker, {
|
|
Name: 'app-network',
|
|
Driver: 'overlay',
|
|
Attachable: true,
|
|
});
|
|
console.log('✅ Network created');
|
|
|
|
// Create secrets
|
|
const dbPassword = await DockerSecret.createSecret(docker, {
|
|
name: 'db-password',
|
|
version: '1.0.0',
|
|
contentArg: 'strong-database-password',
|
|
labels: { app: 'stack' },
|
|
});
|
|
console.log('✅ Secrets created');
|
|
|
|
// Pull images
|
|
const postgresImage = await DockerImage.createFromRegistry(docker, {
|
|
creationObject: {
|
|
imageUrl: 'postgres',
|
|
imageTag: '14-alpine',
|
|
},
|
|
});
|
|
|
|
const appImage = await DockerImage.createFromRegistry(docker, {
|
|
creationObject: {
|
|
imageUrl: 'my-app',
|
|
imageTag: 'latest',
|
|
},
|
|
});
|
|
console.log('✅ Images pulled');
|
|
|
|
// Deploy database service
|
|
const dbService = await DockerService.createService(docker, {
|
|
name: 'postgres-db',
|
|
image: postgresImage,
|
|
labels: { tier: 'database' },
|
|
networks: [network],
|
|
networkAlias: 'postgres',
|
|
secrets: [dbPassword],
|
|
ports: [],
|
|
resources: {
|
|
memorySizeMB: 1024,
|
|
},
|
|
});
|
|
console.log('✅ Database service deployed');
|
|
|
|
// Deploy application service
|
|
const appService = await DockerService.createService(docker, {
|
|
name: 'web-app',
|
|
image: appImage,
|
|
labels: { tier: 'application' },
|
|
networks: [network],
|
|
networkAlias: 'app',
|
|
secrets: [dbPassword],
|
|
ports: ['80:3000'],
|
|
resources: {
|
|
memorySizeMB: 512,
|
|
},
|
|
});
|
|
console.log('✅ Application service deployed');
|
|
|
|
console.log('🚀 Stack deployment complete!');
|
|
}
|
|
|
|
deployStack().catch(console.error);
|
|
```
|
|
|
|
### Image Pipeline: Pull, Tag, Export
|
|
|
|
```typescript
|
|
async function imagePipeline() {
|
|
const docker = new DockerHost({});
|
|
await docker.start();
|
|
|
|
// Pull latest image
|
|
const image = await DockerImage.createFromRegistry(docker, {
|
|
creationObject: {
|
|
imageUrl: 'node',
|
|
imageTag: '18-alpine',
|
|
},
|
|
});
|
|
console.log('✅ Image pulled');
|
|
|
|
// Tag for private registry
|
|
await DockerImage.tagImageByIdOrName(docker, 'node:18-alpine', {
|
|
registry: 'registry.company.com',
|
|
imageName: 'base/node',
|
|
imageTag: 'v18-alpine',
|
|
});
|
|
console.log('✅ Image tagged');
|
|
|
|
// Export to tar
|
|
const exportStream = await image.exportToTarStream();
|
|
const writeStream = fs.createWriteStream('./node-18-alpine.tar');
|
|
|
|
exportStream.pipe(writeStream);
|
|
|
|
await new Promise((resolve, reject) => {
|
|
writeStream.on('finish', resolve);
|
|
writeStream.on('error', reject);
|
|
});
|
|
console.log('✅ Image exported to tar');
|
|
|
|
await docker.stop();
|
|
}
|
|
```
|
|
|
|
## 🔍 TypeScript Support
|
|
|
|
Full TypeScript definitions for all Docker API entities:
|
|
|
|
```typescript
|
|
import type {
|
|
IDockerHostConstructorOptions,
|
|
IImageCreationDescriptor,
|
|
IServiceCreationDescriptor,
|
|
ISecretCreationDescriptor,
|
|
TLabels,
|
|
} from '@apiclient.xyz/docker';
|
|
|
|
// Full IntelliSense support
|
|
const options: IDockerHostConstructorOptions = {
|
|
socketPath: '/var/run/docker.sock',
|
|
imageStoreDir: '/tmp/docker-images',
|
|
};
|
|
|
|
const imageConfig: IImageCreationDescriptor = {
|
|
imageUrl: 'nginx',
|
|
imageTag: 'alpine',
|
|
};
|
|
|
|
const labels: TLabels = {
|
|
app: 'my-app',
|
|
environment: 'production',
|
|
};
|
|
```
|
|
|
|
## 🎯 Real-World Use Cases
|
|
|
|
### CI/CD Pipeline Integration
|
|
|
|
```typescript
|
|
// In your CI/CD pipeline
|
|
const docker = new DockerHost({
|
|
socketPath: process.env.DOCKER_HOST || '/var/run/docker.sock',
|
|
});
|
|
|
|
await docker.start();
|
|
|
|
// Build and push process
|
|
const image = await DockerImage.createFromTarStream(docker, {
|
|
tarStream: buildArtifactStream,
|
|
creationObject: {
|
|
imageUrl: 'my-app',
|
|
imageTag: process.env.CI_COMMIT_SHA,
|
|
},
|
|
});
|
|
|
|
await DockerImage.tagImageByIdOrName(docker, `my-app:${process.env.CI_COMMIT_SHA}`, {
|
|
registry: 'registry.company.com',
|
|
imageName: 'production/my-app',
|
|
imageTag: 'latest',
|
|
});
|
|
|
|
// Push to registry (authentication required)
|
|
// Note: Pushing requires proper registry authentication
|
|
```
|
|
|
|
### Dynamic Service Scaling
|
|
|
|
```typescript
|
|
// Monitor and scale services based on load
|
|
const services = await docker.getServices();
|
|
const webService = services.find(s => s.Spec.Name === 'web-app');
|
|
|
|
if (webService && webService.Spec.Mode.Replicated) {
|
|
const currentReplicas = webService.Spec.Mode.Replicated.Replicas;
|
|
console.log(`Current replicas: ${currentReplicas}`);
|
|
|
|
// Scale based on your metrics
|
|
// (Scaling API would need to be implemented)
|
|
}
|
|
```
|
|
|
|
## 📖 API Documentation
|
|
|
|
- **Package Repository**: [https://code.foss.global/apiclient.xyz/docker](https://code.foss.global/apiclient.xyz/docker)
|
|
- **Docker Engine API Reference**: [https://docs.docker.com/engine/api/latest/](https://docs.docker.com/engine/api/latest/)
|
|
- **Issues & Bug Reports**: [https://code.foss.global/apiclient.xyz/docker/issues](https://code.foss.global/apiclient.xyz/docker/issues)
|
|
|
|
## 🔑 Key Concepts
|
|
|
|
- **DockerHost**: Main entry point for Docker API communication
|
|
- **Health Checks**: Use `ping()` method to verify Docker daemon accessibility
|
|
- **Socket Path Priority**: Constructor option → `DOCKER_HOST` env → CI mode → default socket
|
|
- **Swarm Mode Required**: Services and secrets require Docker Swarm to be activated
|
|
- **Type Safety**: Full TypeScript support with comprehensive interfaces
|
|
- **Streaming Support**: Real-time event monitoring and tar stream operations
|
|
- **S3 Integration**: Built-in image storage/retrieval from S3-compatible storage
|
|
|
|
## License and Legal Information
|
|
|
|
This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
|
|
|
|
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
|
|
|
|
### Trademarks
|
|
|
|
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.
|
|
|
|
### Company Information
|
|
|
|
Task Venture Capital GmbH
|
|
Registered at District court Bremen HRB 35230 HB, Germany
|
|
|
|
For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
|
|
|
|
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
|