feat: deploy bots (no domains)
This commit is contained in:
parent
692665d0da
commit
9b51936131
@ -0,0 +1,20 @@
|
|||||||
|
-- RedefineTables
|
||||||
|
PRAGMA foreign_keys=OFF;
|
||||||
|
CREATE TABLE "new_ApplicationSettings" (
|
||||||
|
"id" TEXT NOT NULL PRIMARY KEY,
|
||||||
|
"applicationId" TEXT NOT NULL,
|
||||||
|
"dualCerts" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
"debug" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
"previews" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
"autodeploy" BOOLEAN NOT NULL DEFAULT true,
|
||||||
|
"isBot" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" DATETIME NOT NULL,
|
||||||
|
CONSTRAINT "ApplicationSettings_applicationId_fkey" FOREIGN KEY ("applicationId") REFERENCES "Application" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
INSERT INTO "new_ApplicationSettings" ("applicationId", "autodeploy", "createdAt", "debug", "dualCerts", "id", "previews", "updatedAt") SELECT "applicationId", "autodeploy", "createdAt", "debug", "dualCerts", "id", "previews", "updatedAt" FROM "ApplicationSettings";
|
||||||
|
DROP TABLE "ApplicationSettings";
|
||||||
|
ALTER TABLE "new_ApplicationSettings" RENAME TO "ApplicationSettings";
|
||||||
|
CREATE UNIQUE INDEX "ApplicationSettings_applicationId_key" ON "ApplicationSettings"("applicationId");
|
||||||
|
PRAGMA foreign_key_check;
|
||||||
|
PRAGMA foreign_keys=ON;
|
@ -124,6 +124,7 @@ model ApplicationSettings {
|
|||||||
debug Boolean @default(false)
|
debug Boolean @default(false)
|
||||||
previews Boolean @default(false)
|
previews Boolean @default(false)
|
||||||
autodeploy Boolean @default(true)
|
autodeploy Boolean @default(true)
|
||||||
|
isBot Boolean @default(false)
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
application Application @relation(fields: [applicationId], references: [id])
|
application Application @relation(fields: [applicationId], references: [id])
|
||||||
|
@ -298,7 +298,6 @@ import * as buildpacks from '../lib/buildPacks';
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
console.log({port})
|
|
||||||
const composeFile = {
|
const composeFile = {
|
||||||
version: '3.8',
|
version: '3.8',
|
||||||
services: {
|
services: {
|
||||||
|
@ -17,7 +17,7 @@ import { checkContainer, removeContainer } from './docker';
|
|||||||
import { day } from './dayjs';
|
import { day } from './dayjs';
|
||||||
import * as serviceFields from './serviceFields'
|
import * as serviceFields from './serviceFields'
|
||||||
|
|
||||||
export const version = '3.4.1';
|
export const version = '3.5.0';
|
||||||
export const isDev = process.env.NODE_ENV === 'development';
|
export const isDev = process.env.NODE_ENV === 'development';
|
||||||
|
|
||||||
const algorithm = 'aes-256-ctr';
|
const algorithm = 'aes-256-ctr';
|
||||||
|
@ -5,7 +5,7 @@ import axios from 'axios';
|
|||||||
import { FastifyReply } from 'fastify';
|
import { FastifyReply } from 'fastify';
|
||||||
import { day } from '../../../../lib/dayjs';
|
import { day } from '../../../../lib/dayjs';
|
||||||
import { setDefaultBaseImage, setDefaultConfiguration } from '../../../../lib/buildPacks/common';
|
import { setDefaultBaseImage, setDefaultConfiguration } from '../../../../lib/buildPacks/common';
|
||||||
import { checkDomainsIsValidInDNS, checkDoubleBranch, decrypt, encrypt, errorHandler, executeDockerCmd, generateSshKeyPair, getContainerUsage, getDomain, getFreeExposedPort, isDev, isDomainConfigured, prisma, stopBuild, uniqueName } from '../../../../lib/common';
|
import { checkDomainsIsValidInDNS, checkDoubleBranch, decrypt, encrypt, errorHandler, executeDockerCmd, generateSshKeyPair, getContainerUsage, getDomain, getFreeExposedPort, isDev, isDomainConfigured, listSettings, prisma, stopBuild, uniqueName } from '../../../../lib/common';
|
||||||
import { checkContainer, formatLabelsOnDocker, isContainerExited, removeContainer } from '../../../../lib/docker';
|
import { checkContainer, formatLabelsOnDocker, isContainerExited, removeContainer } from '../../../../lib/docker';
|
||||||
import { scheduler } from '../../../../lib/scheduler';
|
import { scheduler } from '../../../../lib/scheduler';
|
||||||
|
|
||||||
@ -90,10 +90,11 @@ export async function getApplication(request: FastifyRequest<OnlyId>) {
|
|||||||
const { teamId } = request.user
|
const { teamId } = request.user
|
||||||
const appId = process.env['COOLIFY_APP_ID'];
|
const appId = process.env['COOLIFY_APP_ID'];
|
||||||
const application: any = await getApplicationFromDB(id, teamId);
|
const application: any = await getApplicationFromDB(id, teamId);
|
||||||
|
const settings = await listSettings();
|
||||||
return {
|
return {
|
||||||
application,
|
application,
|
||||||
appId
|
appId,
|
||||||
|
settings
|
||||||
};
|
};
|
||||||
|
|
||||||
} catch ({ status, message }) {
|
} catch ({ status, message }) {
|
||||||
@ -275,7 +276,7 @@ export async function saveApplication(request: FastifyRequest<SaveApplication>,
|
|||||||
export async function saveApplicationSettings(request: FastifyRequest<SaveApplicationSettings>, reply: FastifyReply) {
|
export async function saveApplicationSettings(request: FastifyRequest<SaveApplicationSettings>, reply: FastifyReply) {
|
||||||
try {
|
try {
|
||||||
const { id } = request.params
|
const { id } = request.params
|
||||||
const { debug, previews, dualCerts, autodeploy, branch, projectId } = request.body
|
const { debug, previews, dualCerts, autodeploy, branch, projectId, isBot } = request.body
|
||||||
const isDouble = await checkDoubleBranch(branch, projectId);
|
const isDouble = await checkDoubleBranch(branch, projectId);
|
||||||
if (isDouble && autodeploy) {
|
if (isDouble && autodeploy) {
|
||||||
await prisma.applicationSettings.updateMany({ where: { application: { branch, projectId } }, data: { autodeploy: false } })
|
await prisma.applicationSettings.updateMany({ where: { application: { branch, projectId } }, data: { autodeploy: false } })
|
||||||
@ -283,7 +284,7 @@ export async function saveApplicationSettings(request: FastifyRequest<SaveApplic
|
|||||||
}
|
}
|
||||||
await prisma.application.update({
|
await prisma.application.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
data: { settings: { update: { debug, previews, dualCerts, autodeploy } } },
|
data: { fqdn: isBot ? null : undefined, settings: { update: { debug, previews, dualCerts, autodeploy, isBot } } },
|
||||||
include: { destinationDocker: true }
|
include: { destinationDocker: true }
|
||||||
});
|
});
|
||||||
return reply.code(201).send();
|
return reply.code(201).send();
|
||||||
|
@ -25,7 +25,7 @@ export interface SaveApplication extends OnlyId {
|
|||||||
}
|
}
|
||||||
export interface SaveApplicationSettings extends OnlyId {
|
export interface SaveApplicationSettings extends OnlyId {
|
||||||
Querystring: { domain: string; };
|
Querystring: { domain: string; };
|
||||||
Body: { debug: boolean; previews: boolean; dualCerts: boolean; autodeploy: boolean; branch: string; projectId: number; };
|
Body: { debug: boolean; previews: boolean; dualCerts: boolean; autodeploy: boolean; branch: string; projectId: number; isBot: boolean; };
|
||||||
}
|
}
|
||||||
export interface DeleteApplication extends OnlyId {
|
export interface DeleteApplication extends OnlyId {
|
||||||
Querystring: { domain: string; };
|
Querystring: { domain: string; };
|
||||||
|
@ -144,8 +144,8 @@
|
|||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"need_during_buildtime": "Need during buildtime?",
|
"need_during_buildtime": "Need during buildtime?",
|
||||||
"setup_secret_app_first": "You can add secrets to PR/MR deployments. Please add secrets to the application first. <br>Useful for creating <span class='text-applications font-bold'>staging</span> environments.",
|
"setup_secret_app_first": "You can add secrets to PR/MR deployments. Please add secrets to the application first. <br>Useful for creating <span class='text-green-500 font-bold'>staging</span> environments.",
|
||||||
"values_overwriting_app_secrets": "These values overwrite application secrets in PR/MR deployments. Useful for creating <span class='text-applications font-bold'>staging</span> environments.",
|
"values_overwriting_app_secrets": "These values overwrite application secrets in PR/MR deployments. Useful for creating <span class='text-green-500 font-bold'>staging</span> environments.",
|
||||||
"redeploy": "Redeploy",
|
"redeploy": "Redeploy",
|
||||||
"no_previews_available": "No previews available"
|
"no_previews_available": "No previews available"
|
||||||
},
|
},
|
||||||
@ -194,14 +194,14 @@
|
|||||||
"application": "Application",
|
"application": "Application",
|
||||||
"url_fqdn": "URL (FQDN)",
|
"url_fqdn": "URL (FQDN)",
|
||||||
"domain_fqdn": "Domain (FQDN)",
|
"domain_fqdn": "Domain (FQDN)",
|
||||||
"https_explainer": "If you specify <span class='text-applications font-bold'>https</span>, the application will be accessible only over https. SSL certificate will be generated for you.<br>If you specify <span class='text-applications font-bold'>www</span>, the application will be redirected (302) from non-www and vice versa.<br><br>To modify the domain, you must first stop the application.<br><br><span class='text-white font-bold'>You must set your DNS to point to the server IP in advance.</span>",
|
"https_explainer": "If you specify <span class='text-green-500 font-bold'>https</span>, the application will be accessible only over https. SSL certificate will be generated for you.<br>If you specify <span class='text-green-500 font-bold'>www</span>, the application will be redirected (302) from non-www and vice versa.<br><br>To modify the domain, you must first stop the application.<br><br><span class='text-white font-bold'>You must set your DNS to point to the server IP in advance.</span>",
|
||||||
"ssl_www_and_non_www": "Generate SSL for www and non-www?",
|
"ssl_www_and_non_www": "Generate SSL for www and non-www?",
|
||||||
"ssl_explainer": "It will generate certificates for both www and non-www. <br>You need to have <span class='font-bold text-applications'>both DNS entries</span> set in advance.<br><br>Useful if you expect to have visitors on both.",
|
"ssl_explainer": "It will generate certificates for both www and non-www. <br>You need to have <span class='font-bold text-green-500'>both DNS entries</span> set in advance.<br><br>Useful if you expect to have visitors on both.",
|
||||||
"install_command": "Install Command",
|
"install_command": "Install Command",
|
||||||
"build_command": "Build Command",
|
"build_command": "Build Command",
|
||||||
"start_command": "Start Command",
|
"start_command": "Start Command",
|
||||||
"directory_to_use_explainer": "Directory to use as the base for all commands.<br>Could be useful with <span class='text-applications font-bold'>monorepos</span>.",
|
"directory_to_use_explainer": "Directory to use as the base for all commands.<br>Could be useful with <span class='text-green-500 font-bold'>monorepos</span>.",
|
||||||
"publish_directory_explainer": "Directory containing all the assets for deployment. <br> For example: <span class='text-applications font-bold'>dist</span>,<span class='text-applications font-bold'>_site</span> or <span class='text-applications font-bold'>public</span>.",
|
"publish_directory_explainer": "Directory containing all the assets for deployment. <br> For example: <span class='text-green-500 font-bold'>dist</span>,<span class='text-green-500 font-bold'>_site</span> or <span class='text-green-500 font-bold'>public</span>.",
|
||||||
"features": "Features",
|
"features": "Features",
|
||||||
"enable_automatic_deployment": "Enable Automatic Deployment",
|
"enable_automatic_deployment": "Enable Automatic Deployment",
|
||||||
"enable_auto_deploy_webhooks": "Enable automatic deployment through webhooks.",
|
"enable_auto_deploy_webhooks": "Enable automatic deployment through webhooks.",
|
||||||
|
@ -65,7 +65,7 @@
|
|||||||
"features": "Caractéristiques",
|
"features": "Caractéristiques",
|
||||||
"git_repository": "Dépôt Git",
|
"git_repository": "Dépôt Git",
|
||||||
"git_source": "Source Git",
|
"git_source": "Source Git",
|
||||||
"https_explainer": "Si vous spécifiez <span class='text-applications font-bold'>https</span>, l'application sera accessible uniquement via https. \nUn certificat SSL sera généré pour vous.<br>Si vous spécifiez <span class='text-applications font-bold'>www</span>, l'application sera redirigée (302) à partir de non-www et vice versa \n.<br><br>Pour modifier le domaine, vous devez d'abord arrêter l'application.<br><br><span class='text-white font-bold'>Vous devez configurer, en avance, votre DNS pour pointer vers l'IP du serveur.</span>",
|
"https_explainer": "Si vous spécifiez <span class='text-green-500 font-bold'>https</span>, l'application sera accessible uniquement via https. \nUn certificat SSL sera généré pour vous.<br>Si vous spécifiez <span class='text-green-500 font-bold'>www</span>, l'application sera redirigée (302) à partir de non-www et vice versa \n.<br><br>Pour modifier le domaine, vous devez d'abord arrêter l'application.<br><br><span class='text-white font-bold'>Vous devez configurer, en avance, votre DNS pour pointer vers l'IP du serveur.</span>",
|
||||||
"install_command": "Commande d'installation",
|
"install_command": "Commande d'installation",
|
||||||
"logs": "Journaux des applications",
|
"logs": "Journaux des applications",
|
||||||
"no_applications_found": "Aucune application trouvée",
|
"no_applications_found": "Aucune application trouvée",
|
||||||
@ -78,11 +78,11 @@
|
|||||||
"need_during_buildtime": "Besoin pendant la build ?",
|
"need_during_buildtime": "Besoin pendant la build ?",
|
||||||
"no_previews_available": "Aucun aperçu disponible",
|
"no_previews_available": "Aucun aperçu disponible",
|
||||||
"redeploy": "Redéployer",
|
"redeploy": "Redéployer",
|
||||||
"setup_secret_app_first": "Vous pouvez ajouter des secrets aux déploiements PR/MR. \nVeuillez d'abord ajouter des secrets à l'application. \n<br>Utile pour créer des environnements <span class='text-applications font-bold'>de mise en scène</span>.",
|
"setup_secret_app_first": "Vous pouvez ajouter des secrets aux déploiements PR/MR. \nVeuillez d'abord ajouter des secrets à l'application. \n<br>Utile pour créer des environnements <span class='text-green-500 font-bold'>de mise en scène</span>.",
|
||||||
"values_overwriting_app_secrets": "Ces valeurs remplacent les secrets d'application dans les déploiements PR/MR. \nUtile pour créer des environnements <span class='text-applications font-bold'>de mise en scène</span>."
|
"values_overwriting_app_secrets": "Ces valeurs remplacent les secrets d'application dans les déploiements PR/MR. \nUtile pour créer des environnements <span class='text-green-500 font-bold'>de mise en scène</span>."
|
||||||
},
|
},
|
||||||
"previews": "Aperçus",
|
"previews": "Aperçus",
|
||||||
"publish_directory_explainer": "Répertoire contenant tous les actifs à déployer. \n<br> Par exemple : <span class='text-applications font-bold'>dist</span>,<span class='text-applications font-bold'>_site</span> ou <span \nclass='text-applications font-bold'>public</span>.",
|
"publish_directory_explainer": "Répertoire contenant tous les actifs à déployer. \n<br> Par exemple : <span class='text-green-500 font-bold'>dist</span>,<span class='text-green-500 font-bold'>_site</span> ou <span \nclass='text-green-500 font-bold'>public</span>.",
|
||||||
"rebuild_application": "Re-build l'application",
|
"rebuild_application": "Re-build l'application",
|
||||||
"secret": "secrets",
|
"secret": "secrets",
|
||||||
"secrets": {
|
"secrets": {
|
||||||
@ -91,7 +91,7 @@
|
|||||||
"use_isbuildsecret": "Utiliser isBuildSecret"
|
"use_isbuildsecret": "Utiliser isBuildSecret"
|
||||||
},
|
},
|
||||||
"settings_saved": "Paramètres sauvegardés.",
|
"settings_saved": "Paramètres sauvegardés.",
|
||||||
"ssl_explainer": "Il générera des certificats pour www et non-www. \n<br>Vous devez avoir <span class='font-bold text-applications'>les deux entrées DNS</span> définies à l'avance.<br><br>Utile si vous prévoyez d'avoir des visiteurs sur les deux.",
|
"ssl_explainer": "Il générera des certificats pour www et non-www. \n<br>Vous devez avoir <span class='font-bold text-green-500'>les deux entrées DNS</span> définies à l'avance.<br><br>Utile si vous prévoyez d'avoir des visiteurs sur les deux.",
|
||||||
"ssl_www_and_non_www": "Générer SSL pour www et non-www ?",
|
"ssl_www_and_non_www": "Générer SSL pour www et non-www ?",
|
||||||
"start_command": "Démarrer la commande",
|
"start_command": "Démarrer la commande",
|
||||||
"stop_application": "Arrêter l'application",
|
"stop_application": "Arrêter l'application",
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
export const load: Load = async ({ fetch, url, params }) => {
|
export const load: Load = async ({ fetch, url, params }) => {
|
||||||
try {
|
try {
|
||||||
const response = await get(`/applications/${params.id}`);
|
const response = await get(`/applications/${params.id}`);
|
||||||
let { application, appId, settings, isQueueActive } = response;
|
let { application, appId, settings } = response;
|
||||||
if (!application || Object.entries(application).length === 0) {
|
if (!application || Object.entries(application).length === 0) {
|
||||||
return {
|
return {
|
||||||
status: 302,
|
status: 302,
|
||||||
@ -36,7 +36,8 @@
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
application
|
application,
|
||||||
|
settings
|
||||||
},
|
},
|
||||||
stuff: {
|
stuff: {
|
||||||
application,
|
application,
|
||||||
@ -52,7 +53,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export let application: any;
|
export let application: any;
|
||||||
|
export let settings: any;
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import DeleteIcon from '$lib/components/DeleteIcon.svelte';
|
import DeleteIcon from '$lib/components/DeleteIcon.svelte';
|
||||||
import { del, get, post } from '$lib/api';
|
import { del, get, post } from '$lib/api';
|
||||||
@ -65,10 +66,10 @@
|
|||||||
|
|
||||||
let loading = false;
|
let loading = false;
|
||||||
let statusInterval: any;
|
let statusInterval: any;
|
||||||
let isQueueActive= false;
|
let isQueueActive = false;
|
||||||
$disabledButton =
|
$disabledButton =
|
||||||
!$appSession.isAdmin ||
|
!$appSession.isAdmin ||
|
||||||
!application.fqdn ||
|
(!application.fqdn && !application.settings.isBot) ||
|
||||||
!application.gitSource ||
|
!application.gitSource ||
|
||||||
!application.repository ||
|
!application.repository ||
|
||||||
!application.destinationDocker ||
|
!application.destinationDocker ||
|
||||||
@ -80,9 +81,9 @@
|
|||||||
try {
|
try {
|
||||||
const { buildId } = await post(`/applications/${id}/deploy`, { ...application });
|
const { buildId } = await post(`/applications/${id}/deploy`, { ...application });
|
||||||
addToast({
|
addToast({
|
||||||
message: $t('application.deployment_queued'),
|
message: $t('application.deployment_queued'),
|
||||||
type: 'success'
|
type: 'success'
|
||||||
});
|
});
|
||||||
if ($page.url.pathname.startsWith(`/applications/${id}/logs/build`)) {
|
if ($page.url.pathname.startsWith(`/applications/${id}/logs/build`)) {
|
||||||
return window.location.assign(`/applications/${id}/logs/build?buildId=${buildId}`);
|
return window.location.assign(`/applications/${id}/logs/build?buildId=${buildId}`);
|
||||||
} else {
|
} else {
|
||||||
@ -114,7 +115,7 @@
|
|||||||
return window.location.reload();
|
return window.location.reload();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return errorNotification(error);
|
return errorNotification(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function getStatus() {
|
async function getStatus() {
|
||||||
if ($status.application.loading) return;
|
if ($status.application.loading) return;
|
||||||
@ -133,11 +134,20 @@
|
|||||||
});
|
});
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
setLocation(application);
|
setLocation(application);
|
||||||
|
console.log(settings)
|
||||||
|
if (application.settings.isBot) {
|
||||||
|
$location = `${settings.ipv4}:${application.exposePort}`;
|
||||||
|
console.log($location)
|
||||||
|
}
|
||||||
$status.application.isRunning = false;
|
$status.application.isRunning = false;
|
||||||
$status.application.isExited = false;
|
$status.application.isExited = false;
|
||||||
$status.application.loading = false;
|
$status.application.loading = false;
|
||||||
if (application.gitSourceId && application.destinationDockerId && application.fqdn) {
|
if (
|
||||||
|
application.gitSourceId &&
|
||||||
|
application.destinationDockerId &&
|
||||||
|
application.fqdn &&
|
||||||
|
!application.settings.isBot
|
||||||
|
) {
|
||||||
await getStatus();
|
await getStatus();
|
||||||
statusInterval = setInterval(async () => {
|
statusInterval = setInterval(async () => {
|
||||||
await getStatus();
|
await getStatus();
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
let previews = application.settings.previews;
|
let previews = application.settings.previews;
|
||||||
let dualCerts = application.settings.dualCerts;
|
let dualCerts = application.settings.dualCerts;
|
||||||
let autodeploy = application.settings.autodeploy;
|
let autodeploy = application.settings.autodeploy;
|
||||||
|
let isBot = application.settings.isBot;
|
||||||
|
|
||||||
let nonWWWDomain = application.fqdn && getDomain(application.fqdn).replace(/^www\./, '');
|
let nonWWWDomain = application.fqdn && getDomain(application.fqdn).replace(/^www\./, '');
|
||||||
let isNonWWWDomainOK = false;
|
let isNonWWWDomainOK = false;
|
||||||
@ -99,7 +100,7 @@
|
|||||||
application.fqdn = `http://${cuid()}.demo.coolify.io`;
|
application.fqdn = `http://${cuid()}.demo.coolify.io`;
|
||||||
await handleSubmit();
|
await handleSubmit();
|
||||||
}
|
}
|
||||||
domainEl.focus();
|
// !isBot && domainEl.focus();
|
||||||
await getUsage();
|
await getUsage();
|
||||||
usageInterval = setInterval(async () => {
|
usageInterval = setInterval(async () => {
|
||||||
await getUsage();
|
await getUsage();
|
||||||
@ -129,11 +130,15 @@
|
|||||||
if (name === 'autodeploy') {
|
if (name === 'autodeploy') {
|
||||||
autodeploy = !autodeploy;
|
autodeploy = !autodeploy;
|
||||||
}
|
}
|
||||||
|
if (name === 'isBot') {
|
||||||
|
isBot = !isBot;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
await post(`/applications/${id}/settings`, {
|
await post(`/applications/${id}/settings`, {
|
||||||
previews,
|
previews,
|
||||||
debug,
|
debug,
|
||||||
dualCerts,
|
dualCerts,
|
||||||
|
isBot,
|
||||||
autodeploy,
|
autodeploy,
|
||||||
branch: application.branch,
|
branch: application.branch,
|
||||||
projectId: application.projectId
|
projectId: application.projectId
|
||||||
@ -155,22 +160,26 @@
|
|||||||
if (name === 'autodeploy') {
|
if (name === 'autodeploy') {
|
||||||
autodeploy = !autodeploy;
|
autodeploy = !autodeploy;
|
||||||
}
|
}
|
||||||
|
if (name === 'isBot') {
|
||||||
|
isBot = !isBot;
|
||||||
|
}
|
||||||
return errorNotification(error);
|
return errorNotification(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function handleSubmit() {
|
async function handleSubmit() {
|
||||||
if (loading || !application.fqdn) return;
|
if (loading || (!application.fqdn && !isBot)) return;
|
||||||
loading = true;
|
loading = true;
|
||||||
try {
|
try {
|
||||||
nonWWWDomain = application.fqdn && getDomain(application.fqdn).replace(/^www\./, '');
|
nonWWWDomain = application.fqdn && getDomain(application.fqdn).replace(/^www\./, '');
|
||||||
if (application.deploymentType)
|
if (application.deploymentType)
|
||||||
application.deploymentType = application.deploymentType.toLowerCase();
|
application.deploymentType = application.deploymentType.toLowerCase();
|
||||||
await post(`/applications/${id}/check`, {
|
!isBot &&
|
||||||
fqdn: application.fqdn,
|
(await post(`/applications/${id}/check`, {
|
||||||
forceSave,
|
fqdn: application.fqdn,
|
||||||
dualCerts,
|
forceSave,
|
||||||
exposePort: application.exposePort
|
dualCerts,
|
||||||
});
|
exposePort: application.exposePort
|
||||||
|
}));
|
||||||
await post(`/applications/${id}`, { ...application });
|
await post(`/applications/${id}`, { ...application });
|
||||||
setLocation(application);
|
setLocation(application);
|
||||||
$disabledButton = false;
|
$disabledButton = false;
|
||||||
@ -371,16 +380,16 @@
|
|||||||
{#if isDisabled}
|
{#if isDisabled}
|
||||||
<input class="capitalize" disabled={isDisabled} value={application.buildPack} />
|
<input class="capitalize" disabled={isDisabled} value={application.buildPack} />
|
||||||
{:else}
|
{:else}
|
||||||
<a
|
<a
|
||||||
href={`/applications/${id}/configuration/buildpack?from=/applications/${id}`}
|
href={`/applications/${id}/configuration/buildpack?from=/applications/${id}`}
|
||||||
class="no-underline "
|
class="no-underline "
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
value={application.buildPack}
|
value={application.buildPack}
|
||||||
id="buildPack"
|
id="buildPack"
|
||||||
class="cursor-pointer hover:bg-coolgray-500 capitalize"
|
class="cursor-pointer hover:bg-coolgray-500 capitalize"
|
||||||
/></a
|
/></a
|
||||||
>
|
>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-2 items-center pb-8">
|
<div class="grid grid-cols-2 items-center pb-8">
|
||||||
@ -468,77 +477,88 @@
|
|||||||
<div class="title">{$t('application.application')}</div>
|
<div class="title">{$t('application.application')}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-flow-row gap-2 px-10">
|
<div class="grid grid-flow-row gap-2 px-10">
|
||||||
<div class="grid grid-cols-2">
|
<div class="grid grid-cols-2 items-center">
|
||||||
<div class="flex-col">
|
<Setting
|
||||||
<label for="fqdn" class="pt-2 text-base font-bold text-stone-100"
|
isCenter={false}
|
||||||
>{$t('application.url_fqdn')}</label
|
bind:setting={isBot}
|
||||||
>
|
on:click={() => changeSettings('isBot')}
|
||||||
{#if browser && window.location.hostname === 'demo.coolify.io'}
|
title="Is your application a bot?"
|
||||||
<Explainer
|
description="You can deploy applications without domains. <br>They will listen on <span class='text-green-500 font-bold'>IP:PORT</span> instead.<br></Setting><br>Useful for <span class='text-green-500 font-bold'>example bots.</span>"
|
||||||
text="<span class='text-white font-bold'>You can use the predefined random url name or enter your own domain name.</span>"
|
/>
|
||||||
|
</div>
|
||||||
|
{#if !isBot}
|
||||||
|
<div class="grid grid-cols-2">
|
||||||
|
<div class="flex-col">
|
||||||
|
<label for="fqdn" class="pt-2 text-base font-bold text-stone-100"
|
||||||
|
>{$t('application.url_fqdn')}</label
|
||||||
|
>
|
||||||
|
{#if browser && window.location.hostname === 'demo.coolify.io'}
|
||||||
|
<Explainer
|
||||||
|
text="<span class='text-white font-bold'>You can use the predefined random url name or enter your own domain name.</span>"
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
<Explainer text={$t('application.https_explainer')} />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
readonly={isDisabled}
|
||||||
|
disabled={isDisabled}
|
||||||
|
bind:this={domainEl}
|
||||||
|
name="fqdn"
|
||||||
|
id="fqdn"
|
||||||
|
required
|
||||||
|
bind:value={application.fqdn}
|
||||||
|
pattern="^https?://([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{'{'}2,{'}'}$"
|
||||||
|
placeholder="eg: https://coollabs.io"
|
||||||
/>
|
/>
|
||||||
{/if}
|
{#if forceSave}
|
||||||
<Explainer text={$t('application.https_explainer')} />
|
<div class="flex-col space-y-2 pt-4 text-center">
|
||||||
</div>
|
{#if isNonWWWDomainOK}
|
||||||
<div>
|
|
||||||
<input
|
|
||||||
readonly={isDisabled}
|
|
||||||
disabled={isDisabled}
|
|
||||||
bind:this={domainEl}
|
|
||||||
name="fqdn"
|
|
||||||
id="fqdn"
|
|
||||||
required
|
|
||||||
bind:value={application.fqdn}
|
|
||||||
pattern="^https?://([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{'{'}2,{'}'}$"
|
|
||||||
placeholder="eg: https://coollabs.io"
|
|
||||||
/>
|
|
||||||
{#if forceSave}
|
|
||||||
<div class="flex-col space-y-2 pt-4 text-center">
|
|
||||||
{#if isNonWWWDomainOK}
|
|
||||||
<button
|
|
||||||
class="btn btn-sm bg-green-600 hover:bg-green-500"
|
|
||||||
on:click|preventDefault={() => isDNSValid(getDomain(nonWWWDomain), false)}
|
|
||||||
>DNS settings for {nonWWWDomain} is OK, click to recheck.</button
|
|
||||||
>
|
|
||||||
{:else}
|
|
||||||
<button
|
|
||||||
class="btn btn-sm bg-red-600 hover:bg-red-500"
|
|
||||||
on:click|preventDefault={() => isDNSValid(getDomain(nonWWWDomain), false)}
|
|
||||||
>DNS settings for {nonWWWDomain} is invalid, click to recheck.</button
|
|
||||||
>
|
|
||||||
{/if}
|
|
||||||
{#if dualCerts}
|
|
||||||
{#if isWWWDomainOK}
|
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm bg-green-600 hover:bg-green-500"
|
class="btn btn-sm bg-green-600 hover:bg-green-500"
|
||||||
on:click|preventDefault={() =>
|
on:click|preventDefault={() => isDNSValid(getDomain(nonWWWDomain), false)}
|
||||||
isDNSValid(getDomain(`www.${nonWWWDomain}`), true)}
|
>DNS settings for {nonWWWDomain} is OK, click to recheck.</button
|
||||||
>DNS settings for www.{nonWWWDomain} is OK, click to recheck.</button
|
|
||||||
>
|
>
|
||||||
{:else}
|
{:else}
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm bg-red-600 hover:bg-red-500"
|
class="btn btn-sm bg-red-600 hover:bg-red-500"
|
||||||
on:click|preventDefault={() =>
|
on:click|preventDefault={() => isDNSValid(getDomain(nonWWWDomain), false)}
|
||||||
isDNSValid(getDomain(`www.${nonWWWDomain}`), true)}
|
>DNS settings for {nonWWWDomain} is invalid, click to recheck.</button
|
||||||
>DNS settings for www.{nonWWWDomain} is invalid, click to recheck.</button
|
|
||||||
>
|
>
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{#if dualCerts}
|
||||||
</div>
|
{#if isWWWDomainOK}
|
||||||
{/if}
|
<button
|
||||||
|
class="btn btn-sm bg-green-600 hover:bg-green-500"
|
||||||
|
on:click|preventDefault={() =>
|
||||||
|
isDNSValid(getDomain(`www.${nonWWWDomain}`), true)}
|
||||||
|
>DNS settings for www.{nonWWWDomain} is OK, click to recheck.</button
|
||||||
|
>
|
||||||
|
{:else}
|
||||||
|
<button
|
||||||
|
class="btn btn-sm bg-red-600 hover:bg-red-500"
|
||||||
|
on:click|preventDefault={() =>
|
||||||
|
isDNSValid(getDomain(`www.${nonWWWDomain}`), true)}
|
||||||
|
>DNS settings for www.{nonWWWDomain} is invalid, click to recheck.</button
|
||||||
|
>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="grid grid-cols-2 items-center pb-8">
|
||||||
<div class="grid grid-cols-2 items-center pb-8">
|
<Setting
|
||||||
<Setting
|
dataTooltip={$t('forms.must_be_stopped_to_modify')}
|
||||||
dataTooltip={$t('forms.must_be_stopped_to_modify')}
|
disabled={$status.application.isRunning}
|
||||||
disabled={$status.application.isRunning}
|
isCenter={false}
|
||||||
isCenter={false}
|
bind:setting={dualCerts}
|
||||||
bind:setting={dualCerts}
|
title={$t('application.ssl_www_and_non_www')}
|
||||||
title={$t('application.ssl_www_and_non_www')}
|
description={$t('application.ssl_explainer')}
|
||||||
description={$t('application.ssl_explainer')}
|
on:click={() => !$status.application.isRunning && changeSettings('dualCerts')}
|
||||||
on:click={() => !$status.application.isRunning && changeSettings('dualCerts')}
|
/>
|
||||||
/>
|
</div>
|
||||||
</div>
|
{/if}
|
||||||
{#if application.buildPack === 'python'}
|
{#if application.buildPack === 'python'}
|
||||||
<div class="grid grid-cols-2 items-center">
|
<div class="grid grid-cols-2 items-center">
|
||||||
<label for="pythonModule" class="text-base font-bold text-stone-100">WSGI / ASGI</label>
|
<label for="pythonModule" class="text-base font-bold text-stone-100">WSGI / ASGI</label>
|
||||||
@ -588,7 +608,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
{#if !staticDeployments.includes(application.buildPack)}
|
{#if !staticDeployments.includes(application.buildPack) && !isBot}
|
||||||
<div class="grid grid-cols-2 items-center">
|
<div class="grid grid-cols-2 items-center">
|
||||||
<label for="port" class="text-base font-bold text-stone-100">{$t('forms.port')}</label>
|
<label for="port" class="text-base font-bold text-stone-100">{$t('forms.port')}</label>
|
||||||
<input
|
<input
|
||||||
@ -609,6 +629,7 @@
|
|||||||
name="exposePort"
|
name="exposePort"
|
||||||
id="exposePort"
|
id="exposePort"
|
||||||
bind:value={application.exposePort}
|
bind:value={application.exposePort}
|
||||||
|
required={isBot}
|
||||||
placeholder="12345"
|
placeholder="12345"
|
||||||
/>
|
/>
|
||||||
<Explainer
|
<Explainer
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "coolify",
|
"name": "coolify",
|
||||||
"description": "An open-source & self-hostable Heroku / Netlify alternative.",
|
"description": "An open-source & self-hostable Heroku / Netlify alternative.",
|
||||||
"version": "3.4.1",
|
"version": "3.5.0",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"repository": "github:coollabsio/coolify",
|
"repository": "github:coollabsio/coolify",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user