ایجاد ایمیج جدید از کانتینر
کانتینر را commit کرده و ایمیج جدید از تغییرات آن ایجاد میکند.
🧩 دستور کلی
async createNewImageFromContainer(imageName, imageTag, contId, optionsObj = {}, manifestFile)
شرح عملکرد
این متد کانتینر را commit کرده و ایمیج جدید ایجاد میکند. شامل:
- اعتبارسنجی پارامترهای commit
- تحقق از وجود کانتینر
- بررسی عدم وجود ایمیج قبلی
- دریافت مسیر bundle کانتینر
- خواندن config کانتینر
- تهیه manifest با Cmd, WorkingDir, Env
- اضافه کردن filesystem layer
- کپی ایمیج در صورت عدم تطابق نام
- یافتن blobهای ایمیج
- ایجاد رکوردهای blob در DB
- محاسبه اندازه ایمیج
- ایجاد رکورد ایمیج در DB
- logging عملیات
مهم: commit یک عملیات سنگین است. تمام تغییرات کانتینر در ایمیج جدید ذخیره میشود. ایمیج پس از commit نمیتواند تغییر کند.
ورودیها
| پارامتر | نوع | اجباری | توضیح |
|---|---|---|---|
imageName | String | بله | نام ایمیج جدید (مثلاً myapp, myrepo/myapp) |
imageTag | String | بله | تگ ایمیج جدید (مثلاً v1.0, latest) |
contId | String | بله | شناسه یا نام کانتینر (میتواند partial match) |
optionsObj | Object | خیر | گزینههای اضافی (مثل labels, annotations) |
manifestFile | String | خیر | مسیر فایل manifest سفارشی |
خروجی
نوع: String
پیام موفقیت:
added new layer of fs to myapp
استثناها (Errors)
InvalidCommitParameters (422)
پیام: "Invalid commit parameters."
زمان رخ دادن: پارامترهای commit نامعتبر باشند
جزئیات:
{
"type": "VALIDATION_ERROR",
"statusCode": 422,
"imageName": "invalid@image",
"imageTag": "v1.0",
"contId": "container123",
"error": "Image name contains invalid characters"
}
راهنمای حل:
- نام ایمیج: فقط حروف، اعداد، '-', '_', '/' مجاز
- تگ: فقط حروف، اعداد، '.', '-' مجاز
- contId باید valid باشد
ResolveContainerName (500)
پیام: "Failed to resolve container name."
زمان رخ دادن: خطا در تحقق هویت کانتینر
جزئیات:
{
"type": "DB_ERROR",
"statusCode": 500,
"contId": "mycontainer",
"error": "Database query failed"
}
راهنمای حل:
- اتصال دیتابیس را بررسی کنید
- دیتابیس را restart کنید
ContainerNotFound (404)
پیام: "Container not found."
زمان رخ دادن: کانتینر موجود نیست
جزئیات:
{
"type": "NOT_FOUND",
"statusCode": 404,
"contId": "nonexistent-container",
"error": "Container not found"
}
راهنمای حل:
- نام کانتینر را بررسی کنید
- کانتینر واقعاً موجود است؟
listContainers()استفاده کنید
FetchImageState (500)
پیام: "Failed to check image state in database."
زمان رخ دادن: خطا در بررسی وجود ایمیج در DB
جزئیات:
{
"type": "DB_ERROR",
"statusCode": 500,
"imageName": "myapp",
"imageTag": "v1.0",
"error": "Database query failed"
}
راهنمای حل:
- اتصال دیتابیس را بررسی کنید
- دیتابیس را restart کنید
ImageAlreadyExists (409)
پیام: "Image already exists in local registry."
زمان رخ دادن: ایمیج با همین نام و تگ قبلاً موجود است
جزئیات:
{
"type": "INVALID_STATE_ERROR",
"statusCode": 409,
"imageName": "myapp",
"imageTag": "v1.0",
"error": "Image already exists"
}
راهنمای حل:
- تگ متفاوتی استفاده کنید
- ایمیج قبلی را حذف کنید
- نام ایمیج را تغییر دهید
FetchContainerBundleFailure (500)
پیام: "Failed to fetch container bundle."
زمان رخ دادن: خطا در دریافت مسیر bundle کانتینر
جزئیات:
{
"type": "CONTAINER_SERVICE_ERROR",
"statusCode": 500,
"containerId": "container123",
"error": "Container fetch failed"
}
راهنمای حل:
- container manager را بررسی کنید
- کانتینر موجود است؟
- لاگهای سیستم را بررسی کنید
ReadContainerConfigFailure (500)
پیام: "Failed to read container config."
زمان رخ دادن: خطا در خواندن config.json کانتینر
جزئیات:
{
"type": "CONTAINER_SERVICE_ERROR",
"statusCode": 500,
"containerId": "container123",
"error": "Config file not found"
}
راهنمای حل:
- فایل config.json موجود است؟
- اجازههای فایل سیستم را بررسی کنید
- مسیر bundle درست است؟
AddFsLayerFailure (500)
پیام: "Failed to add filesystem layer to image."
زمان رخ دادن: خطا در اضافه کردن filesystem layer
جزئیات:
{
"type": "IMAGE_SERVICE_ERROR",
"statusCode": 500,
"imageName": "myapp",
"imageTag": "v1.0",
"error": "Layer addition failed"
}
راهنمای حل:
- ImageManager را بررسی کنید
- فضای دیسک کافی است؟
- لاگهای سیستم را بررسی کنید
CopyImageToNewNameFailure (500)
پیام: "Failed to copy image to new name."
زمان رخ دادن: خطا در کپی ایمیج به نام جدید
جزئیات:
{
"type": "IMAGE_SERVICE_ERROR",
"statusCode": 500,
"fromImage": "original-name:tag",
"toImage": "myapp:v1.0",
"error": "Image copy failed"
}
راهنمای حل:
- RegistryManager را بررسی کنید
- فضای دیسک کافی است؟
- لاگهای سیستم را بررسی کنید
FindBlobsFailure (500)
پیام: "Failed to find image blobs."
زمان رخ دادن: خطا در یافتن blobهای ایمیج
جزئیات:
{
"type": "IMAGE_SERVICE_ERROR",
"statusCode": 500,
"imageName": "myapp",
"imageTag": "v1.0",
"error": "Blob scanning failed"
}
راهنمای حل:
- دایرکتوری ایمیج را بررسی کنید
- فایلهای blob موجود است؟
CreateImageBlobFailure (500)
پیام: "Failed to create blob record in database."
زمان رخ دادن: خطا در ایجاد رکورد blob در DB
جزئیات:
{
"type": "DB_ERROR",
"statusCode": 500,
"imageName": "myapp",
"imageTag": "v1.0",
"blobCount": 5,
"error": "Database write failed"
}
راهنمای حل:
- اتصال دیتابیس را بررسی کنید
- دیتابیس را restart کنید
CalculateImageSizeFailure (500)
پیام: "Failed to calculate image size."
زمان رخ دادن: خطا در محاسبه اندازه ایمیج
جزئیات:
{
"type": "IMAGE_SERVICE_ERROR",
"statusCode": 500,
"imageName": "myapp",
"imageTag": "v1.0",
"error": "Size calculation failed"
}
راهنمای حل:
- دایرکتوری ایمیج موجود است؟
- اجازههای خواندن موجود است؟
CreateImageRecordFailure (500)
پیام: "Failed to create image record in database."
زمان رخ دادن: خطا در ایجاد رکورد ایمیج در DB
جزئیات:
{
"type": "DB_ERROR",
"statusCode": 500,
"imageName": "myapp",
"imageTag": "v1.0",
"error": "Database write failed"
}
راهنمای حل:
- اتصال دیتابیس را بررسی کنید
- دیتابیس را restart کنید
InvalidManifestFile (422)
پیام: "Invalid manifest file."
زمان رخ دادن: فایل manifest نامعتبر است
جزئیات:
{
"type": "VALIDATION_ERROR",
"statusCode": 422,
"manifestFile": "/path/to/manifest.json",
"error": "JSON parse error"
}
راهنمای حل:
- فایل JSON معتبر است؟
- مسیر فایل درست است؟
- فایل موجود است؟
GenericFailure (500)
پیام: "Generic failure during image creation."
زمان رخ دادن: خطای عمومی
جزئیات:
{
"type": "GENERIC_ERROR",
"statusCode": 500,
"error": "Image creation failed"
}
راهنمای حل:
- سیستم لاگ را بررسی کنید
- تمام سرویسها را restart کنید
- دوباره تلاش کنید
مثالهای استفاده
مثال 1: Commit ساده
const K3Core = require('k3-core');
(async () => {
const k3 = new K3Core();
try {
const result = await k3.imageCore.createNewImageFromContainer(
'myapp',
'v1.0',
'container-123'
);
console.log('Success:', result);
// Output: added new layer of fs to myapp
} catch (error) {
console.log('ERROR:', error.createFullMessage());
}
})();
مثال 2: Commit کانتینر در حال اجرا
(async () => {
const k3 = new K3Core();
try {
// List running containers
const containers = await k3.containerCore.listContainers({ state: 'running' });
console.log('Running containers:', containers.length);
if (containers.length > 0) {
const container = containers[0];
// Commit container
const result = await k3.imageCore.createNewImageFromContainer(
'my-custom-app',
'latest',
container.Id
);
console.log('Commit result:', result);
console.log(`Image created: my-custom-app:latest`);
}
} catch (error) {
console.log('ERROR:', error.message);
}
})();
مثال 3: Commit با options
(async () => {
const k3 = new K3Core();
try {
const result = await k3.imageCore.createNewImageFromContainer(
'database-image',
'v2.0',
'postgres-container',
{
labels: {
'app': 'database',
'version': '2.0',
'author': 'dev-team'
},
annotations: {
'description': 'PostgreSQL with custom configuration'
}
}
);
console.log('Commit successful:', result);
} catch (error) {
console.log('ERROR:', error.message);
}
})();
مثال 4: Commit با manifest سفارشی
(async () => {
const k3 = new K3Core();
const fs = require('fs');
// Create custom manifest
const manifest = {
Cmd: ['/app/start.sh'],
WorkingDir: '/app',
Env: [
'NODE_ENV=production',
'LOG_LEVEL=info',
'DATABASE_URL=postgresql://db:5432/app'
],
Ports: ['3000'],
Volumes: ['/data']
};
try {
fs.writeFileSync('/tmp/manifest.json', JSON.stringify(manifest, null, 2));
const result = await k3.imageCore.createNewImageFromContainer(
'app-server',
'v1.0',
'app-container',
{},
'/tmp/manifest.json'
);
console.log('Commit successful:', result);
} catch (error) {
console.log('ERROR:', error.message);
}
})();
مثال 5: Commit و verify
(async () => {
const k3 = new K3Core();
try {
// Commit
console.log('Committing container...');
const commitResult = await k3.imageCore.createNewImageFromContainer(
'verified-app',
'v1.0',
'my-container'
);
console.log('Commit result:', commitResult);
// Verify
console.log('Verifying image...');
const imageInfo = await k3.imageCore.inspectAnImage('verified-app', {
imageName: 'verified-app',
imageTag: 'v1.0'
});
console.log('Image verified:');
console.log(' Digest:', imageInfo.Digest);
console.log(' Size:', (imageInfo.LayersData.reduce((s, l) => s + l.Size, 0) / 1024 / 1024).toFixed(2), 'MB');
console.log(' Layers:', imageInfo.LayersData.length);
} catch (error) {
console.log('ERROR:', error.message);
}
})();
مثال 6: Commit با مدیریت خطا
(async () => {
const k3 = new K3Core();
const commitWithErrorHandling = async (imageName, imageTag, contId) => {
try {
const result = await k3.imageCore.createNewImageFromContainer(
imageName,
imageTag,
contId
);
return { success: true, message: result };
} catch (error) {
if (error.statusCode === 404) {
console.log(`ERROR: Container ${contId} not found`);
return { success: false, error: 'Container not found' };
} else if (error.statusCode === 409) {
console.log(`ERROR: Image ${imageName}:${imageTag} already exists`);
return { success: false, error: 'Image already exists' };
} else if (error.statusCode === 422) {
console.log('ERROR: Invalid parameters');
return { success: false, error: 'Invalid parameters' };
} else {
console.log(`ERROR: Commit failed - ${error.message}`);
return { success: false, error: error.message };
}
}
};
const result = await commitWithErrorHandling('myapp', 'v1.0', 'container-123');
console.log('Result:', result);
})();
مثال 7: Commit چند کانتینر
(async () => {
const k3 = new K3Core();
const containers = [
{ name: 'web-server', tag: 'v1.0' },
{ name: 'api-service', tag: 'v1.0' },
{ name: 'database', tag: 'v1.0' }
];
const results = [];
for (const container of containers) {
try {
const result = await k3.imageCore.createNewImageFromContainer(
container.name,
container.tag,
container.name
);
results.push({
container: container.name,
status: 'success',
message: result
});
console.log(`✓ ${container.name}:${container.tag} committed`);
} catch (error) {
results.push({
container: container.name,
status: 'failed',
error: error.message
});
console.log(`✗ Failed to commit ${container.name}`);
}
}
console.log('\nCommit Summary:');
console.table(results);
})();
مثال 8: Commit و استفاده فوری
(async () => {
const k3 = new K3Core();
try {
// Step 1: Commit container
console.log('Step 1: Committing container...');
const commitResult = await k3.imageCore.createNewImageFromContainer(
'snapshot-app',
'backup-v1',
'production-container'
);
console.log('Commit result:', commitResult);
// Step 2: Create new container from committed image
console.log('Step 2: Creating new container from image...');
const containerResult = await k3.containerCore.createContainer({
imageName: 'snapshot-app',
imageTag: 'backup-v1',
containerId: 'snapshot-backup-001',
containerPort: 8080,
hostPort: 9090
});
console.log('Container created:', containerResult);
// Step 3: Start new container
console.log('Step 3: Starting container...');
await k3.containerCore.startContainer('snapshot-backup-001');
console.log('Container started successfully');
} catch (error) {
console.log('ERROR:', error.message);
}
})();
الگوهای خطا و راهنمای حل
الگو 1: کانتینر یافت نشد
خطا: ContainerNotFound (404)
راهنمای حل:
const commitWithContainerCheck = async (imageName, imageTag, contId) => {
try {
const result = await k3.imageCore.createNewImageFromContainer(
imageName,
imageTag,
contId
);
return result;
} catch (error) {
if (error.statusCode === 404) {
console.log(`Container ${contId} not found`);
// List available containers
const containers = await k3.containerCore.listContainers();
console.log('Available containers:');
containers.forEach(c => {
console.log(` - ${c.Id}: ${c.Status}`);
});
throw new Error(`Container ${contId} not found. See available containers above.`);
}
throw error;
}
};
await commitWithContainerCheck('myapp', 'v1.0', 'container-id');
الگو 2: ایمیج قبلاً موجود است
خطا: ImageAlreadyExists (409)
راهنمای حل:
const commitOrReplace = async (imageName, imageTag, contId, replace = false) => {
try {
const result = await k3.imageCore.createNewImageFromContainer(
imageName,
imageTag,
contId
);
return { success: true, message: result };
} catch (error) {
if (error.statusCode === 409 && replace) {
console.log(`Image ${imageName}:${imageTag} already exists. Removing...`);
try {
await k3.imageCore.removeAnImage(imageName, imageTag);
console.log('Old image removed');
// Retry commit
const retryResult = await k3.imageCore.createNewImageFromContainer(
imageName,
imageTag,
contId
);
return { success: true, message: retryResult, replaced: true };
} catch (removeError) {
return { success: false, error: `Failed to remove old image: ${removeError.message}` };
}
} else if (error.statusCode === 409) {
console.log(`Image ${imageName}:${imageTag} already exists`);
console.log('Use a different tag or set replace=true to overwrite');
return { success: false, error: 'Image already exists' };
}
throw error;
}
};
await commitOrReplace('myapp', 'v1.0', 'container-123', true);
الگو 3: ایمیج با نام متفاوت
راهنمای حل:
const commitWithNameChange = async (origImageName, newImageName, imageTag, contId) => {
try {
console.log(`Committing container to ${newImageName}:${imageTag}...`);
const result = await k3.imageCore.createNewImageFromContainer(
newImageName,
imageTag,
contId
);
console.log('Commit successful:', result);
// If original image name differs, system automatically handles copying
console.log(`Image ${newImageName}:${imageTag} created successfully`);
return result;
} catch (error) {
console.log('ERROR:', error.message);
throw error;
}
};
await commitWithNameChange('base-image', 'custom-app', 'v1.0', 'container-123');
نکات عملی
-
Container State:
- کانتینر باید موجود باشد (running یا stopped)
- تمام تغییرات commit میشود
- کانتینر بعد از commit تغییر نمیکند
-
Image Name:
- اگر نام متفاوت باشد، سیستم کپی خودکار میکند
- کپی ایجاد hash تصادفی برای temporary layer
-
Performance:
- commit برای ایمیجهای بزرگ زمانبر است
- فضای دیسک کافی نیاز است
- LayerData تمام تغییرات را شامل میشود
-
Manifest:
- اگر manifest فایل ارائه نشود، از container config استفاده میشود
- WorkingDir, Cmd, Env از کانتینر کپی میشود
-
Database:
- تمام blobها در DB ذخیره میشود
- رکورد ایمیج در جدول images ثبت میشود
-
Tagging:
- تگ باید valid باشد
- میتواند latest یا version مثل v1.0 باشد
-
Container Identification:
- contId میتواند نام یا ID باشد
- partial match پذیرفته میشود
دنباله عملیات
- اعتبارسنجی پارامترها
- تحقق از وجود کانتینر
- بررسی عدم وجود ایمیج
- دریافت bundle path
- خواندن container config
- تهیه manifest
- اضافه کردن filesystem layer
- کپی ایمیج (اگر نام متفاوت)
- یافتن blobهای ایمیج
- ایجاد رکوردهای blob در DB
- محاسبه اندازه ایمیج
- ایجاد رکورد ایمیج در DB
- Logging موفقیت
مرجع سریع
| وضعیت | کد | توضیح |
|---|---|---|
| موفق | 200 | Commit موفق |
| پارامتر نامعتبر | 422 | InvalidCommitParameters |
| کانتینر یافت نشد | 404 | ContainerNotFound |
| ایمیج موجود است | 409 | ImageAlreadyExists |
| خطای کانتینر | 500 | FetchContainerBundleFailure |
| خطای layer | 500 | AddFsLayerFailure |
| خطای DB | 500 | CreateImageRecordFailure |
| خطای عمومی | 500 | GenericFailure |
موارد استفاده
Application Snapshot
const result = await createNewImageFromContainer('app-snapshot', 'v1.0', 'production-app');
Container Backup
const result = await createNewImageFromContainer('backup', 'daily', 'database-container');
Development to Production
const result = await createNewImageFromContainer('production-ready', 'v1.0', 'dev-container');
Multi-Replica Deployment
const result = await createNewImageFromContainer('service', 'v2.0', 'base-container');
// Then deploy multiple replicas from the committed image
نسخه: 1.3
تاریخ آپدیت: 10 آذرماه ۱۴۰۴
تیم توسعه: K3 Development Team