mirror of
https://github.com/ershisan99/coolify.git
synced 2025-12-31 05:09:24 +00:00
v1.0.12 - Sveltekit migration (#44)
Changed the whole tech stack to SvelteKit which means: - Typescript - SSR - No fastify :( - Beta, but it's fine! Other changes: - Tailwind -> Tailwind JIT - A lot more
This commit is contained in:
52
src/routes/api/v1/services/[serviceName].ts
Normal file
52
src/routes/api/v1/services/[serviceName].ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { execShellAsync } from '$lib/api/common';
|
||||
import { docker } from '$lib/api/docker';
|
||||
import type { Request } from '@sveltejs/kit';
|
||||
|
||||
export async function get(request: Request) {
|
||||
const { serviceName } = request.params;
|
||||
try {
|
||||
const service = (await docker.engine.listServices()).find(
|
||||
(r) =>
|
||||
r.Spec.Labels.managedBy === 'coolify' &&
|
||||
r.Spec.Labels.type === 'service' &&
|
||||
r.Spec.Labels.serviceName === serviceName &&
|
||||
r.Spec.Name === `${serviceName}_${serviceName}`
|
||||
);
|
||||
if (service) {
|
||||
const payload = {
|
||||
config: JSON.parse(service.Spec.Labels.configuration)
|
||||
};
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
success: true,
|
||||
...payload
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
success: false,
|
||||
showToast: false,
|
||||
message: 'Not found'
|
||||
}
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return {
|
||||
status: 500,
|
||||
body: {
|
||||
success: false,
|
||||
error
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function del(request: Request) {
|
||||
const { serviceName } = request.params;
|
||||
await execShellAsync(`docker stack rm ${serviceName}`);
|
||||
return { status: 200, body: {} };
|
||||
}
|
||||
24
src/routes/api/v1/services/deploy/plausible/activate.ts
Normal file
24
src/routes/api/v1/services/deploy/plausible/activate.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { execShellAsync } from '$lib/api/common';
|
||||
import type { Request } from '@sveltejs/kit';
|
||||
|
||||
export async function patch(request: Request) {
|
||||
const { POSTGRESQL_USERNAME, POSTGRESQL_PASSWORD, POSTGRESQL_DATABASE } = JSON.parse(
|
||||
JSON.parse(
|
||||
await execShellAsync(
|
||||
"docker service inspect plausible_plausible --format='{{json .Spec.Labels.configuration}}'"
|
||||
)
|
||||
)
|
||||
).generateEnvsPostgres;
|
||||
const containers = (await execShellAsync("docker ps -a --format='{{json .Names}}'"))
|
||||
.replace(/"/g, '')
|
||||
.trim()
|
||||
.split('\n');
|
||||
const postgresDB = containers.find((container) => container.startsWith('plausible_plausible_db'));
|
||||
await execShellAsync(
|
||||
`docker exec ${postgresDB} psql -H postgresql://${POSTGRESQL_USERNAME}:${POSTGRESQL_PASSWORD}@localhost:5432/${POSTGRESQL_DATABASE} -c "UPDATE users SET email_verified = true;"`
|
||||
);
|
||||
return {
|
||||
status: 200,
|
||||
body: { message: 'OK' }
|
||||
};
|
||||
}
|
||||
187
src/routes/api/v1/services/deploy/plausible/index.ts
Normal file
187
src/routes/api/v1/services/deploy/plausible/index.ts
Normal file
@@ -0,0 +1,187 @@
|
||||
import type { Request } from '@sveltejs/kit';
|
||||
import generator from 'generate-password';
|
||||
import { promises as fs } from 'fs';
|
||||
import yaml from 'js-yaml';
|
||||
import { docker } from '$lib/api/docker';
|
||||
import { baseServiceConfiguration } from '$lib/api/applications/common';
|
||||
import { cleanupTmp, execShellAsync } from '$lib/api/common';
|
||||
|
||||
export async function post(request: Request) {
|
||||
const { email, userName, userPassword } = request.body;
|
||||
let { baseURL } = request.body;
|
||||
const traefikURL = baseURL;
|
||||
baseURL = `https://${baseURL}`;
|
||||
const deployId = 'plausible';
|
||||
const workdir = '/tmp/plausible';
|
||||
const secretKey = generator.generate({ length: 64, numbers: true, strict: true });
|
||||
const generateEnvsPostgres = {
|
||||
POSTGRESQL_PASSWORD: generator.generate({ length: 24, numbers: true, strict: true }),
|
||||
POSTGRESQL_USERNAME: generator.generate({ length: 10, numbers: true, strict: true }),
|
||||
POSTGRESQL_DATABASE: 'plausible'
|
||||
};
|
||||
|
||||
const secrets = [
|
||||
{ name: 'ADMIN_USER_EMAIL', value: email },
|
||||
{ name: 'ADMIN_USER_NAME', value: userName },
|
||||
{ name: 'ADMIN_USER_PWD', value: userPassword },
|
||||
{ name: 'BASE_URL', value: baseURL },
|
||||
{ name: 'SECRET_KEY_BASE', value: secretKey },
|
||||
{ name: 'DISABLE_AUTH', value: 'false' },
|
||||
{ name: 'DISABLE_REGISTRATION', value: 'true' },
|
||||
{
|
||||
name: 'DATABASE_URL',
|
||||
value: `postgresql://${generateEnvsPostgres.POSTGRESQL_USERNAME}:${generateEnvsPostgres.POSTGRESQL_PASSWORD}@plausible_db:5432/${generateEnvsPostgres.POSTGRESQL_DATABASE}`
|
||||
},
|
||||
{ name: 'CLICKHOUSE_DATABASE_URL', value: 'http://plausible_events_db:8123/plausible' }
|
||||
];
|
||||
|
||||
const generateEnvsClickhouse = {};
|
||||
for (const secret of secrets) generateEnvsClickhouse[secret.name] = secret.value;
|
||||
|
||||
const clickhouseConfigXml = `
|
||||
<yandex>
|
||||
<logger>
|
||||
<level>warning</level>
|
||||
<console>true</console>
|
||||
</logger>
|
||||
|
||||
<!-- Stop all the unnecessary logging -->
|
||||
<query_thread_log remove="remove"/>
|
||||
<query_log remove="remove"/>
|
||||
<text_log remove="remove"/>
|
||||
<trace_log remove="remove"/>
|
||||
<metric_log remove="remove"/>
|
||||
<asynchronous_metric_log remove="remove"/>
|
||||
</yandex>`;
|
||||
const clickhouseUserConfigXml = `
|
||||
<yandex>
|
||||
<profiles>
|
||||
<default>
|
||||
<log_queries>0</log_queries>
|
||||
<log_query_threads>0</log_query_threads>
|
||||
</default>
|
||||
</profiles>
|
||||
</yandex>`;
|
||||
|
||||
const clickhouseConfigs = [
|
||||
{
|
||||
source: 'plausible-clickhouse-user-config.xml',
|
||||
target: '/etc/clickhouse-server/users.d/logging.xml'
|
||||
},
|
||||
{
|
||||
source: 'plausible-clickhouse-config.xml',
|
||||
target: '/etc/clickhouse-server/config.d/logging.xml'
|
||||
},
|
||||
{ source: 'plausible-init.query', target: '/docker-entrypoint-initdb.d/init.query' },
|
||||
{ source: 'plausible-init-db.sh', target: '/docker-entrypoint-initdb.d/init-db.sh' }
|
||||
];
|
||||
|
||||
const initQuery = 'CREATE DATABASE IF NOT EXISTS plausible;';
|
||||
const initScript = 'clickhouse client --queries-file /docker-entrypoint-initdb.d/init.query';
|
||||
await execShellAsync(`mkdir -p ${workdir}`);
|
||||
await fs.writeFile(`${workdir}/clickhouse-config.xml`, clickhouseConfigXml);
|
||||
await fs.writeFile(`${workdir}/clickhouse-user-config.xml`, clickhouseUserConfigXml);
|
||||
await fs.writeFile(`${workdir}/init.query`, initQuery);
|
||||
await fs.writeFile(`${workdir}/init-db.sh`, initScript);
|
||||
const stack = {
|
||||
version: '3.8',
|
||||
services: {
|
||||
[deployId]: {
|
||||
image: 'plausible/analytics:latest',
|
||||
command:
|
||||
'sh -c "sleep 10 && /entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh db init-admin && /entrypoint.sh run"',
|
||||
networks: [`${docker.network}`],
|
||||
volumes: [`${deployId}-postgres-data:/var/lib/postgresql/data`],
|
||||
environment: generateEnvsClickhouse,
|
||||
deploy: {
|
||||
...baseServiceConfiguration,
|
||||
labels: [
|
||||
'managedBy=coolify',
|
||||
'type=service',
|
||||
'serviceName=plausible',
|
||||
'configuration=' +
|
||||
JSON.stringify({
|
||||
email,
|
||||
userName,
|
||||
userPassword,
|
||||
baseURL,
|
||||
secretKey,
|
||||
generateEnvsPostgres,
|
||||
generateEnvsClickhouse
|
||||
}),
|
||||
'traefik.enable=true',
|
||||
'traefik.http.services.' + deployId + '.loadbalancer.server.port=8000',
|
||||
'traefik.http.routers.' + deployId + '.entrypoints=websecure',
|
||||
'traefik.http.routers.' +
|
||||
deployId +
|
||||
'.rule=Host(`' +
|
||||
traefikURL +
|
||||
'`) && PathPrefix(`/`)',
|
||||
'traefik.http.routers.' + deployId + '.tls.certresolver=letsencrypt',
|
||||
'traefik.http.routers.' + deployId + '.middlewares=global-compress'
|
||||
]
|
||||
}
|
||||
},
|
||||
plausible_db: {
|
||||
image: 'bitnami/postgresql:13.2.0',
|
||||
networks: [`${docker.network}`],
|
||||
environment: generateEnvsPostgres,
|
||||
deploy: {
|
||||
...baseServiceConfiguration,
|
||||
labels: ['managedBy=coolify', 'type=service', 'serviceName=plausible']
|
||||
}
|
||||
},
|
||||
plausible_events_db: {
|
||||
image: 'yandex/clickhouse-server:21.3.2.5',
|
||||
networks: [`${docker.network}`],
|
||||
volumes: [`${deployId}-clickhouse-data:/var/lib/clickhouse`],
|
||||
ulimits: {
|
||||
nofile: {
|
||||
soft: 262144,
|
||||
hard: 262144
|
||||
}
|
||||
},
|
||||
configs: [...clickhouseConfigs],
|
||||
deploy: {
|
||||
...baseServiceConfiguration,
|
||||
labels: ['managedBy=coolify', 'type=service', 'serviceName=plausible']
|
||||
}
|
||||
}
|
||||
},
|
||||
networks: {
|
||||
[`${docker.network}`]: {
|
||||
external: true
|
||||
}
|
||||
},
|
||||
volumes: {
|
||||
[`${deployId}-clickhouse-data`]: {
|
||||
external: true
|
||||
},
|
||||
[`${deployId}-postgres-data`]: {
|
||||
external: true
|
||||
}
|
||||
},
|
||||
configs: {
|
||||
'plausible-clickhouse-user-config.xml': {
|
||||
file: `${workdir}/clickhouse-user-config.xml`
|
||||
},
|
||||
'plausible-clickhouse-config.xml': {
|
||||
file: `${workdir}/clickhouse-config.xml`
|
||||
},
|
||||
'plausible-init.query': {
|
||||
file: `${workdir}/init.query`
|
||||
},
|
||||
'plausible-init-db.sh': {
|
||||
file: `${workdir}/init-db.sh`
|
||||
}
|
||||
}
|
||||
};
|
||||
await fs.writeFile(`${workdir}/stack.yml`, yaml.dump(stack));
|
||||
await execShellAsync('docker stack rm plausible');
|
||||
await execShellAsync(`cat ${workdir}/stack.yml | docker stack deploy --prune -c - ${deployId}`);
|
||||
cleanupTmp(workdir);
|
||||
return {
|
||||
status: 200,
|
||||
body: { message: 'OK' }
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user