added uvicorn
This commit is contained in:
parent
cd3663038f
commit
c376123877
@ -36,8 +36,7 @@ const createDockerfile = async (data, image): Promise<void> => {
|
|||||||
Dockerfile.push(`RUN pip install gunicorn`);
|
Dockerfile.push(`RUN pip install gunicorn`);
|
||||||
} else if (pythonWSGI?.toLowerCase() === "uvicorn") {
|
} else if (pythonWSGI?.toLowerCase() === "uvicorn") {
|
||||||
Dockerfile.push(`RUN pip install uvicorn`);
|
Dockerfile.push(`RUN pip install uvicorn`);
|
||||||
}
|
} else if (pythonWSGI?.toLowerCase() === 'uwsgi') {
|
||||||
else if (pythonWSGI?.toLowerCase() === 'uwsgi') {
|
|
||||||
Dockerfile.push(`RUN apk add --no-cache uwsgi-python3`);
|
Dockerfile.push(`RUN apk add --no-cache uwsgi-python3`);
|
||||||
// Dockerfile.push(`RUN pip install --no-cache-dir uwsgi`)
|
// Dockerfile.push(`RUN pip install --no-cache-dir uwsgi`)
|
||||||
}
|
}
|
||||||
@ -52,12 +51,11 @@ const createDockerfile = async (data, image): Promise<void> => {
|
|||||||
Dockerfile.push(`COPY .${baseDirectory || ''} ./`);
|
Dockerfile.push(`COPY .${baseDirectory || ''} ./`);
|
||||||
Dockerfile.push(`EXPOSE ${port}`);
|
Dockerfile.push(`EXPOSE ${port}`);
|
||||||
if (pythonWSGI?.toLowerCase() === 'gunicorn') {
|
if (pythonWSGI?.toLowerCase() === 'gunicorn') {
|
||||||
Dockerfile.push(`CMD gunicorn ${pythonModule}:${pythonVariable}`);
|
Dockerfile.push(`CMD gunicorn -w=4 -b=0.0.0.0:8000 ${pythonModule}:${pythonVariable}`);
|
||||||
} else if (pythonWSGI?.toLowerCase() === "uvicorn") {
|
} else if (pythonWSGI?.toLowerCase() === "uvicorn") {
|
||||||
Dockerfile.push(`CMD uvicorn ${pythonModule}:${pythonVariable} --reload --port ${port}`);
|
Dockerfile.push(`CMD uvicorn ${pythonModule}:${pythonVariable} --reload --port ${port}`);
|
||||||
|
|
||||||
}
|
} else if (pythonWSGI?.toLowerCase() === 'uwsgi') {
|
||||||
else if (pythonWSGI?.toLowerCase() === 'uwsgi') {
|
|
||||||
Dockerfile.push(
|
Dockerfile.push(
|
||||||
`CMD uwsgi --master -p 4 --http-socket 0.0.0.0:8000 --uid uwsgi --plugins python3 --protocol uwsgi --wsgi ${pythonModule}:${pythonVariable}`
|
`CMD uwsgi --master -p 4 --http-socket 0.0.0.0:8000 --uid uwsgi --plugins python3 --protocol uwsgi --wsgi ${pythonModule}:${pythonVariable}`
|
||||||
);
|
);
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
}
|
}
|
||||||
const endpoint = `/applications/${params.id}.json`;
|
const endpoint = `/applications/${params.id}.json`;
|
||||||
const res = await fetch(endpoint);
|
const res = await fetch(endpoint);
|
||||||
|
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
@ -19,7 +18,6 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: res.status,
|
status: res.status,
|
||||||
error: new Error(`Could not load ${endpoint}`)
|
error: new Error(`Could not load ${endpoint}`)
|
||||||
@ -41,28 +39,27 @@
|
|||||||
import { errorNotification } from '$lib/form';
|
import { errorNotification } from '$lib/form';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import Select from 'svelte-select';
|
import Select from 'svelte-select';
|
||||||
|
|
||||||
import Explainer from '$lib/components/Explainer.svelte';
|
import Explainer from '$lib/components/Explainer.svelte';
|
||||||
import Setting from '$lib/components/Setting.svelte';
|
import Setting from '$lib/components/Setting.svelte';
|
||||||
import type Prisma from '@prisma/client';
|
import type Prisma from '@prisma/client';
|
||||||
import { notNodeDeployments, staticDeployments } from '$lib/components/common';
|
import { getDomain, notNodeDeployments, staticDeployments } from '$lib/components/common';
|
||||||
import { toast } from '@zerodevx/svelte-toast';
|
import { toast } from '@zerodevx/svelte-toast';
|
||||||
import { post } from '$lib/api';
|
import { get, post } from '$lib/api';
|
||||||
import cuid from 'cuid';
|
import cuid from 'cuid';
|
||||||
import { browser } from '$app/env';
|
import { browser } from '$app/env';
|
||||||
import { disabledButton } from '$lib/store';
|
import { disabledButton } from '$lib/store';
|
||||||
import { t } from '$lib/translations';
|
import { t } from '$lib/translations';
|
||||||
const { id } = $page.params;
|
const { id } = $page.params;
|
||||||
|
|
||||||
let domainEl: HTMLInputElement;
|
let domainEl: HTMLInputElement;
|
||||||
|
|
||||||
let loading = false;
|
let loading = false;
|
||||||
let forceSave = false;
|
let forceSave = false;
|
||||||
let debug = application.settings.debug;
|
let debug = application.settings.debug;
|
||||||
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 nonWWWDomain = application.fqdn && getDomain(application.fqdn).replace(/^www\./, '');
|
||||||
|
let isNonWWWDomainOK = false;
|
||||||
|
let isWWWDomainOK = false;
|
||||||
let wsgis = [
|
let wsgis = [
|
||||||
{
|
{
|
||||||
value: 'None',
|
value: 'None',
|
||||||
@ -88,7 +85,6 @@
|
|||||||
onMount(() => {
|
onMount(() => {
|
||||||
domainEl.focus();
|
domainEl.focus();
|
||||||
});
|
});
|
||||||
|
|
||||||
async function changeSettings(name) {
|
async function changeSettings(name) {
|
||||||
if (name === 'debug') {
|
if (name === 'debug') {
|
||||||
debug = !debug;
|
debug = !debug;
|
||||||
@ -131,13 +127,31 @@
|
|||||||
async function handleSubmit() {
|
async function handleSubmit() {
|
||||||
loading = true;
|
loading = true;
|
||||||
try {
|
try {
|
||||||
await post(`/applications/${id}/check.json`, { fqdn: application.fqdn, forceSave });
|
nonWWWDomain = application.fqdn && getDomain(application.fqdn).replace(/^www\./, '');
|
||||||
|
await post(`/applications/${id}/check.json`, {
|
||||||
|
fqdn: application.fqdn,
|
||||||
|
forceSave,
|
||||||
|
dualCerts,
|
||||||
|
exposePort: application.exposePort
|
||||||
|
});
|
||||||
await post(`/applications/${id}.json`, { ...application });
|
await post(`/applications/${id}.json`, { ...application });
|
||||||
$disabledButton = false;
|
$disabledButton = false;
|
||||||
|
forceSave = false;
|
||||||
return toast.push('Configurations saved.');
|
return toast.push('Configurations saved.');
|
||||||
} catch ({ error }) {
|
} catch ({ error }) {
|
||||||
if (error?.startsWith($t('application.dns_not_set_partial_error'))) {
|
if (error?.startsWith($t('application.dns_not_set_partial_error'))) {
|
||||||
forceSave = true;
|
forceSave = true;
|
||||||
|
if (dualCerts) {
|
||||||
|
isNonWWWDomainOK = await isDNSValid(getDomain(nonWWWDomain), false);
|
||||||
|
isWWWDomainOK = await isDNSValid(getDomain(`www.${nonWWWDomain}`), true);
|
||||||
|
} else {
|
||||||
|
const isWWW = getDomain(application.fqdn).includes('www.');
|
||||||
|
if (isWWW) {
|
||||||
|
isWWWDomainOK = await isDNSValid(getDomain(`www.${nonWWWDomain}`), true);
|
||||||
|
} else {
|
||||||
|
isNonWWWDomainOK = await isDNSValid(getDomain(nonWWWDomain), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return errorNotification(error);
|
return errorNotification(error);
|
||||||
} finally {
|
} finally {
|
||||||
@ -155,6 +169,18 @@
|
|||||||
application.baseBuildImage = event.detail.value;
|
application.baseBuildImage = event.detail.value;
|
||||||
await handleSubmit();
|
await handleSubmit();
|
||||||
}
|
}
|
||||||
|
async function isDNSValid(domain, isWWW) {
|
||||||
|
try {
|
||||||
|
await get(`/applications/${id}/check.json?domain=${domain}`);
|
||||||
|
toast.push('DNS configuration is valid.');
|
||||||
|
isWWW ? (isWWWDomainOK = true) : (isNonWWWDomainOK = true);
|
||||||
|
return true;
|
||||||
|
} catch ({ error }) {
|
||||||
|
errorNotification(error);
|
||||||
|
isWWW ? (isWWWDomainOK = false) : (isNonWWWDomainOK = false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex items-center space-x-2 p-5 px-6 font-bold">
|
<div class="flex items-center space-x-2 p-5 px-6 font-bold">
|
||||||
@ -164,7 +190,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<span class="text-xs">{application.name} </span>
|
<span class="text-xs">{application.name} </span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if application.fqdn}
|
{#if application.fqdn}
|
||||||
<a
|
<a
|
||||||
href={application.fqdn}
|
href={application.fqdn}
|
||||||
@ -229,7 +254,6 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mx-auto max-w-4xl px-6">
|
<div class="mx-auto max-w-4xl px-6">
|
||||||
<!-- svelte-ignore missing-declaration -->
|
<!-- svelte-ignore missing-declaration -->
|
||||||
<form on:submit|preventDefault={handleSubmit} class="py-4">
|
<form on:submit|preventDefault={handleSubmit} class="py-4">
|
||||||
@ -327,6 +351,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{#if application.buildPack !== 'docker'}
|
||||||
<div class="grid grid-cols-2 items-center">
|
<div class="grid grid-cols-2 items-center">
|
||||||
<label for="baseImage" class="text-base font-bold text-stone-100"
|
<label for="baseImage" class="text-base font-bold text-stone-100"
|
||||||
>{$t('application.base_image')}</label
|
>{$t('application.base_image')}</label
|
||||||
@ -345,12 +370,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<Explainer text={$t('application.base_image_explainer')} />
|
<Explainer text={$t('application.base_image_explainer')} />
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
{#if application.buildCommand || application.buildPack === 'rust' || application.buildPack === 'laravel'}
|
{#if application.buildCommand || application.buildPack === 'rust' || application.buildPack === 'laravel'}
|
||||||
<div class="grid grid-cols-2 items-center pb-8">
|
<div class="grid grid-cols-2 items-center pb-8">
|
||||||
<label for="baseBuildImage" class="text-base font-bold text-stone-100"
|
<label for="baseBuildImage" class="text-base font-bold text-stone-100"
|
||||||
>{$t('application.base_build_image')}</label
|
>{$t('application.base_build_image')}</label
|
||||||
>
|
>
|
||||||
|
|
||||||
<div class="custom-select-wrapper">
|
<div class="custom-select-wrapper">
|
||||||
<Select
|
<Select
|
||||||
isDisabled={!$session.isAdmin || isRunning}
|
isDisabled={!$session.isAdmin || isRunning}
|
||||||
@ -387,6 +412,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
<Explainer text={$t('application.https_explainer')} />
|
<Explainer text={$t('application.https_explainer')} />
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
<input
|
<input
|
||||||
readonly={!$session.isAdmin || isRunning}
|
readonly={!$session.isAdmin || isRunning}
|
||||||
disabled={!$session.isAdmin || isRunning}
|
disabled={!$session.isAdmin || isRunning}
|
||||||
@ -396,8 +422,42 @@
|
|||||||
bind:value={application.fqdn}
|
bind:value={application.fqdn}
|
||||||
pattern="^https?://([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{'{'}2,{'}'}$"
|
pattern="^https?://([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{'{'}2,{'}'}$"
|
||||||
placeholder="eg: https://coollabs.io"
|
placeholder="eg: https://coollabs.io"
|
||||||
required
|
|
||||||
/>
|
/>
|
||||||
|
{#if forceSave}
|
||||||
|
<div class="flex-col space-y-2 pt-4 text-center">
|
||||||
|
{#if isNonWWWDomainOK}
|
||||||
|
<button
|
||||||
|
class="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="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
|
||||||
|
class="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="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 class="grid grid-cols-2 items-center pb-8">
|
<div class="grid grid-cols-2 items-center pb-8">
|
||||||
<Setting
|
<Setting
|
||||||
@ -412,12 +472,11 @@
|
|||||||
</div>
|
</div>
|
||||||
{#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</label>
|
||||||
<div class="custom-select-wrapper">
|
<div class="custom-select-wrapper">
|
||||||
<Select id="wsgi" items={wsgis} on:select={selectWSGI} value={application.pythonWSGI} />
|
<Select id="wsgi" items={wsgis} on:select={selectWSGI} value={application.pythonWSGI} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<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">Module</label>
|
<label for="pythonModule" class="text-base font-bold text-stone-100">Module</label>
|
||||||
<input
|
<input
|
||||||
@ -468,9 +527,24 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if application.buildPack !== 'docker'}
|
||||||
{#if !notNodeDeployments.includes(application.buildPack)}
|
|
||||||
<div class="grid grid-cols-2 items-center">
|
<div class="grid grid-cols-2 items-center">
|
||||||
|
<label for="exposePort" class="text-base font-bold text-stone-100">Exposed Port</label>
|
||||||
|
<input
|
||||||
|
readonly={!$session.isAdmin && !isRunning}
|
||||||
|
disabled={!$session.isAdmin || isRunning}
|
||||||
|
name="exposePort"
|
||||||
|
id="exposePort"
|
||||||
|
bind:value={application.exposePort}
|
||||||
|
placeholder="12345"
|
||||||
|
/>
|
||||||
|
<Explainer
|
||||||
|
text={'You can expose your application to a port on the host system.<br><br>Useful if you would like to use your own reverse proxy or tunnel and also in development mode. Otherwise leave empty.'}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{#if !notNodeDeployments.includes(application.buildPack)}
|
||||||
|
<div class="grid grid-cols-2 items-center pt-4">
|
||||||
<label for="installCommand" class="text-base font-bold text-stone-100"
|
<label for="installCommand" class="text-base font-bold text-stone-100"
|
||||||
>{$t('application.install_command')}</label
|
>{$t('application.install_command')}</label
|
||||||
>
|
>
|
||||||
@ -508,7 +582,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if application.buildPack === 'docker'}
|
{#if application.buildPack === 'docker'}
|
||||||
<div class="grid grid-cols-2 items-center">
|
<div class="grid grid-cols-2 items-center pt-4">
|
||||||
<label for="dockerFileLocation" class="text-base font-bold text-stone-100"
|
<label for="dockerFileLocation" class="text-base font-bold text-stone-100"
|
||||||
>Dockerfile Location</label
|
>Dockerfile Location</label
|
||||||
>
|
>
|
||||||
@ -574,7 +648,6 @@
|
|||||||
>
|
>
|
||||||
<Explainer text={$t('application.publish_directory_explainer')} />
|
<Explainer text={$t('application.publish_directory_explainer')} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
readonly={!$session.isAdmin}
|
readonly={!$session.isAdmin}
|
||||||
name="publishDirectory"
|
name="publishDirectory"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user