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

توقف کانتینر

کانتینر مشخص شده را به‌طور مرتب متوقف می‌کند.


🧩 دستور کلی

async stopContainer(containerId, options = {})

شرح عملکرد

این متد کانتینر را متوقف می‌کند. شامل:

  • انتظار برای مدت زمان مشخص (grace period)
  • ارسال سیگنال SIGKILL (9) برای خاتمه کانتینر
  • بروزرسانی وضعیت دیتابیس
  • ارسال webhook notification

مهم: این متد از killContainer استفاده می‌کند تا کانتینر را کشتن.


ورودی‌ها

پارامترنوعاجباریتوضیح
containerIdStringبلهشناسه یا نام کانتینر
optionsObjectبلهگزینه‌های توقف
options.timeNumberخیرزمان انتظار قبل از توقف (ثانیه)
options.debugBooleanخیرفعال کردن حالت debug

خروجی

نوع: String (پیام نتیجه عملیات)

خروجی:

Using debug verbosity
Stopping container...
Container stopped successfully

استثناها (Errors)

ContainerRecord (404)

پیام: "Container record not found in database."

زمان رخ دادن: کانتینری با شناسه/نام درخواستی یافت نشود

جزئیات:

{
"type": "NOT_FOUND",
"statusCode": 404,
"containerId": "invalid-id"
}

راهنمای حل:

  • شناسه کانتینر را بررسی کنید
  • listContainers() استفاده کنید تا تمام کانتینرها را ببینید
  • نام یا ID صحیح را وارد کنید

ResolveContainerName (500)

پیام: "Database error occurred while resolving container name or ID."

زمان رخ دادن: خطای دیتابیس در تطابق شناسه/نام کانتینر

جزئیات:

{
"type": "DB_ERROR",
"statusCode": 500,
"input": "container-id",
"error": "Database connection lost"
}

راهنمای حل:

  • اتصال دیتابیس را بررسی کنید
  • لاگ‌های دیتابیس را مطالعه کنید
  • دیتابیس را راه‌اندازی کنید

ContainerService (500)

پیام: "Container service error."

زمان رخ دادن: خطا در کشتن کانتینر یا بروزرسانی وضعیت

جزئیات:

{
"type": "GENERIC_ERROR",
"statusCode": 500,
"containerId": "abc123def456",
"error": "Runtime error"
}

راهنمای حل:

  • لاگ‌های runtime را بررسی کنید
  • سرویس K3 فعال است یا خیر؟
  • وضعیت کانتینر را تأیید کنید

FailedToUpdateStateAfterStop (500)

پیام: "Failed to update container state after stopping."

زمان رخ دادن: خطا در بروزرسانی وضعیت دیتابیس

جزئیات:

{
"type": "DB_ERROR",
"statusCode": 500,
"containerId": "abc123def456",
"error": "Database write failed"
}

راهنمای حل:

  • دیتابیس را بررسی کنید
  • اتصال دیتابیس را تأیید کنید
  • فضای دیسک را بررسی کنید

OptionConflict (422)

پیام: "Failed to validate stop options."

زمان رخ دادن: گزینه‌های ورودی نامعتبر باشند

جزئیات:

{
"type": "VALIDATION_ERROR",
"statusCode": 422,
"error": "Invalid schema"
}

راهنمای حل:

  • گزینه‌های ورودی را بررسی کنید
  • time باید Number باشد
  • debug باید Boolean باشد

مثال‌های استفاده

مثال 1: توقف کانتینر ساده

const K3Core = require('k3-core');

(async () => {
const k3 = new K3Core();

try {
const result = await k3.containerCore.stopContainer('my-container', {});
console.log('Container stopped successfully');
console.log(result);
} catch (error) {
console.log(error.createFullMessage());
}
})();

مثال 2: توقف کانتینر با زمان انتظار

(async () => {
const k3 = new K3Core();

try {
const result = await k3.containerCore.stopContainer('web-server', {
time: 15 // 15 ثانیه انتظار
});
console.log('Container stopped with grace period');
} catch (error) {
console.log(error.createFullMessage());
}
})();

مثال 3: توقف کانتینر با debug mode

(async () => {
const k3 = new K3Core();

try {
const result = await k3.containerCore.stopContainer('debug-container', {
time: 10,
debug: true
});
console.log('Debug output:');
console.log(result);
} catch (error) {
console.log(error.createFullMessage());
}
})();

مثال 4: توقف کانتینر بدون انتظار

(async () => {
const k3 = new K3Core();

try {
const result = await k3.containerCore.stopContainer('fast-stop-container', {
time: 0 // توقف فوری بدون انتظار
});
console.log('Container stopped immediately');
} catch (error) {
console.log(error.createFullMessage());
}
})();

مثال 5: توقف کانتینر با بررسی قبلی

(async () => {
const k3 = new K3Core();
const containerId = 'target-container';

try {
// Step 1: بررسی وضعیت کانتینر
const inspect = await k3.containerCore.inspectContainer(containerId);

if (!inspect) {
console.log('Container not found');
return;
}

console.log(`Current state: ${inspect.state?.running ? 'running' : 'stopped'}`);

if (!inspect.state?.running) {
console.log('Container is already stopped');
return;
}

// Step 2: توقف کانتینر
console.log(`Stopping container: ${inspect.name}`);
const result = await k3.containerCore.stopContainer(containerId, {
time: 20
});

console.log('Container stopped successfully');

} catch (error) {
console.log(error.createFullMessage());
}
})();

مثال 6: توقف چند کانتینر

(async () => {
const k3 = new K3Core();

try {
const containers = ['app-1', 'app-2', 'app-3'];

for (const containerId of containers) {
try {
console.log(`Stopping ${containerId}...`);
await k3.containerCore.stopContainer(containerId, { time: 10 });
console.log(`${containerId} stopped`);
} catch (error) {
console.log(`Failed to stop ${containerId}: ${error.message}`);
}
}

} catch (error) {
console.log(error.createFullMessage());
}
})();

مثال 7: توقف کانتینر و انتظار

(async () => {
const k3 = new K3Core();
const containerId = 'service-container';

try {
console.log('Stopping container...');

// توقف کانتینر
await k3.containerCore.stopContainer(containerId, {
time: 15
});

console.log('Container stopped, waiting for cleanup...');

// انتظار برای cleanup
await new Promise(resolve => setTimeout(resolve, 2000));

// بررسی وضعیت نهایی
const inspect = await k3.containerCore.inspectContainer(containerId);
console.log(`Final state: ${inspect.state?.running ? 'running' : 'stopped'}`);

} catch (error) {
console.log(error.createFullMessage());
}
})();

الگوهای خطا و راهنمای حل

الگو 1: کانتینر یافت نشد

خطا: ContainerRecord (404)

راهنمای حل:

try {
await k3.containerCore.stopContainer('invalid-container', { time: 10 });
} catch (error) {
if (error.type === 'NOT_FOUND') {
// Get list of all containers
const allContainers = await k3.containerCore.listContainers({ all: true });
console.log('Available containers:', allContainers.map(c => c.name));

// Find and stop the correct container
const container = allContainers.find(c => c.name.includes('target'));
if (container) {
await k3.containerCore.stopContainer(container.id, { time: 10 });
}
} else {
console.log(error.createFullMessage());
}
}

الگو 2: خطای دیتابیس

خطا: ResolveContainerName یا FailedToUpdateStateAfterStop (500)

راهنمای حل:

try {
await k3.containerCore.stopContainer('my-container', { time: 10 });
} catch (error) {
if (error.type === 'DB_ERROR') {
console.log('Database error occurred');
console.log('Attempting to reconnect...');

// منتظر بمانید و دوباره سعی کنید
await new Promise(resolve => setTimeout(resolve, 2000));

try {
const result = await k3.containerCore.stopContainer('my-container', { time: 10 });
console.log('Retry successful');
} catch (retryError) {
console.log('Retry failed:', retryError.message);
}
} else {
console.log(error.createFullMessage());
}
}

الگو 3: توقف محتاط (safe stop)

راهنمای حل:

const safeStopContainer = async (containerId, timeoutSeconds = 30) => {
try {
// Step 1: بررسی وضعیت
const inspect = await k3.containerCore.inspectContainer(containerId);

if (!inspect) {
console.log(`Container ${containerId} not found`);
return false;
}

if (!inspect.state?.running) {
console.log(`Container ${containerId} is already stopped`);
return true;
}

console.log(`Stopping container: ${inspect.name}`);
console.log(`PID: ${inspect.state?.pid}`);

// Step 2: توقف
const result = await k3.containerCore.stopContainer(containerId, {
time: timeoutSeconds
});

console.log('Stop signal sent');

// Step 3: انتظار برای تأیید
await new Promise(resolve => setTimeout(resolve, 1000));

// Step 4: بررسی وضعیت نهایی
const finalInspect = await k3.containerCore.inspectContainer(containerId);

if (finalInspect.state?.running) {
console.log('Container still running, attempting force stop...');
// می‌توانید force stop انجام دهید
} else {
console.log('Container stopped successfully');
}

return true;

} catch (error) {
console.log(`Failed to stop container: ${error.message}`);
return false;
}
};

await safeStopContainer('my-container', 20);

الگو 4: توقف با timeout

راهنمای حل:

const stopContainerWithTimeout = async (containerId, maxWaitTime = 30000) => {
return Promise.race([
// عملیات توقف
(async () => {
const result = await k3.containerCore.stopContainer(containerId, {
time: Math.floor(maxWaitTime / 1000)
});
console.log('Container stopped within timeout');
return result;
})(),

// timeout
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Stop operation timeout')), maxWaitTime)
)
]);
};

try {
await stopContainerWithTimeout('my-container', 30000);
} catch (error) {
if (error.message === 'Stop operation timeout') {
console.log('Container stop timed out, may need force stop');
} else {
console.log(error.message);
}
}

نکات عملی

  1. Time Parameter:

    • time: 0 - توقف فوری بدون انتظار
    • time: 10 - 10 ثانیه انتظار
    • time: 30 - 30 ثانیه انتظار برای grace period
  2. Grace Period:

    • به کانتینر فرصت می‌دهد تا به‌طور مرتب خودش را ببند
    • منابع را تمیز کند
    • connections را بسته کند
  3. سیگنال:

    • این متد از SIGKILL (9) استفاده می‌کند
    • برای graceful shutdown، از killContainer با SIGTERM استفاده کنید
  4. وضعیت دیتابیس:

    • بعد از توقف، وضعیت دیتابیس بروزرسانی می‌شود
    • PID به 0 تعیین می‌شود
    • Stopped flag به true تعیین می‌شود
  5. Webhooks:

    • پس از توقف، webhook notification ارسال می‌شود
    • event: "container stopped"
  6. Logging:

    • تمام عملیات logged می‌شوند
    • برای troubleshooting مفید است

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

  1. Validation options
  2. Resolve container name/ID
  3. Wait for grace period (time)
  4. Kill container (SIGKILL)
  5. Update database state
  6. Send webhook notification
  7. Log operation

مرجع سریع

وضعیتکدتوضیح
موفق200کانتینر متوقف شد
یافت نشد404ContainerRecord
گزینه نامعتبر422OptionConflict
خطای دیتابیس500ResolveContainerName
خطای state500FailedToUpdateStateAfterStop
خطای عمومی500ContainerService

نسخه: 1.3
تاریخ آپدیت: 9 آذرماه ۱۴۰۴
تیم توسعه: K3 Development Team