diff --git a/src/lib/buildPacks/python.ts b/src/lib/buildPacks/python.ts index edced9c20..5b3b8d787 100644 --- a/src/lib/buildPacks/python.ts +++ b/src/lib/buildPacks/python.ts @@ -36,8 +36,7 @@ const createDockerfile = async (data, image): Promise => { Dockerfile.push(`RUN pip install gunicorn`); } else if (pythonWSGI?.toLowerCase() === "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 pip install --no-cache-dir uwsgi`) } @@ -52,12 +51,11 @@ const createDockerfile = async (data, image): Promise => { Dockerfile.push(`COPY .${baseDirectory || ''} ./`); Dockerfile.push(`EXPOSE ${port}`); 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") { Dockerfile.push(`CMD uvicorn ${pythonModule}:${pythonVariable} --reload --port ${port}`); - } - else if (pythonWSGI?.toLowerCase() === 'uwsgi') { + } else if (pythonWSGI?.toLowerCase() === 'uwsgi') { Dockerfile.push( `CMD uwsgi --master -p 4 --http-socket 0.0.0.0:8000 --uid uwsgi --plugins python3 --protocol uwsgi --wsgi ${pythonModule}:${pythonVariable}` ); @@ -76,4 +74,4 @@ export default async function (data) { } catch (error) { throw error; } -} +} \ No newline at end of file diff --git a/src/routes/applications/[id]/index.svelte b/src/routes/applications/[id]/index.svelte index 134f02467..1e9e2716e 100644 --- a/src/routes/applications/[id]/index.svelte +++ b/src/routes/applications/[id]/index.svelte @@ -11,7 +11,6 @@ } const endpoint = `/applications/${params.id}.json`; const res = await fetch(endpoint); - if (res.ok) { return { props: { @@ -19,7 +18,6 @@ } }; } - return { status: res.status, error: new Error(`Could not load ${endpoint}`) @@ -41,28 +39,27 @@ import { errorNotification } from '$lib/form'; import { onMount } from 'svelte'; import Select from 'svelte-select'; - import Explainer from '$lib/components/Explainer.svelte'; import Setting from '$lib/components/Setting.svelte'; 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 { post } from '$lib/api'; + import { get, post } from '$lib/api'; import cuid from 'cuid'; import { browser } from '$app/env'; import { disabledButton } from '$lib/store'; import { t } from '$lib/translations'; const { id } = $page.params; - let domainEl: HTMLInputElement; - let loading = false; let forceSave = false; let debug = application.settings.debug; let previews = application.settings.previews; let dualCerts = application.settings.dualCerts; let autodeploy = application.settings.autodeploy; - + let nonWWWDomain = application.fqdn && getDomain(application.fqdn).replace(/^www\./, ''); + let isNonWWWDomainOK = false; + let isWWWDomainOK = false; let wsgis = [ { value: 'None', @@ -88,7 +85,6 @@ onMount(() => { domainEl.focus(); }); - async function changeSettings(name) { if (name === 'debug') { debug = !debug; @@ -131,13 +127,31 @@ async function handleSubmit() { loading = true; 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 }); $disabledButton = false; + forceSave = false; return toast.push('Configurations saved.'); } catch ({ error }) { if (error?.startsWith($t('application.dns_not_set_partial_error'))) { 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); } finally { @@ -155,6 +169,18 @@ application.baseBuildImage = event.detail.value; 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; + } + }
@@ -164,7 +190,6 @@
{application.name} - {#if application.fqdn} -
@@ -327,30 +351,31 @@ />
-
- -
- +
+
- - + {/if} {#if application.buildCommand || application.buildPack === 'rust' || application.buildPack === 'laravel'}
-
+
+ + {#if forceSave} +
+ {#if isNonWWWDomainOK} + + {:else} + + {/if} + {#if dualCerts} + {#if isWWWDomainOK} + + {:else} + + {/if} + {/if} +
+ {/if} +
{#if application.buildPack === 'python'}
- +
{/if} - - {#if !notNodeDeployments.includes(application.buildPack)} + {#if application.buildPack !== 'docker'}
+ + +
Useful if you would like to use your own reverse proxy or tunnel and also in development mode. Otherwise leave empty.'} + /> +
+ {/if} + {#if !notNodeDeployments.includes(application.buildPack)} +
@@ -508,7 +582,7 @@
{/if} {#if application.buildPack === 'docker'} -
+
@@ -574,7 +648,6 @@ >
-