v1.0.22 (#67)
This commit is contained in:
parent
a8e9668c2b
commit
2d0f22b379
@ -54,7 +54,6 @@ With Github integration
|
||||
- [VSCode Server](https://github.com/cdr/code-server)
|
||||
- [MinIO](https://min.io)
|
||||
|
||||
|
||||
## Support
|
||||
|
||||
- Twitter: [@andrasbacsai](https://twitter.com/andrasbacsai)
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "coolify",
|
||||
"description": "An open-source, hassle-free, self-hostable Heroku & Netlify alternative.",
|
||||
"version": "1.0.21",
|
||||
"version": "1.0.22",
|
||||
"license": "AGPL-3.0",
|
||||
"scripts": {
|
||||
"dev:docker:start": "docker-compose -f docker-compose-dev.yml up -d",
|
||||
@ -50,6 +50,7 @@
|
||||
"generate-password": "^1.6.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"microtip": "^0.2.2",
|
||||
"mongoose": "^5.12.13",
|
||||
"shelljs": "^0.8.4",
|
||||
"svelte-kit-cookie-session": "^1.0.6",
|
||||
|
2528
pnpm-lock.yaml
generated
2528
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,6 @@
|
||||
<link rel="dns-prefetch" href="https://cdn.coollabs.io/" />
|
||||
<link rel="preconnect" href="https://cdn.coollabs.io/" crossorigin="" />
|
||||
<link rel="stylesheet" href="https://cdn.coollabs.io/fonts/montserrat/montserrat.css" />
|
||||
<link rel="stylesheet" href="https://cdn.coollabs.io/css/microtip-0.2.2.min.css" />
|
||||
%svelte.head%
|
||||
</head>
|
||||
<body>
|
||||
|
@ -101,7 +101,7 @@ export async function handle({ request, resolve }) {
|
||||
cookie: { path: '/', secure: true }
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
console.log(error);
|
||||
return {
|
||||
status: 302,
|
||||
headers: {
|
||||
@ -124,7 +124,7 @@ export async function handle({ request, resolve }) {
|
||||
if (!session['set-cookie']) {
|
||||
if (!session?.data?.coolToken && !publicPages.includes(request.path)) {
|
||||
return {
|
||||
status: 301,
|
||||
status: 302,
|
||||
headers: {
|
||||
location: '/'
|
||||
}
|
||||
|
@ -70,9 +70,9 @@ export default async function (configuration, imageChanged) {
|
||||
}
|
||||
async function purgeImagesAsync(found) {
|
||||
await delay(10000);
|
||||
await purgeImagesContainers(found, true);
|
||||
await purgeImagesContainers(found);
|
||||
}
|
||||
purgeImagesAsync(configuration);
|
||||
//purgeImagesAsync(configuration);
|
||||
|
||||
await saveAppLog('### Published done!', configuration);
|
||||
}
|
||||
|
@ -1,2 +1,8 @@
|
||||
export const publicPages = ['/', '/api/v1/login/github/app', '/api/v1/webhooks/deploy', '/success', '/api/v1/login/email']
|
||||
export const VITE_GITHUB_APP_NAME = import.meta.env.VITE_GITHUB_APP_NAME
|
||||
export const publicPages = [
|
||||
'/',
|
||||
'/api/v1/login/github/app',
|
||||
'/api/v1/webhooks/deploy',
|
||||
'/success',
|
||||
'/api/v1/login/email'
|
||||
];
|
||||
export const VITE_GITHUB_APP_NAME = import.meta.env.VITE_GITHUB_APP_NAME;
|
||||
|
@ -9,7 +9,7 @@
|
||||
if (!publicPages.includes(path)) {
|
||||
if (!session.session.isLoggedIn) {
|
||||
return {
|
||||
status: 301,
|
||||
status: 302,
|
||||
redirect: '/'
|
||||
};
|
||||
}
|
||||
@ -17,7 +17,7 @@
|
||||
}
|
||||
if (!publicPages.includes(path)) {
|
||||
return {
|
||||
status: 301,
|
||||
status: 302,
|
||||
redirect: '/'
|
||||
};
|
||||
}
|
||||
@ -26,6 +26,7 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import 'microtip/microtip.css';
|
||||
import '../app.postcss';
|
||||
export let initDashboard;
|
||||
import { onMount } from 'svelte';
|
||||
|
@ -9,97 +9,96 @@ import type { Request } from '@sveltejs/kit';
|
||||
const saltRounds = 15;
|
||||
|
||||
export async function post(request: Request) {
|
||||
const { email, password } = request.body
|
||||
const { JWT_SIGN_KEY } = process.env;
|
||||
const settings = await Settings.findOne({ applicationName: 'coolify' });
|
||||
const registeredUsers = await User.find().countDocuments();
|
||||
const foundUser = await User.findOne({ email });
|
||||
try {
|
||||
let uid = cuid();
|
||||
if (foundUser) {
|
||||
if (foundUser.type === 'github') {
|
||||
return {
|
||||
status: 500,
|
||||
body: {
|
||||
error: 'Wrong password or email address.'
|
||||
}
|
||||
};
|
||||
}
|
||||
uid = foundUser.uid;
|
||||
if (!await bcrypt.compare(password, foundUser.password)) {
|
||||
return {
|
||||
status: 500,
|
||||
body: {
|
||||
error: 'Wrong password or email address.'
|
||||
}
|
||||
};
|
||||
}
|
||||
} else {
|
||||
if (registeredUsers === 0) {
|
||||
const newUser = new User({
|
||||
_id: new mongoose.Types.ObjectId(),
|
||||
email,
|
||||
uid,
|
||||
type: 'email',
|
||||
password: await bcrypt.hash(password, saltRounds)
|
||||
});
|
||||
const defaultSettings = new Settings({
|
||||
_id: new mongoose.Types.ObjectId()
|
||||
});
|
||||
try {
|
||||
await newUser.save();
|
||||
await defaultSettings.save();
|
||||
} catch (error) {
|
||||
return {
|
||||
status: 500,
|
||||
error: error.message || error
|
||||
};
|
||||
}
|
||||
} else {
|
||||
if (!settings?.allowRegistration) {
|
||||
return {
|
||||
status: 500,
|
||||
body: {
|
||||
error: 'Registration disabled, enable it in settings.'
|
||||
}
|
||||
};
|
||||
} else {
|
||||
const newUser = new User({
|
||||
_id: new mongoose.Types.ObjectId(),
|
||||
email,
|
||||
uid,
|
||||
type: 'email',
|
||||
password: await bcrypt.hash(password, saltRounds)
|
||||
});
|
||||
try {
|
||||
await newUser.save();
|
||||
} catch (error) {
|
||||
return {
|
||||
status: 500,
|
||||
error: error.message || error
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const coolToken = jsonwebtoken.sign({}, JWT_SIGN_KEY, {
|
||||
expiresIn: 15778800,
|
||||
algorithm: 'HS256',
|
||||
audience: 'coolLabs',
|
||||
issuer: 'coolLabs',
|
||||
jwtid: uid,
|
||||
subject: `User:${uid}`,
|
||||
notBefore: -1000
|
||||
});
|
||||
request.locals.session.data = { coolToken, ghToken: null };
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
message: "Successfully logged in."
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
return { status: 500, body: { error: error.message || error } };
|
||||
}
|
||||
|
||||
}
|
||||
const { email, password } = request.body;
|
||||
const { JWT_SIGN_KEY } = process.env;
|
||||
const settings = await Settings.findOne({ applicationName: 'coolify' });
|
||||
const registeredUsers = await User.find().countDocuments();
|
||||
const foundUser = await User.findOne({ email });
|
||||
try {
|
||||
let uid = cuid();
|
||||
if (foundUser) {
|
||||
if (foundUser.type === 'github') {
|
||||
return {
|
||||
status: 500,
|
||||
body: {
|
||||
error: 'Wrong password or email address.'
|
||||
}
|
||||
};
|
||||
}
|
||||
uid = foundUser.uid;
|
||||
if (!(await bcrypt.compare(password, foundUser.password))) {
|
||||
return {
|
||||
status: 500,
|
||||
body: {
|
||||
error: 'Wrong password or email address.'
|
||||
}
|
||||
};
|
||||
}
|
||||
} else {
|
||||
if (registeredUsers === 0) {
|
||||
const newUser = new User({
|
||||
_id: new mongoose.Types.ObjectId(),
|
||||
email,
|
||||
uid,
|
||||
type: 'email',
|
||||
password: await bcrypt.hash(password, saltRounds)
|
||||
});
|
||||
const defaultSettings = new Settings({
|
||||
_id: new mongoose.Types.ObjectId()
|
||||
});
|
||||
try {
|
||||
await newUser.save();
|
||||
await defaultSettings.save();
|
||||
} catch (error) {
|
||||
return {
|
||||
status: 500,
|
||||
error: error.message || error
|
||||
};
|
||||
}
|
||||
} else {
|
||||
if (!settings?.allowRegistration) {
|
||||
return {
|
||||
status: 500,
|
||||
body: {
|
||||
error: 'Registration disabled, enable it in settings.'
|
||||
}
|
||||
};
|
||||
} else {
|
||||
const newUser = new User({
|
||||
_id: new mongoose.Types.ObjectId(),
|
||||
email,
|
||||
uid,
|
||||
type: 'email',
|
||||
password: await bcrypt.hash(password, saltRounds)
|
||||
});
|
||||
try {
|
||||
await newUser.save();
|
||||
} catch (error) {
|
||||
return {
|
||||
status: 500,
|
||||
error: error.message || error
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const coolToken = jsonwebtoken.sign({}, JWT_SIGN_KEY, {
|
||||
expiresIn: 15778800,
|
||||
algorithm: 'HS256',
|
||||
audience: 'coolLabs',
|
||||
issuer: 'coolLabs',
|
||||
jwtid: uid,
|
||||
subject: `User:${uid}`,
|
||||
notBefore: -1000
|
||||
});
|
||||
request.locals.session.data = { coolToken, ghToken: null };
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
message: 'Successfully logged in.'
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
return { status: 500, body: { error: error.message || error } };
|
||||
}
|
||||
}
|
||||
|
@ -2,24 +2,26 @@ import { saveServerLog } from '$lib/api/applications/logging';
|
||||
import { execShellAsync } from '$lib/api/common';
|
||||
import type { Request } from '@sveltejs/kit';
|
||||
|
||||
|
||||
export async function post(request: Request) {
|
||||
try {
|
||||
const output = await execShellAsync('docker builder prune -af')
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
message: 'OK',
|
||||
output: output.replace(/^(?=\n)$|^\s*|\s*$|\n\n+/gm,"").split('\n').pop()
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
await saveServerLog(error);
|
||||
return {
|
||||
status: 500,
|
||||
body: {
|
||||
error: error.message || error
|
||||
}
|
||||
};
|
||||
}
|
||||
try {
|
||||
const output = await execShellAsync('docker builder prune -af');
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
message: 'OK',
|
||||
output: output
|
||||
.replace(/^(?=\n)$|^\s*|\s*$|\n\n+/gm, '')
|
||||
.split('\n')
|
||||
.pop()
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
await saveServerLog(error);
|
||||
return {
|
||||
status: 500,
|
||||
body: {
|
||||
error: error.message || error
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -2,24 +2,26 @@ import { saveServerLog } from '$lib/api/applications/logging';
|
||||
import { execShellAsync } from '$lib/api/common';
|
||||
import type { Request } from '@sveltejs/kit';
|
||||
|
||||
|
||||
export async function post(request: Request) {
|
||||
try {
|
||||
const output = await execShellAsync('docker container prune -f')
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
message: 'OK',
|
||||
output: output.replace(/^(?=\n)$|^\s*|\s*$|\n\n+/gm,"").split('\n').pop()
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
await saveServerLog(error);
|
||||
return {
|
||||
status: 500,
|
||||
body: {
|
||||
error: error.message || error
|
||||
}
|
||||
};
|
||||
}
|
||||
try {
|
||||
const output = await execShellAsync('docker container prune -f');
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
message: 'OK',
|
||||
output: output
|
||||
.replace(/^(?=\n)$|^\s*|\s*$|\n\n+/gm, '')
|
||||
.split('\n')
|
||||
.pop()
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
await saveServerLog(error);
|
||||
return {
|
||||
status: 500,
|
||||
body: {
|
||||
error: error.message || error
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -2,24 +2,26 @@ import { saveServerLog } from '$lib/api/applications/logging';
|
||||
import { execShellAsync } from '$lib/api/common';
|
||||
import type { Request } from '@sveltejs/kit';
|
||||
|
||||
|
||||
export async function post(request: Request) {
|
||||
try {
|
||||
const output = await execShellAsync('docker image prune -af')
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
message: 'OK',
|
||||
output: output.replace(/^(?=\n)$|^\s*|\s*$|\n\n+/gm,"").split('\n').pop()
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
await saveServerLog(error);
|
||||
return {
|
||||
status: 500,
|
||||
body: {
|
||||
error: error.message || error
|
||||
}
|
||||
};
|
||||
}
|
||||
try {
|
||||
const output = await execShellAsync('docker image prune -af');
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
message: 'OK',
|
||||
output: output
|
||||
.replace(/^(?=\n)$|^\s*|\s*$|\n\n+/gm, '')
|
||||
.split('\n')
|
||||
.pop()
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
await saveServerLog(error);
|
||||
return {
|
||||
status: 500,
|
||||
body: {
|
||||
error: error.message || error
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -2,24 +2,26 @@ import { saveServerLog } from '$lib/api/applications/logging';
|
||||
import { execShellAsync } from '$lib/api/common';
|
||||
import type { Request } from '@sveltejs/kit';
|
||||
|
||||
|
||||
export async function post(request: Request) {
|
||||
try {
|
||||
const output = await execShellAsync('docker volume prune -f')
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
message: 'OK',
|
||||
output: output.replace(/^(?=\n)$|^\s*|\s*$|\n\n+/gm,"").split('\n').pop()
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
await saveServerLog(error);
|
||||
return {
|
||||
status: 500,
|
||||
body: {
|
||||
error: error.message || error
|
||||
}
|
||||
};
|
||||
}
|
||||
try {
|
||||
const output = await execShellAsync('docker volume prune -f');
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
message: 'OK',
|
||||
output: output
|
||||
.replace(/^(?=\n)$|^\s*|\s*$|\n\n+/gm, '')
|
||||
.split('\n')
|
||||
.pop()
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
await saveServerLog(error);
|
||||
return {
|
||||
status: 500,
|
||||
body: {
|
||||
error: error.message || error
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -2,26 +2,26 @@ import { saveServerLog } from '$lib/api/applications/logging';
|
||||
import { execShellAsync } from '$lib/api/common';
|
||||
import { docker } from '$lib/api/docker';
|
||||
import type { Request } from '@sveltejs/kit';
|
||||
import systeminformation from 'systeminformation'
|
||||
import systeminformation from 'systeminformation';
|
||||
|
||||
export async function get(request: Request) {
|
||||
try {
|
||||
const df = await execShellAsync(
|
||||
`docker system df --format '{{ json . }}'`
|
||||
);
|
||||
const df = await execShellAsync(`docker system df --format '{{ json . }}'`);
|
||||
const dockerReclaimable = df
|
||||
.split('\n')
|
||||
.filter((n) => n)
|
||||
.map((s) => JSON.parse(s))
|
||||
|
||||
.map((s) => JSON.parse(s));
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
hostname: await (await systeminformation.osInfo()).hostname,
|
||||
filesystems: await (await systeminformation.fsSize()).filter(fs => !fs.fs.match('/dev/loop') || !fs.fs.match('/var/lib/docker/')),
|
||||
filesystems: await (
|
||||
await systeminformation.fsSize()
|
||||
).filter((fs) => !fs.fs.match('/dev/loop') || !fs.fs.match('/var/lib/docker/')),
|
||||
dockerReclaimable
|
||||
}
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
await saveServerLog(error);
|
||||
return {
|
||||
|
@ -59,8 +59,8 @@ export async function post(request: Request) {
|
||||
volumes: {
|
||||
[`${deployId}-code-server-data`]: {
|
||||
external: true
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
await execShellAsync(`mkdir -p ${workdir}`);
|
||||
await fs.writeFile(`${workdir}/stack.yml`, yaml.dump(stack));
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { execShellAsync } from '$lib/api/common';
|
||||
import type { Request } from '@sveltejs/kit';
|
||||
import yaml from "js-yaml"
|
||||
import yaml from 'js-yaml';
|
||||
|
||||
export async function get(request: Request) {
|
||||
// const { POSTGRESQL_USERNAME, POSTGRESQL_PASSWORD, POSTGRESQL_DATABASE } = JSON.parse(
|
||||
@ -15,10 +15,12 @@ export async function get(request: Request) {
|
||||
.trim()
|
||||
.split('\n');
|
||||
const codeServer = containers.find((container) => container.startsWith('code-server'));
|
||||
const configYaml = yaml.load(await execShellAsync(
|
||||
`docker exec ${codeServer} cat /home/coder/.config/code-server/config.yaml`
|
||||
))
|
||||
return {
|
||||
const configYaml = yaml.load(
|
||||
await execShellAsync(
|
||||
`docker exec ${codeServer} cat /home/coder/.config/code-server/config.yaml`
|
||||
)
|
||||
);
|
||||
return {
|
||||
status: 200,
|
||||
body: { message: 'OK', password: configYaml.password }
|
||||
};
|
||||
|
@ -13,9 +13,14 @@ export async function post(request: Request) {
|
||||
const workdir = '/tmp/minio';
|
||||
const deployId = 'minio';
|
||||
const secrets = [
|
||||
{ name: 'MINIO_ROOT_USER', value: generator.generate({ length: 12, numbers: true, strict: true }) },
|
||||
{ name: 'MINIO_ROOT_PASSWORD', value: generator.generate({ length: 24, numbers: true, strict: true }) }
|
||||
|
||||
{
|
||||
name: 'MINIO_ROOT_USER',
|
||||
value: generator.generate({ length: 12, numbers: true, strict: true })
|
||||
},
|
||||
{
|
||||
name: 'MINIO_ROOT_PASSWORD',
|
||||
value: generator.generate({ length: 24, numbers: true, strict: true })
|
||||
}
|
||||
];
|
||||
const generateEnvsMinIO = {};
|
||||
for (const secret of secrets) generateEnvsMinIO[secret.name] = secret.value;
|
||||
@ -36,18 +41,18 @@ export async function post(request: Request) {
|
||||
'type=service',
|
||||
'serviceName=minio',
|
||||
'configuration=' +
|
||||
JSON.stringify({
|
||||
baseURL,
|
||||
generateEnvsMinIO
|
||||
}),
|
||||
JSON.stringify({
|
||||
baseURL,
|
||||
generateEnvsMinIO
|
||||
}),
|
||||
'traefik.enable=true',
|
||||
'traefik.http.services.' + deployId + '.loadbalancer.server.port=9000',
|
||||
'traefik.http.routers.' + deployId + '.entrypoints=websecure',
|
||||
'traefik.http.routers.' +
|
||||
deployId +
|
||||
'.rule=Host(`' +
|
||||
traefikURL +
|
||||
'`) && PathPrefix(`/`)',
|
||||
deployId +
|
||||
'.rule=Host(`' +
|
||||
traefikURL +
|
||||
'`) && PathPrefix(`/`)',
|
||||
'traefik.http.routers.' + deployId + '.tls.certresolver=letsencrypt',
|
||||
'traefik.http.routers.' + deployId + '.middlewares=global-compress'
|
||||
]
|
||||
@ -62,8 +67,8 @@ export async function post(request: Request) {
|
||||
volumes: {
|
||||
[`${deployId}-minio-data`]: {
|
||||
external: true
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
await execShellAsync(`mkdir -p ${workdir}`);
|
||||
await fs.writeFile(`${workdir}/stack.yml`, yaml.dump(stack));
|
||||
|
@ -7,166 +7,166 @@ import { baseServiceConfiguration } from '$lib/api/applications/common';
|
||||
import { cleanupTmp, execShellAsync } from '$lib/api/common';
|
||||
|
||||
export async function post(request: Request) {
|
||||
let { baseURL, remoteDB, database, wordpressExtraConfiguration } = request.body;
|
||||
const traefikURL = baseURL;
|
||||
baseURL = `https://${baseURL}`;
|
||||
console.log({ baseURL, remoteDB, database, wordpressExtraConfiguration })
|
||||
let { baseURL, remoteDB, database, wordpressExtraConfiguration } = request.body;
|
||||
const traefikURL = baseURL;
|
||||
baseURL = `https://${baseURL}`;
|
||||
console.log({ baseURL, remoteDB, database, wordpressExtraConfiguration });
|
||||
|
||||
const workdir = '/tmp/wordpress';
|
||||
const deployId = `wp-${generator.generate({ length: 5, numbers: true, strict: true })}`
|
||||
const defaultDatabaseName = generator.generate({ length: 12, numbers: true, strict: true })
|
||||
const defaultDatabaseHost = `${deployId}-mysql`
|
||||
const defaultDatabaseUser = generator.generate({ length: 12, numbers: true, strict: true })
|
||||
const defaultDatabasePassword = generator.generate({ length: 24, numbers: true, strict: true })
|
||||
const defaultDatabaseRootPassword = generator.generate({ length: 24, numbers: true, strict: true })
|
||||
const defaultDatabaseRootUser = generator.generate({ length: 12, numbers: true, strict: true })
|
||||
let secrets = [
|
||||
{ name: 'WORDPRESS_DB_HOST', value: defaultDatabaseHost },
|
||||
{ name: 'WORDPRESS_DB_USER', value: defaultDatabaseUser },
|
||||
{ name: 'WORDPRESS_DB_PASSWORD', value: defaultDatabasePassword },
|
||||
{ name: 'WORDPRESS_DB_NAME', value: defaultDatabaseName },
|
||||
{ name: 'WORDPRESS_CONFIG_EXTRA', value: wordpressExtraConfiguration }
|
||||
];
|
||||
const workdir = '/tmp/wordpress';
|
||||
const deployId = `wp-${generator.generate({ length: 5, numbers: true, strict: true })}`;
|
||||
const defaultDatabaseName = generator.generate({ length: 12, numbers: true, strict: true });
|
||||
const defaultDatabaseHost = `${deployId}-mysql`;
|
||||
const defaultDatabaseUser = generator.generate({ length: 12, numbers: true, strict: true });
|
||||
const defaultDatabasePassword = generator.generate({ length: 24, numbers: true, strict: true });
|
||||
const defaultDatabaseRootPassword = generator.generate({
|
||||
length: 24,
|
||||
numbers: true,
|
||||
strict: true
|
||||
});
|
||||
const defaultDatabaseRootUser = generator.generate({ length: 12, numbers: true, strict: true });
|
||||
let secrets = [
|
||||
{ name: 'WORDPRESS_DB_HOST', value: defaultDatabaseHost },
|
||||
{ name: 'WORDPRESS_DB_USER', value: defaultDatabaseUser },
|
||||
{ name: 'WORDPRESS_DB_PASSWORD', value: defaultDatabasePassword },
|
||||
{ name: 'WORDPRESS_DB_NAME', value: defaultDatabaseName },
|
||||
{ name: 'WORDPRESS_CONFIG_EXTRA', value: wordpressExtraConfiguration }
|
||||
];
|
||||
|
||||
const generateEnvsMySQL = {
|
||||
MYSQL_ROOT_PASSWORD: defaultDatabaseRootPassword,
|
||||
MYSQL_ROOT_USER: defaultDatabaseRootUser,
|
||||
MYSQL_USER: defaultDatabaseUser,
|
||||
MYSQL_PASSWORD: defaultDatabasePassword,
|
||||
MYSQL_DATABASE: defaultDatabaseName
|
||||
};
|
||||
const image = 'bitnami/mysql:8.0';
|
||||
const volume = `${deployId}-mysql-data:/bitnami/mysql/data`;
|
||||
const generateEnvsMySQL = {
|
||||
MYSQL_ROOT_PASSWORD: defaultDatabaseRootPassword,
|
||||
MYSQL_ROOT_USER: defaultDatabaseRootUser,
|
||||
MYSQL_USER: defaultDatabaseUser,
|
||||
MYSQL_PASSWORD: defaultDatabasePassword,
|
||||
MYSQL_DATABASE: defaultDatabaseName
|
||||
};
|
||||
const image = 'bitnami/mysql:8.0';
|
||||
const volume = `${deployId}-mysql-data:/bitnami/mysql/data`;
|
||||
|
||||
if (remoteDB) {
|
||||
secrets = [
|
||||
{ name: 'WORDPRESS_DB_HOST', value: database.host },
|
||||
{ name: 'WORDPRESS_DB_USER', value: database.user },
|
||||
{ name: 'WORDPRESS_DB_PASSWORD', value: database.password },
|
||||
{ name: 'WORDPRESS_DB_NAME', value: database.name },
|
||||
{ name: 'WORDPRESS_TABLE_PREFIX', value: database.tablePrefix },
|
||||
{ name: 'WORDPRESS_CONFIG_EXTRA', value: wordpressExtraConfiguration }
|
||||
]
|
||||
}
|
||||
if (remoteDB) {
|
||||
secrets = [
|
||||
{ name: 'WORDPRESS_DB_HOST', value: database.host },
|
||||
{ name: 'WORDPRESS_DB_USER', value: database.user },
|
||||
{ name: 'WORDPRESS_DB_PASSWORD', value: database.password },
|
||||
{ name: 'WORDPRESS_DB_NAME', value: database.name },
|
||||
{ name: 'WORDPRESS_TABLE_PREFIX', value: database.tablePrefix },
|
||||
{ name: 'WORDPRESS_CONFIG_EXTRA', value: wordpressExtraConfiguration }
|
||||
];
|
||||
}
|
||||
|
||||
const generateEnvsWordpress = {};
|
||||
for (const secret of secrets) generateEnvsWordpress[secret.name] = secret.value;
|
||||
let stack = {
|
||||
version: '3.8',
|
||||
services: {
|
||||
[deployId]: {
|
||||
image: 'wordpress',
|
||||
networks: [`${docker.network}`],
|
||||
environment: generateEnvsWordpress,
|
||||
volumes: [`${deployId}-wordpress-data:/var/www/html`],
|
||||
deploy: {
|
||||
...baseServiceConfiguration,
|
||||
labels: [
|
||||
'managedBy=coolify',
|
||||
'type=service',
|
||||
'serviceName=' + deployId,
|
||||
'configuration=' +
|
||||
JSON.stringify({
|
||||
deployId,
|
||||
baseURL,
|
||||
generateEnvsWordpress
|
||||
}),
|
||||
'traefik.enable=true',
|
||||
'traefik.http.services.' + deployId + '.loadbalancer.server.port=80',
|
||||
'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'
|
||||
]
|
||||
}
|
||||
},
|
||||
[`${deployId}-mysql`]: {
|
||||
image,
|
||||
networks: [`${docker.network}`],
|
||||
environment: generateEnvsMySQL,
|
||||
volumes: [volume],
|
||||
deploy: {
|
||||
...baseServiceConfiguration,
|
||||
labels: [
|
||||
'managedBy=coolify',
|
||||
'type=service',
|
||||
'serviceName=' + deployId,
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
networks: {
|
||||
[`${docker.network}`]: {
|
||||
external: true
|
||||
}
|
||||
},
|
||||
volumes: {
|
||||
[`${deployId}-wordpress-data`]: {
|
||||
external: true
|
||||
},
|
||||
[`${deployId}-mysql-data`]: {
|
||||
external: true
|
||||
}
|
||||
},
|
||||
};
|
||||
if (remoteDB) {
|
||||
stack = {
|
||||
version: '3.8',
|
||||
services: {
|
||||
[deployId]: {
|
||||
image: 'wordpress',
|
||||
networks: [`${docker.network}`],
|
||||
environment: generateEnvsWordpress,
|
||||
volumes: [`${deployId}-wordpress-data:/var/www/html`],
|
||||
deploy: {
|
||||
...baseServiceConfiguration,
|
||||
labels: [
|
||||
'managedBy=coolify',
|
||||
'type=service',
|
||||
'serviceName=' + deployId,
|
||||
'configuration=' +
|
||||
JSON.stringify({
|
||||
deployId,
|
||||
baseURL,
|
||||
generateEnvsWordpress
|
||||
}),
|
||||
'traefik.enable=true',
|
||||
'traefik.http.services.' + deployId + '.loadbalancer.server.port=80',
|
||||
'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'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
networks: {
|
||||
[`${docker.network}`]: {
|
||||
external: true
|
||||
}
|
||||
},
|
||||
volumes: {
|
||||
[`${deployId}-wordpress-data`]: {
|
||||
external: true
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
await execShellAsync(`mkdir -p ${workdir}`);
|
||||
await fs.writeFile(`${workdir}/stack.yml`, yaml.dump(stack));
|
||||
await execShellAsync(`docker stack rm ${deployId}`);
|
||||
await execShellAsync(`cat ${workdir}/stack.yml | docker stack deploy --prune -c - ${deployId}`);
|
||||
cleanupTmp(workdir);
|
||||
return {
|
||||
status: 200,
|
||||
body: { message: 'OK' }
|
||||
};
|
||||
const generateEnvsWordpress = {};
|
||||
for (const secret of secrets) generateEnvsWordpress[secret.name] = secret.value;
|
||||
let stack = {
|
||||
version: '3.8',
|
||||
services: {
|
||||
[deployId]: {
|
||||
image: 'wordpress',
|
||||
networks: [`${docker.network}`],
|
||||
environment: generateEnvsWordpress,
|
||||
volumes: [`${deployId}-wordpress-data:/var/www/html`],
|
||||
deploy: {
|
||||
...baseServiceConfiguration,
|
||||
labels: [
|
||||
'managedBy=coolify',
|
||||
'type=service',
|
||||
'serviceName=' + deployId,
|
||||
'configuration=' +
|
||||
JSON.stringify({
|
||||
deployId,
|
||||
baseURL,
|
||||
generateEnvsWordpress
|
||||
}),
|
||||
'traefik.enable=true',
|
||||
'traefik.http.services.' + deployId + '.loadbalancer.server.port=80',
|
||||
'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'
|
||||
]
|
||||
}
|
||||
},
|
||||
[`${deployId}-mysql`]: {
|
||||
image,
|
||||
networks: [`${docker.network}`],
|
||||
environment: generateEnvsMySQL,
|
||||
volumes: [volume],
|
||||
deploy: {
|
||||
...baseServiceConfiguration,
|
||||
labels: ['managedBy=coolify', 'type=service', 'serviceName=' + deployId]
|
||||
}
|
||||
}
|
||||
},
|
||||
networks: {
|
||||
[`${docker.network}`]: {
|
||||
external: true
|
||||
}
|
||||
},
|
||||
volumes: {
|
||||
[`${deployId}-wordpress-data`]: {
|
||||
external: true
|
||||
},
|
||||
[`${deployId}-mysql-data`]: {
|
||||
external: true
|
||||
}
|
||||
}
|
||||
};
|
||||
if (remoteDB) {
|
||||
stack = {
|
||||
version: '3.8',
|
||||
services: {
|
||||
[deployId]: {
|
||||
image: 'wordpress',
|
||||
networks: [`${docker.network}`],
|
||||
environment: generateEnvsWordpress,
|
||||
volumes: [`${deployId}-wordpress-data:/var/www/html`],
|
||||
deploy: {
|
||||
...baseServiceConfiguration,
|
||||
labels: [
|
||||
'managedBy=coolify',
|
||||
'type=service',
|
||||
'serviceName=' + deployId,
|
||||
'configuration=' +
|
||||
JSON.stringify({
|
||||
deployId,
|
||||
baseURL,
|
||||
generateEnvsWordpress
|
||||
}),
|
||||
'traefik.enable=true',
|
||||
'traefik.http.services.' + deployId + '.loadbalancer.server.port=80',
|
||||
'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'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
networks: {
|
||||
[`${docker.network}`]: {
|
||||
external: true
|
||||
}
|
||||
},
|
||||
volumes: {
|
||||
[`${deployId}-wordpress-data`]: {
|
||||
external: true
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
await execShellAsync(`mkdir -p ${workdir}`);
|
||||
await fs.writeFile(`${workdir}/stack.yml`, yaml.dump(stack));
|
||||
await execShellAsync(`docker stack rm ${deployId}`);
|
||||
await execShellAsync(`cat ${workdir}/stack.yml | docker stack deploy --prune -c - ${deployId}`);
|
||||
cleanupTmp(workdir);
|
||||
return {
|
||||
status: 200,
|
||||
body: { message: 'OK' }
|
||||
};
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
export async function load(session) {
|
||||
if (!browser && !process.env.VITE_GITHUB_APP_CLIENTID) {
|
||||
return {
|
||||
status: 301,
|
||||
status: 302,
|
||||
redirect: '/dashboard/services'
|
||||
};
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
export async function load(session) {
|
||||
if (!browser && !process.env.VITE_GITHUB_APP_CLIENTID) {
|
||||
return {
|
||||
status: 301,
|
||||
status: 302,
|
||||
redirect: '/dashboard/services'
|
||||
};
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
export async function load(session) {
|
||||
if (!browser && !process.env.VITE_GITHUB_APP_CLIENTID) {
|
||||
return {
|
||||
status: 301,
|
||||
status: 302,
|
||||
redirect: '/dashboard/services'
|
||||
};
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import type {
|
||||
import { writable } from 'svelte/store';
|
||||
export const settings = writable({
|
||||
clientId: null
|
||||
})
|
||||
});
|
||||
export const dashboard = writable<Dashboard>({
|
||||
databases: {
|
||||
deployed: []
|
||||
|
Loading…
x
Reference in New Issue
Block a user