پرش به مطلب اصلی

ایجاد ایمیج جدید از کانتینر

کانتینر را 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 نمی‌تواند تغییر کند.


ورودی‌ها

پارامترنوعاجباریتوضیح
imageNameStringبلهنام ایمیج جدید (مثلاً myapp, myrepo/myapp)
imageTagStringبلهتگ ایمیج جدید (مثلاً v1.0, latest)
contIdStringبلهشناسه یا نام کانتینر (می‌تواند partial match)
optionsObjObjectخیرگزینه‌های اضافی (مثل labels, annotations)
manifestFileStringخیرمسیر فایل 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');

نکات عملی

  1. Container State:

    • کانتینر باید موجود باشد (running یا stopped)
    • تمام تغییرات commit می‌شود
    • کانتینر بعد از commit تغییر نمی‌کند
  2. Image Name:

    • اگر نام متفاوت باشد، سیستم کپی خودکار می‌کند
    • کپی ایجاد hash تصادفی برای temporary layer
  3. Performance:

    • commit برای ایمیج‌های بزرگ زمان‌بر است
    • فضای دیسک کافی نیاز است
    • LayerData تمام تغییرات را شامل می‌شود
  4. Manifest:

    • اگر manifest فایل ارائه نشود، از container config استفاده می‌شود
    • WorkingDir, Cmd, Env از کانتینر کپی می‌شود
  5. Database:

    • تمام blob‌ها در DB ذخیره می‌شود
    • رکورد ایمیج در جدول images ثبت می‌شود
  6. Tagging:

    • تگ باید valid باشد
    • می‌تواند latest یا version مثل v1.0 باشد
  7. Container Identification:

    • contId می‌تواند نام یا ID باشد
    • partial match پذیرفته می‌شود

دنباله عملیات

  1. اعتبارسنجی پارامترها
  2. تحقق از وجود کانتینر
  3. بررسی عدم وجود ایمیج
  4. دریافت bundle path
  5. خواندن container config
  6. تهیه manifest
  7. اضافه کردن filesystem layer
  8. کپی ایمیج (اگر نام متفاوت)
  9. یافتن blob‌های ایمیج
  10. ایجاد رکوردهای blob در DB
  11. محاسبه اندازه ایمیج
  12. ایجاد رکورد ایمیج در DB
  13. Logging موفقیت

مرجع سریع

وضعیتکدتوضیح
موفق200Commit موفق
پارامتر نامعتبر422InvalidCommitParameters
کانتینر یافت نشد404ContainerNotFound
ایمیج موجود است409ImageAlreadyExists
خطای کانتینر500FetchContainerBundleFailure
خطای layer500AddFsLayerFailure
خطای DB500CreateImageRecordFailure
خطای عمومی500GenericFailure

موارد استفاده

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