Skip to content

Commit

Permalink
v1.0.14 (#48)
Browse files Browse the repository at this point in the history
# Features
- Basic Python support

# Fixes
- Fix default start command
  • Loading branch information
andrasbacsai authored May 22, 2021
1 parent adcd68c commit c7efe89
Show file tree
Hide file tree
Showing 12 changed files with 225 additions and 64 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
144 changes: 94 additions & 50 deletions src/components/Application/ActiveTab/General.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@
},
build: false,
start: false
},
python: {
port: {
active: true,
number: 4000
},
build: false,
start: false,
custom: true
}
};
function selectBuildPack(event) {
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down
7 changes: 5 additions & 2 deletions src/components/Application/Tabs.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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
}
Expand Down
5 changes: 5 additions & 0 deletions src/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ export type Application = {
build: string | null;
installation: string;
start: string;
python: {
module?: string;
instance?: string;
}

};
container: {
name: string;
Expand Down
1 change: 0 additions & 1 deletion src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
25 changes: 20 additions & 5 deletions src/lib/api/applications/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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')
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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}`
);
}
Expand Down
4 changes: 3 additions & 1 deletion src/lib/api/applications/packs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -23,5 +24,6 @@ export {
nextjs,
nestjs,
gatsby,
docker
docker,
python
};
2 changes: 1 addition & 1 deletion src/lib/api/applications/packs/php/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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');
};

Expand Down
27 changes: 27 additions & 0 deletions src/lib/api/applications/packs/python/index.ts
Original file line number Diff line number Diff line change
@@ -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);
}
5 changes: 5 additions & 0 deletions src/models/Configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Expand Down
Loading

0 comments on commit c7efe89

Please sign in to comment.