v1.0.14 (#48)
# Features - Basic Python support # Fixes - Fix default start command
This commit is contained in:
parent
adcd68c1ab
commit
c7efe899fa
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "coolify",
|
||||
"description": "An open-source, hassle-free, self-hostable Heroku & Netlify alternative.",
|
||||
"version": "1.0.13",
|
||||
"version": "1.0.14",
|
||||
"license": "AGPL-3.0",
|
||||
"scripts": {
|
||||
"dev:docker:start": "docker-compose -f docker-compose-dev.yml up -d",
|
||||
|
@ -99,6 +99,15 @@
|
||||
},
|
||||
build: false,
|
||||
start: false
|
||||
},
|
||||
python: {
|
||||
port: {
|
||||
active: true,
|
||||
number: 4000
|
||||
},
|
||||
build: false,
|
||||
start: false,
|
||||
custom: true
|
||||
}
|
||||
};
|
||||
function selectBuildPack(event) {
|
||||
@ -214,6 +223,14 @@
|
||||
>
|
||||
Docker
|
||||
</div>
|
||||
<div
|
||||
class={$application.build.pack === 'python'
|
||||
? 'buildpack bg-green-500'
|
||||
: 'buildpack hover:border-green-500'}
|
||||
on:click={selectBuildPack}
|
||||
>
|
||||
Python
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-2xl font-bold border-gradient w-52">General settings</div>
|
||||
@ -282,68 +299,95 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="text-2xl font-bold w-40"
|
||||
class:border-gradient={buildpacks[$application.build.pack].build}
|
||||
class:text-warmGray-800={!buildpacks[$application.build.pack].build}
|
||||
class="text-2xl font-bold w-40 border-gradient"
|
||||
>
|
||||
Commands
|
||||
</div>
|
||||
<div class=" max-w-2xl md:mx-auto mx-6 justify-center items-center pt-10 pb-32">
|
||||
<div class="grid grid-flow-col gap-2 items-center">
|
||||
<div class="grid grid-flow-row">
|
||||
<label
|
||||
for="installCommand"
|
||||
class:text-warmGray-800={!buildpacks[$application.build.pack].build}
|
||||
>Install Command <TooltipInfo
|
||||
label="Command to run for installing dependencies. eg: yarn install"
|
||||
{#if $application.build.pack === 'python'}
|
||||
<label for="ModulePackageName"
|
||||
>Module/Package Name<TooltipInfo
|
||||
label="The module/package name to start (eg: the entry filename [main], without the py extension. See gunicorn.org for more details)"
|
||||
/>
|
||||
</label>
|
||||
|
||||
<input
|
||||
class="mb-6"
|
||||
id="ModulePackageName"
|
||||
bind:value={$application.build.command.python.module}
|
||||
placeholder="main"
|
||||
/>
|
||||
<label for="ApplicationInstance"
|
||||
>Application Instance<TooltipInfo
|
||||
label="The instance name (the main function name. See gunicorn.org for more details)"
|
||||
/>
|
||||
</label>
|
||||
|
||||
<input
|
||||
class="mb-6"
|
||||
class:bg-warmGray-900={!buildpacks[$application.build.pack].build}
|
||||
class:text-warmGray-900={!buildpacks[$application.build.pack].build}
|
||||
class:placeholder-warmGray-800={!buildpacks[$application.build.pack].build}
|
||||
class:hover:bg-warmGray-900={!buildpacks[$application.build.pack].build}
|
||||
class:cursor-not-allowed={!buildpacks[$application.build.pack].build}
|
||||
id="installCommand"
|
||||
bind:value={$application.build.command.installation}
|
||||
placeholder="eg: yarn install"
|
||||
/>
|
||||
<label
|
||||
for="buildCommand"
|
||||
class:text-warmGray-800={!buildpacks[$application.build.pack].build}
|
||||
>Build Command <TooltipInfo
|
||||
label="Command to run for building your application. If empty, no build phase initiated in the deploy process."
|
||||
/></label
|
||||
>
|
||||
<input
|
||||
class="mb-6"
|
||||
class:bg-warmGray-900={!buildpacks[$application.build.pack].build}
|
||||
class:text-warmGray-900={!buildpacks[$application.build.pack].build}
|
||||
class:placeholder-warmGray-800={!buildpacks[$application.build.pack].build}
|
||||
class:hover:bg-warmGray-900={!buildpacks[$application.build.pack].build}
|
||||
class:cursor-not-allowed={!buildpacks[$application.build.pack].build}
|
||||
id="buildCommand"
|
||||
bind:value={$application.build.command.build}
|
||||
placeholder="eg: yarn build"
|
||||
/>
|
||||
<label
|
||||
for="startCommand"
|
||||
class:text-warmGray-800={!buildpacks[$application.build.pack].start}
|
||||
>Start Command <TooltipInfo label="Command to start the application. eg: yarn start" /></label
|
||||
>
|
||||
<input
|
||||
class="mb-6"
|
||||
class:bg-warmGray-900={!buildpacks[$application.build.pack].start}
|
||||
class:text-warmGray-900={!buildpacks[$application.build.pack].start}
|
||||
class:placeholder-warmGray-800={!buildpacks[$application.build.pack].start}
|
||||
class:hover:bg-warmGray-900={!buildpacks[$application.build.pack].start}
|
||||
class:cursor-not-allowed={!buildpacks[$application.build.pack].start}
|
||||
id="startcommand"
|
||||
bind:value={$application.build.command.start}
|
||||
placeholder="eg: yarn start"
|
||||
id="ApplicationInstance"
|
||||
bind:value={$application.build.command.python.instance}
|
||||
placeholder="app"
|
||||
/>
|
||||
{:else}
|
||||
<label
|
||||
for="installCommand"
|
||||
class:text-warmGray-800={!buildpacks[$application.build.pack].build}
|
||||
>Install Command <TooltipInfo
|
||||
label="Command to run for installing dependencies. eg: yarn install"
|
||||
/>
|
||||
</label>
|
||||
|
||||
<input
|
||||
class="mb-6"
|
||||
class:bg-warmGray-900={!buildpacks[$application.build.pack].build}
|
||||
class:text-warmGray-900={!buildpacks[$application.build.pack].build}
|
||||
class:placeholder-warmGray-800={!buildpacks[$application.build.pack].build}
|
||||
class:hover:bg-warmGray-900={!buildpacks[$application.build.pack].build}
|
||||
class:cursor-not-allowed={!buildpacks[$application.build.pack].build}
|
||||
id="installCommand"
|
||||
bind:value={$application.build.command.installation}
|
||||
placeholder="eg: yarn install"
|
||||
/>
|
||||
<label
|
||||
for="buildCommand"
|
||||
class:text-warmGray-800={!buildpacks[$application.build.pack].build}
|
||||
>Build Command <TooltipInfo
|
||||
label="Command to run for building your application. If empty, no build phase initiated in the deploy process."
|
||||
/></label
|
||||
>
|
||||
<input
|
||||
class="mb-6"
|
||||
class:bg-warmGray-900={!buildpacks[$application.build.pack].build}
|
||||
class:text-warmGray-900={!buildpacks[$application.build.pack].build}
|
||||
class:placeholder-warmGray-800={!buildpacks[$application.build.pack].build}
|
||||
class:hover:bg-warmGray-900={!buildpacks[$application.build.pack].build}
|
||||
class:cursor-not-allowed={!buildpacks[$application.build.pack].build}
|
||||
id="buildCommand"
|
||||
bind:value={$application.build.command.build}
|
||||
placeholder="eg: yarn build"
|
||||
/>
|
||||
<label
|
||||
for="startCommand"
|
||||
class:text-warmGray-800={!buildpacks[$application.build.pack].start}
|
||||
>Start Command <TooltipInfo
|
||||
label="Command to start the application. eg: yarn start"
|
||||
/></label
|
||||
>
|
||||
<input
|
||||
class="mb-6"
|
||||
class:bg-warmGray-900={!buildpacks[$application.build.pack].start}
|
||||
class:text-warmGray-900={!buildpacks[$application.build.pack].start}
|
||||
class:placeholder-warmGray-800={!buildpacks[$application.build.pack].start}
|
||||
class:hover:bg-warmGray-900={!buildpacks[$application.build.pack].start}
|
||||
class:cursor-not-allowed={!buildpacks[$application.build.pack].start}
|
||||
id="startcommand"
|
||||
bind:value={$application.build.command.start}
|
||||
placeholder="eg: yarn start"
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -66,7 +66,7 @@
|
||||
const packageJson = dir.find((f) => f.type === 'file' && f.name === 'package.json');
|
||||
const Dockerfile = dir.find((f) => f.type === 'file' && f.name === 'Dockerfile');
|
||||
const CargoToml = dir.find((f) => f.type === 'file' && f.name === 'Cargo.toml');
|
||||
|
||||
const requirementsTXT = dir.find((f) => f.type === 'file' && f.name === 'requirements.txt');
|
||||
if (packageJson) {
|
||||
const { content } = await request(packageJson.git_url, $session);
|
||||
const packageJsonContent = JSON.parse(atob(content));
|
||||
@ -102,10 +102,13 @@
|
||||
} else if (CargoToml) {
|
||||
$application.build.pack = 'rust';
|
||||
browser && toast.push(`Rust language detected. Default values set.`);
|
||||
} else if (requirementsTXT) {
|
||||
$application.build.pack = 'python'
|
||||
browser && toast.push('Python language detected. Default values set.');
|
||||
} else if (Dockerfile) {
|
||||
$application.build.pack = 'docker';
|
||||
browser && toast.push('Custom Dockerfile found. Build pack set to docker.');
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// Nothing detected
|
||||
}
|
||||
|
5
src/global.d.ts
vendored
5
src/global.d.ts
vendored
@ -44,6 +44,11 @@ export type Application = {
|
||||
build: string | null;
|
||||
installation: string;
|
||||
start: string;
|
||||
python: {
|
||||
module?: string;
|
||||
instance?: string;
|
||||
}
|
||||
|
||||
};
|
||||
container: {
|
||||
name: string;
|
||||
|
@ -39,7 +39,6 @@ async function connectMongoDB() {
|
||||
}
|
||||
|
||||
(async () => {
|
||||
console.log(mongoose.connection.readyState)
|
||||
if (mongoose.connection.readyState !== 1) await connectMongoDB();
|
||||
try {
|
||||
await mongoose.connection.db.dropCollection('logs-servers');
|
||||
|
@ -29,9 +29,12 @@ export function setDefaultConfiguration(configuration) {
|
||||
configuration.build.pack === 'vuejs' ||
|
||||
configuration.build.pack === 'nuxtjs' ||
|
||||
configuration.build.pack === 'rust' ||
|
||||
configuration.build.pack === 'nextjs'
|
||||
configuration.build.pack === 'nextjs' ||
|
||||
configuration.build.pack === 'nestjs'
|
||||
) {
|
||||
configuration.publish.port = 3000;
|
||||
} else if (configuration.build.pack === 'python') {
|
||||
configuration.publish.port = 4000;
|
||||
} else {
|
||||
configuration.publish.port = 80;
|
||||
}
|
||||
@ -48,6 +51,19 @@ export function setDefaultConfiguration(configuration) {
|
||||
if (!configuration.build.command.installation)
|
||||
configuration.build.command.installation = 'yarn install';
|
||||
}
|
||||
if (
|
||||
configuration.build.pack === 'nodejs' ||
|
||||
configuration.build.pack === 'vuejs' ||
|
||||
configuration.build.pack === 'nuxtjs' ||
|
||||
configuration.build.pack === 'nextjs' ||
|
||||
configuration.build.pack === 'nestjs'
|
||||
) {
|
||||
if (!configuration.build.command.start) configuration.build.command.start = 'yarn start'
|
||||
}
|
||||
if (configuration.build.pack === 'python') {
|
||||
if (!configuration.build.command.python.module) configuration.build.command.python.module = 'main'
|
||||
if (!configuration.build.command.python.instance) configuration.build.command.python.instance = 'app'
|
||||
}
|
||||
|
||||
configuration.build.container.baseSHA = crypto
|
||||
.createHash('sha256')
|
||||
@ -103,9 +119,9 @@ export async function precheckDeployment({ services, configuration }) {
|
||||
// If only the configuration changed
|
||||
if (
|
||||
JSON.stringify(runningWithoutContainer.build) !==
|
||||
JSON.stringify(configurationWithoutContainer.build) ||
|
||||
JSON.stringify(configurationWithoutContainer.build) ||
|
||||
JSON.stringify(runningWithoutContainer.publish) !==
|
||||
JSON.stringify(configurationWithoutContainer.publish)
|
||||
JSON.stringify(configurationWithoutContainer.publish)
|
||||
)
|
||||
configChanged = true;
|
||||
// If only the image changed
|
||||
@ -148,8 +164,7 @@ export async function updateServiceLabels(configuration) {
|
||||
await execShellAsync(
|
||||
`docker service update --label-add configuration='${JSON.stringify(
|
||||
Labels
|
||||
)}' --label-add com.docker.stack.image='${configuration.build.container.name}:${
|
||||
configuration.build.container.tag
|
||||
)}' --label-add com.docker.stack.image='${configuration.build.container.name}:${configuration.build.container.tag
|
||||
}' ${ID}`
|
||||
);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import nextjs from './nextjs';
|
||||
import nestjs from './nestjs';
|
||||
import gatsby from './gatsby';
|
||||
import docker from './docker';
|
||||
import python from './python';
|
||||
|
||||
export {
|
||||
vuejs,
|
||||
@ -23,5 +24,6 @@ export {
|
||||
nextjs,
|
||||
nestjs,
|
||||
gatsby,
|
||||
docker
|
||||
docker,
|
||||
python
|
||||
};
|
||||
|
@ -8,7 +8,7 @@ const publishPHPDocker = (configuration) => {
|
||||
'WORKDIR /usr/src/app',
|
||||
`COPY ./${configuration.build.directory} /var/www/html`,
|
||||
'EXPOSE 80',
|
||||
' CMD ["apache2-foreground"]'
|
||||
'CMD ["apache2-foreground"]'
|
||||
].join('\n');
|
||||
};
|
||||
|
||||
|
27
src/lib/api/applications/packs/python/index.ts
Normal file
27
src/lib/api/applications/packs/python/index.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { docker, streamEvents } from '$lib/api/docker';
|
||||
import { promises as fs } from 'fs';
|
||||
// `HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost:${configuration.publish.port}${configuration.publish.path} || exit 1`,
|
||||
const publishPython = (configuration) => {
|
||||
return [
|
||||
'FROM python:3-alpine',
|
||||
'WORKDIR /usr/src/app',
|
||||
'RUN pip install gunicorn',
|
||||
`COPY ./${configuration.build.directory}/requirements.txt ./`,
|
||||
`RUN pip install --no-cache-dir -r ./${configuration.build.directory}/requirements.txt`,
|
||||
`COPY ./${configuration.build.directory}/ .`,
|
||||
`EXPOSE ${configuration.publish.port}`,
|
||||
`CMD gunicorn -w=4 ${configuration.build.command.python.module}:${configuration.build.command.python.instance}`
|
||||
].join('\n');
|
||||
};
|
||||
|
||||
export default async function (configuration) {
|
||||
await fs.writeFile(
|
||||
`${configuration.general.workdir}/Dockerfile`,
|
||||
publishPython(configuration)
|
||||
);
|
||||
const stream = await docker.engine.buildImage(
|
||||
{ src: ['.'], context: configuration.general.workdir },
|
||||
{ t: `${configuration.build.container.name}:${configuration.build.container.tag}` }
|
||||
);
|
||||
await streamEvents(stream, configuration);
|
||||
}
|
@ -27,6 +27,11 @@ const ConfigurationSchema = new Schema({
|
||||
build: { type: String },
|
||||
installation: { type: String },
|
||||
start: { type: String },
|
||||
python: {
|
||||
module: { type: String },
|
||||
instance: { type: String },
|
||||
}
|
||||
|
||||
},
|
||||
container: {
|
||||
name: { type: String, required: true },
|
||||
|
@ -278,6 +278,57 @@
|
||||
fill-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
{:else if application.configuration.build.pack === 'python'}
|
||||
<svg class="w-14 h-14 absolute top-0 left-0 -m-6" viewBox="0 0 128 128">
|
||||
<linearGradient
|
||||
id="a"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="70.252"
|
||||
y1="1237.476"
|
||||
x2="170.659"
|
||||
y2="1151.089"
|
||||
gradientTransform="matrix(.563 0 0 -.568 -29.215 707.817)"
|
||||
><stop offset="0" stop-color="#5A9FD4" /><stop
|
||||
offset="1"
|
||||
stop-color="#306998"
|
||||
/></linearGradient
|
||||
><path
|
||||
fill="url(#a)"
|
||||
d="M63.391 1.988c-4.222.02-8.252.379-11.8 1.007-10.45 1.846-12.346 5.71-12.346 12.837v9.411h24.693v3.137h-33.961c-7.176 0-13.46 4.313-15.426 12.521-2.268 9.405-2.368 15.275 0 25.096 1.755 7.311 5.947 12.519 13.124 12.519h8.491v-11.282c0-8.151 7.051-15.34 15.426-15.34h24.665c6.866 0 12.346-5.654 12.346-12.548v-23.513c0-6.693-5.646-11.72-12.346-12.837-4.244-.706-8.645-1.027-12.866-1.008zm-13.354 7.569c2.55 0 4.634 2.117 4.634 4.721 0 2.593-2.083 4.69-4.634 4.69-2.56 0-4.633-2.097-4.633-4.69-.001-2.604 2.073-4.721 4.633-4.721z"
|
||||
/><linearGradient
|
||||
id="b"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="209.474"
|
||||
y1="1098.811"
|
||||
x2="173.62"
|
||||
y2="1149.537"
|
||||
gradientTransform="matrix(.563 0 0 -.568 -29.215 707.817)"
|
||||
><stop offset="0" stop-color="#FFD43B" /><stop
|
||||
offset="1"
|
||||
stop-color="#FFE873"
|
||||
/></linearGradient
|
||||
><path
|
||||
fill="url(#b)"
|
||||
d="M91.682 28.38v10.966c0 8.5-7.208 15.655-15.426 15.655h-24.665c-6.756 0-12.346 5.783-12.346 12.549v23.515c0 6.691 5.818 10.628 12.346 12.547 7.816 2.297 15.312 2.713 24.665 0 6.216-1.801 12.346-5.423 12.346-12.547v-9.412h-24.664v-3.138h37.012c7.176 0 9.852-5.005 12.348-12.519 2.578-7.735 2.467-15.174 0-25.096-1.774-7.145-5.161-12.521-12.348-12.521h-9.268zm-13.873 59.547c2.561 0 4.634 2.097 4.634 4.692 0 2.602-2.074 4.719-4.634 4.719-2.55 0-4.633-2.117-4.633-4.719 0-2.595 2.083-4.692 4.633-4.692z"
|
||||
/><radialGradient
|
||||
id="c"
|
||||
cx="1825.678"
|
||||
cy="444.45"
|
||||
r="26.743"
|
||||
gradientTransform="matrix(0 -.24 -1.055 0 532.979 557.576)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
><stop offset="0" stop-color="#B8B8B8" stop-opacity=".498" /><stop
|
||||
offset="1"
|
||||
stop-color="#7F7F7F"
|
||||
stop-opacity="0"
|
||||
/></radialGradient
|
||||
><path
|
||||
opacity=".444"
|
||||
fill="url(#c)"
|
||||
enable-background="new"
|
||||
d="M97.309 119.597c0 3.543-14.816 6.416-33.091 6.416-18.276 0-33.092-2.873-33.092-6.416 0-3.544 14.815-6.417 33.092-6.417 18.275 0 33.091 2.872 33.091 6.417z"
|
||||
/>
|
||||
</svg>
|
||||
{/if}
|
||||
<div class="flex flex-col justify-center items-center w-full">
|
||||
<div class="text-base font-bold text-center w-full text-white pb-6">
|
||||
|
@ -5,7 +5,7 @@ import type {
|
||||
DateTimeFormatOptions,
|
||||
GithubInstallations
|
||||
} from 'src/global';
|
||||
import { writable, derived, readable, Writable } from 'svelte/store';
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
export const dashboard = writable<Dashboard>({
|
||||
databases: {
|
||||
@ -55,7 +55,12 @@ export const application = writable<Application>({
|
||||
directory: null,
|
||||
command: {
|
||||
build: null,
|
||||
installation: null
|
||||
installation: null,
|
||||
start: null,
|
||||
python: {
|
||||
module: null,
|
||||
instance: null
|
||||
}
|
||||
},
|
||||
container: {
|
||||
name: null,
|
||||
@ -99,7 +104,12 @@ export const initialApplication: Application = {
|
||||
directory: null,
|
||||
command: {
|
||||
build: null,
|
||||
installation: null
|
||||
installation: null,
|
||||
start: null,
|
||||
python: {
|
||||
module: null,
|
||||
instance: null
|
||||
}
|
||||
},
|
||||
container: {
|
||||
name: null,
|
||||
|
Loading…
x
Reference in New Issue
Block a user