changemaker.lite/api/dist/services/docker.service.js

91 lines
3.4 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.dockerService = void 0;
const child_process_1 = require("child_process");
const util_1 = require("util");
const http_1 = require("http");
const logger_1 = require("../utils/logger");
const execAsync = (0, util_1.promisify)(child_process_1.exec);
/** Docker socket proxy URL (tecnativa/docker-socket-proxy) — read-only container inspection */
const DOCKER_PROXY_URL = process.env.DOCKER_PROXY_URL || 'http://docker-socket-proxy:2375';
/**
* Make a request to the Docker Engine API via the socket proxy (HTTP).
*/
function dockerRequest(method, path) {
return new Promise((resolve, reject) => {
const url = new URL(path, DOCKER_PROXY_URL);
const options = {
hostname: url.hostname,
port: url.port,
path: url.pathname,
method,
};
const req = (0, http_1.request)(options, (res) => {
const chunks = [];
res.on('data', (chunk) => chunks.push(chunk));
res.on('end', () => {
resolve({
statusCode: res.statusCode || 0,
body: Buffer.concat(chunks).toString(),
});
});
});
req.setTimeout(5000, () => {
req.destroy(new Error('Docker proxy request timed out'));
});
req.on('error', reject);
req.end();
});
}
/**
* Check if a container is running via Docker socket proxy.
*/
async function getContainerStatus(containerName) {
try {
const response = await dockerRequest('GET', `/containers/${containerName}/json`);
if (response.statusCode === 404) {
return { running: false, status: 'not_found', error: 'Container not found' };
}
if (response.statusCode !== 200) {
return { running: false, status: 'error', error: response.body };
}
const data = JSON.parse(response.body);
return {
running: data.State?.Running === true,
status: data.State?.Status || 'unknown',
exitCode: data.State?.ExitCode,
};
}
catch (err) {
logger_1.logger.error(`Failed to check container status: ${containerName}`, err);
return { running: false, status: 'error', error: err.message };
}
}
/**
* Restart/recreate a container using docker compose.
* This ensures environment variables are picked up.
*/
async function restartContainer(containerName) {
try {
// Use docker compose to recreate the container with updated env vars
// -d = detached mode, service name is 'newt' in docker-compose.yml
const { stdout, stderr } = await execAsync('docker compose up -d newt', {
cwd: '/app', // Assuming docker-compose.yml is in /app
timeout: 30000, // 30 second timeout
});
const output = stdout + stderr;
logger_1.logger.info(`Container restart output: ${output}`);
return { success: true, output };
}
catch (err) {
const error = err;
const output = (error.stdout || '') + (error.stderr || '') + error.message;
logger_1.logger.error(`Failed to restart container: ${containerName}`, err);
return { success: false, output };
}
}
exports.dockerService = {
getContainerStatus,
restartContainer,
};
//# sourceMappingURL=docker.service.js.map