Files
coolify/src/routes/api/v1/databases/deploy.ts
Andras Bacsai adcd68c1ab v1.0.13 (#46)
2021-05-16 21:54:44 +02:00

168 lines
4.2 KiB
TypeScript

import { saveServerLog } from '$lib/api/applications/logging';
import { docker } from '$lib/api/docker';
import type { Request } from '@sveltejs/kit';
import yaml from 'js-yaml';
import { promises as fs } from 'fs';
import cuid from 'cuid';
import generator from 'generate-password';
import { uniqueNamesGenerator, adjectives, colors, animals } from 'unique-names-generator';
import { execShellAsync } from '$lib/api/common';
function getUniq() {
return uniqueNamesGenerator({ dictionaries: [adjectives, animals, colors], length: 2 });
}
export async function post(request: Request) {
try {
const { type } = request.body;
let { defaultDatabaseName } = request.body;
const passwords = generator.generateMultiple(2, {
length: 24,
numbers: true,
strict: true
});
const usernames = generator.generateMultiple(2, {
length: 10,
numbers: true,
strict: true
});
// TODO: Query for existing db with the same name
const nickname = getUniq();
if (!defaultDatabaseName) defaultDatabaseName = nickname;
const deployId = cuid();
const configuration = {
general: {
workdir: `/tmp/${deployId}`,
deployId,
nickname,
type
},
database: {
usernames,
passwords,
defaultDatabaseName
},
deploy: {
name: nickname
}
};
await execShellAsync(`mkdir -p ${configuration.general.workdir}`);
let generateEnvs = {};
let image = null;
let volume = null;
let ulimits = {};
if (type === 'mongodb') {
generateEnvs = {
MONGODB_ROOT_PASSWORD: passwords[0],
MONGODB_USERNAME: usernames[0],
MONGODB_PASSWORD: passwords[1],
MONGODB_DATABASE: defaultDatabaseName
};
image = 'bitnami/mongodb:4.4';
volume = `${configuration.general.deployId}-${type}-data:/bitnami/mongodb`;
} else if (type === 'postgresql') {
generateEnvs = {
POSTGRESQL_PASSWORD: passwords[0],
POSTGRESQL_USERNAME: usernames[0],
POSTGRESQL_DATABASE: defaultDatabaseName
};
image = 'bitnami/postgresql:13.2.0';
volume = `${configuration.general.deployId}-${type}-data:/bitnami/postgresql`;
} else if (type === 'couchdb') {
generateEnvs = {
COUCHDB_PASSWORD: passwords[0],
COUCHDB_USER: usernames[0]
};
image = 'bitnami/couchdb:3';
volume = `${configuration.general.deployId}-${type}-data:/bitnami/couchdb`;
} else if (type === 'mysql') {
generateEnvs = {
MYSQL_ROOT_PASSWORD: passwords[0],
MYSQL_ROOT_USER: usernames[0],
MYSQL_USER: usernames[1],
MYSQL_PASSWORD: passwords[1],
MYSQL_DATABASE: defaultDatabaseName
};
image = 'bitnami/mysql:8.0';
volume = `${configuration.general.deployId}-${type}-data:/bitnami/mysql/data`;
} else if (type === 'clickhouse') {
image = 'yandex/clickhouse-server';
volume = `${configuration.general.deployId}-${type}-data:/var/lib/clickhouse`;
ulimits = {
nofile: {
soft: 262144,
hard: 262144
}
};
} else if (type === 'redis') {
image = 'bitnami/redis';
volume = `${configuration.general.deployId}-${type}-data:/bitnami/redis/data`;
generateEnvs = {
REDIS_PASSWORD: passwords[0]
};
}
const stack = {
version: '3.8',
services: {
[configuration.general.deployId]: {
image,
networks: [`${docker.network}`],
environment: generateEnvs,
volumes: [volume],
ulimits,
deploy: {
replicas: 1,
update_config: {
parallelism: 0,
delay: '10s',
order: 'start-first'
},
rollback_config: {
parallelism: 0,
delay: '10s',
order: 'start-first'
},
labels: [
'managedBy=coolify',
'type=database',
'configuration=' + JSON.stringify(configuration)
]
}
}
},
networks: {
[`${docker.network}`]: {
external: true
}
},
volumes: {
[`${configuration.general.deployId}-${type}-data`]: {
external: true
}
}
};
await fs.writeFile(`${configuration.general.workdir}/stack.yml`, yaml.dump(stack));
await execShellAsync(
`cat ${configuration.general.workdir}/stack.yml | docker stack deploy -c - ${configuration.general.deployId}`
);
return {
status: 201,
body: {
message: 'Deployed.'
}
};
} catch (error) {
console.log(error);
await saveServerLog(error);
return {
status: 500,
body: {
error
}
};
}
}