image service

This commit is contained in:
2026-08-08 04:04:39 +00:00
parent 5b3a22d9da
commit b61efccd01
7 changed files with 114 additions and 2 deletions
+28
View File
@@ -11,6 +11,34 @@ export const validateComposeModel = (model, mode) => {
const runtime = model?.services?.runtime;
if (!runtime) return ['runtime service is missing'];
const requiredImageEnvironment = {
GATEWAY_IMAGE_UPLOAD_SECRET_FILE: '/run/secrets/image_upload_core2026_secret',
GAME_IMAGE_UPLOAD_SECRET_FILE: '/run/secrets/image_upload_core2026_secret',
IMAGE_SYNC_SECRET_FILE: '/run/secrets/image_sync_core2026_secret',
};
for (const [key, expected] of Object.entries(requiredImageEnvironment)) {
if (runtime.environment?.[key] !== expected) errors.push(`${key} must be ${expected}`);
}
for (const key of [
'GATEWAY_IMAGE_UPLOAD_URL',
'GATEWAY_SHARED_ICON_PUBLIC_URL',
'GAME_IMAGE_UPLOAD_URL',
'GAME_CONTENT_IMAGE_PUBLIC_URL',
'IMAGE_SYNC_URL',
]) {
if (!runtime.environment?.[key]) errors.push(`${key} must be configured`);
}
const mounts = Array.isArray(runtime.volumes) ? runtime.volumes : [];
for (const target of [
'/run/secrets/image_upload_core2026_secret',
'/run/secrets/image_sync_core2026_secret',
]) {
const mount = mounts.find((candidate) => candidate?.target === target);
if (!mount || mount.type !== 'bind' || mount.read_only !== true) {
errors.push(`${target} must be a read-only bind mount`);
}
}
if (!positive(runtime.mem_limit)) errors.push('runtime memory limit must be positive');
if (!positive(runtime.memswap_limit)) errors.push('runtime memory+swap limit must be positive');
if (Number(runtime.memswap_limit) !== Number(runtime.mem_limit)) {