Merge branch 'canary' into 57-dokploy-api-or-cli

This commit is contained in:
Mauricio Siu 2024-06-21 21:49:41 -06:00
commit c5ace67b3f
24 changed files with 199 additions and 56 deletions

62
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@ -0,0 +1,62 @@
name: Bug Report
description: Create a bug report
labels: ['bug']
body:
- type: markdown
attributes:
value: |
Before opening a new issue, please do a search of existing issues.
If you need help with your own project, you can start a discussion in the [Q&A Section](https://github.com/Dokploy/dokploy/discussions).
- type: textarea
attributes:
label: To Reproduce
description: A step-by-step description of how to reproduce the issue, or a link to the reproducible repository.
placeholder: |
1. Create a application
2. Click X
3. Y will happen
validations:
required: true
- type: textarea
attributes:
label: Current vs. Expected behavior
description: A clear and concise description of what the bug is, and what you expected to happen.
placeholder: 'Following the steps from the previous section, I expected A to happen, but I observed B instead'
validations:
required: true
- type: textarea
attributes:
label: Provide environment information
description: Please provide the following information about your environment.
render: bash
placeholder: |
Operating System:
OS: Ubuntu 20.04
Arch: arm64
Dokploy version: 0.2.2'
VPS Provider: DigitalOcean, Hetzner, Linode, etc.
What applications/services are you tying to deploy?
eg - Database, Nextjs App, laravel, etc.
validations:
required: true
- type: dropdown
attributes:
label: Which area(s) are affected? (Select all that apply)
multiple: true
options:
- 'Installation'
- 'Application'
- 'Databases'
- 'Docker Compose'
- 'Traefik'
- 'Docker'
validations:
required: true
- type: textarea
attributes:
label: Additional context
description: |
Any extra information that might help us investigate.
placeholder: |
I tested on a DigitalOcean VPS with Ubuntu 20.04 and Docker version 20.10.12.

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Questions?
url: https://github.com/Dokploy/dokploy/discussions
about: Ask your questions here.

View File

@ -0,0 +1,33 @@
name: Feature Request
description: Suggest a new feature or improvement to the project
labels: ['enhancement']
body:
- type: textarea
attributes:
label: What problem will this feature address?
description: A clear and concise description of what the problem is.
placeholder: |
I'm always frustrated when I can't do X
validations:
required: true
- type: textarea
attributes:
label: Describe the solution you'd like
description: A clear and concise description of what you want to happen.
placeholder: Add X to the core
validations:
required: true
- type: textarea
attributes:
label: Describe alternatives you've considered
description: A clear and concise description of any alternative solutions or features you've considered.
placeholder: |
Maybe use Y as a workaround?
validations:
required: true
- type: textarea
attributes:
label: Additional context
description: Add any other context or screenshots about the feature request here.
validations:
required: false

View File

@ -1,36 +1,37 @@
<div align="center">
<h1 align="center">Dokploy</h1>
<div>
<img style="object-fit: cover; border-radius:20px;" align="center" width="50%"src="https://raw.githubusercontent.com/Dokploy/docs/main/public/logo.png" >
</div>
<div align="center" style="width:100%;">
<img src="https://raw.githubusercontent.com/Dokploy/dokploy/main/logo.png" alt="Reflex Logo" style="width:60%;">
</div>
<hr>
<br />
Dokploy is a free self-hostable Platform as a Service (PaaS) that simplifies the deployment and management of applications and databases.
### Features
Dokploy is a free self-hostable Platform as a Service (PaaS) that simplifies the deployment and management of applications and databases using Docker and Traefik. Designed to enhance efficiency and security, Dokploy allows you to deploy your applications on any VPS.
Dokploy include multiples features to make your life easier.
## Explanation
[English](README.md) | [中文](README-zh.md) | [Deutsch](README-de.md) | [Русский Язык](README-ru.md)
* **Applications**: Deploy any type of application (Node.js, PHP, Python, Go, Ruby, etc.).
* **Databases**: Create and manage databases with support for MySQL, PostgreSQL, MongoDB, MariaDB, Redis.
* **Backups**: Automate backups for databases to a external storage destination.
* **Docker Compose**: Native support for Docker Compose to manage complex applications.
* **Multi Node**: Scale applications to multiples nodes using docker swarm to manage the cluster.
* **Templates**: Deploy in a single click open source templates (Plausible, Pocketbase, Calcom, etc.).
* **Traefik Integration**: Automatically integrates with Traefik for routing and load balancing.
* **Real-time Monitoring**: Monitor CPU, memory, storage, and network usage, for every resource.
* **Docker Management**: Easily deploy and manage Docker containers.
* **CLI (Soon⌛)**: Manage your applications and databases using the command line.
* **Self-Hosted**: Self-host Dokploy on your VPS.
## 🌟 Features
- **Applications**: Deploy any type of application (Node.js, PHP, Python, Go, Ruby, etc.) with ease.
- **Databases**: Create and manage databases with support for MySQL, PostgreSQL, MongoDB, MariaDB, Redis, and more.
- **Docker Management**: Easily deploy and manage Docker containers.
- **Traefik Integration**: Automatically integrates with Traefik for routing and load balancing.
- **Real-time Monitoring**: Monitor CPU, memory, storage, and network usage.
- **Database Backups**: Automate backups with support for multiple storage destinations.
## 🚀 Getting Started
To get started run the following command in a VPS:
@ -40,20 +41,54 @@ To get started run the following command in a VPS:
curl -sSL https://dokploy.com/install.sh | sh
```
Tested Systems:
- Ubuntu 24.04 LTS (Noble Numbat)
- Ubuntu 23.10 (Mantic Minotaur)
- Ubuntu 22.04 LTS (Jammy Jellyfish)
- Ubuntu 20.04 LTS (Focal Fossa)
- Ubuntu 18.04 LTS (Bionic Beaver)
## 📄 Documentation
For detailed documentation, visit [docs.dokploy.com](https://docs.dokploy.com).
## Video Tutorial
<a href="https://youtu.be/mznYKPvhcfw">
<img src="https://dokploy.com/banner.webp" alt="Watch the video" width="400" style="border-radius:20px;"/>
</a>
## Donations
If you like dokploy, and want to support the project to cover the costs of hosting, testing and development new features, you can donate to the project using the following link:
Thanks to all the supporters!
https://opencollective.com/dokploy
<a href="https://opencollective.com/dokploy"><img src="https://opencollective.com/dokploy/individuals.svg?width=890"></a>
## Contributors
<a href="https://github.com/dokploy/dokploy/graphs/contributors">
<img src="https://contrib.rocks/image?repo=dokploy/dokploy" />
</a>
## Support OS
- Ubuntu 24.04 LTS
- Ubuntu 23.10
- Ubuntu 22.04 LTS
- Ubuntu 20.04 LTS
- Ubuntu 18.04 LTS
- Debian 12
- Debian 11
- Fedora 40
- Centos 9
- Centos 8
## 📄 Documentation
For detailed documentation, visit [docs.dokploy.com](https://docs.dokploy.com).
## Explanation
[English](README.md) | [中文](README-zh.md) | [Deutsch](README-de.md) | [Русский Язык](README-ru.md)

View File

@ -19,7 +19,7 @@ import {
import { api } from "@/utils/api";
import { AlertBlock } from "@/components/shared/alert-block";
import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect } from "react";
import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
@ -58,6 +58,7 @@ export const validateAndFormatYAML = (yamlText: string) => {
};
export const UpdateTraefikConfig = ({ applicationId }: Props) => {
const [open, setOpen] = useState(false);
const { data, refetch } = api.application.readTraefikConfig.useQuery(
{
applicationId,
@ -81,7 +82,7 @@ export const UpdateTraefikConfig = ({ applicationId }: Props) => {
traefikConfig: data || "",
});
}
}, [form, form.reset, data]);
}, [data]);
const onSubmit = async (data: UpdateTraefikConfig) => {
const { valid, error } = validateAndFormatYAML(data.traefikConfig);
@ -100,6 +101,8 @@ export const UpdateTraefikConfig = ({ applicationId }: Props) => {
.then(async () => {
toast.success("Traefik config Updated");
refetch();
setOpen(false);
form.reset();
})
.catch(() => {
toast.error("Error to update the traefik config");
@ -107,7 +110,12 @@ export const UpdateTraefikConfig = ({ applicationId }: Props) => {
};
return (
<Dialog>
<Dialog open={open} onOpenChange={(open) => {
setOpen(open)
if (!open) {
form.reset();
}
}}>
<DialogTrigger asChild>
<Button isLoading={isLoading}>Modify</Button>
</DialogTrigger>
@ -122,7 +130,7 @@ export const UpdateTraefikConfig = ({ applicationId }: Props) => {
<form
id="hook-form-update-traefik-config"
onSubmit={form.handleSubmit(onSubmit)}
className="grid w-full py-4 overflow-auto"
className="w-full space-y-4 overflow-auto"
>
<div className="flex flex-col">
<FormField

View File

@ -189,7 +189,7 @@ export const AddVolumes = ({
/>
<Label
htmlFor="bind"
className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-popover p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary"
className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-popover p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary cursor-pointer"
>
Bind Mount
</Label>
@ -209,7 +209,7 @@ export const AddVolumes = ({
/>
<Label
htmlFor="volume"
className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-popover p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary"
className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-popover p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary cursor-pointer"
>
Volume Mount
</Label>
@ -233,7 +233,7 @@ export const AddVolumes = ({
/>
<Label
htmlFor="file"
className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-popover p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary"
className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-popover p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary cursor-pointer"
>
File Mount
</Label>

View File

@ -124,7 +124,7 @@ export const ShowEnvironment = ({ applicationId }: Props) => {
<form
id="hook-form"
onSubmit={form.handleSubmit(onSubmit)}
className="grid w-full gap-4 "
className="w-full space-y-4"
>
<FormField
control={form.control}

View File

@ -124,7 +124,7 @@ export const ShowEnvironmentCompose = ({ composeId }: Props) => {
<form
id="hook-form"
onSubmit={form.handleSubmit(onSubmit)}
className="grid w-full gap-4 "
className="w-full space-y-4"
>
<FormField
control={form.control}

View File

@ -87,7 +87,7 @@ export const ComposeFileEditor = ({ composeId }: Props) => {
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="grid w-full relative gap-4"
className="w-full relative space-y-4"
>
<FormField
control={form.control}
@ -99,8 +99,8 @@ export const ComposeFileEditor = ({ composeId }: Props) => {
<CodeEditor
// disabled
value={field.value}
className="font-mono min-h-[20rem] compose-file-editor"
wrapperClassName="min-h-[20rem]"
className="font-mono"
wrapperClassName="compose-file-editor"
placeholder={`version: '3'
services:
web:

View File

@ -90,7 +90,7 @@ export const ShowTraefikFile = ({ path }: Props) => {
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="grid w-full relative z-[5]"
className="w-full relative z-[5]"
>
<div className="flex flex-col overflow-auto">
<FormField

View File

@ -85,7 +85,7 @@ export const ShowMariadbEnvironment = ({ mariadbId }: Props) => {
<form
id="hook-form"
onSubmit={form.handleSubmit(onSubmit)}
className="grid w-full gap-4 "
className="w-full space-y-4"
>
<FormField
control={form.control}

View File

@ -85,7 +85,7 @@ export const ShowMongoEnvironment = ({ mongoId }: Props) => {
<form
id="hook-form"
onSubmit={form.handleSubmit(onSubmit)}
className="grid w-full gap-4 "
className="w-full space-y-4"
>
<FormField
control={form.control}

View File

@ -85,7 +85,7 @@ export const ShowMysqlEnvironment = ({ mysqlId }: Props) => {
<form
id="hook-form"
onSubmit={form.handleSubmit(onSubmit)}
className="grid w-full gap-4 "
className="w-full space-y-4"
>
<FormField
control={form.control}

View File

@ -85,7 +85,7 @@ export const ShowPostgresEnvironment = ({ postgresId }: Props) => {
<form
id="hook-form"
onSubmit={form.handleSubmit(onSubmit)}
className="grid w-full gap-4 "
className="w-full space-y-4"
>
<FormField
control={form.control}

View File

@ -85,7 +85,7 @@ export const ShowRedisEnvironment = ({ redisId }: Props) => {
<form
id="hook-form"
onSubmit={form.handleSubmit(onSubmit)}
className="grid w-full gap-4 "
className="w-full space-y-4"
>
<FormField
control={form.control}

View File

@ -194,7 +194,7 @@ export const WebServer = () => {
Space
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56" align="start">
<DropdownMenuContent className="w-64" align="start">
<DropdownMenuLabel>Actions</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuGroup>

View File

@ -95,7 +95,7 @@ export const ShowMainTraefikConfig = ({ children }: Props) => {
<form
id="hook-form-update-main-traefik-config"
onSubmit={form.handleSubmit(onSubmit)}
className="grid w-full py-4 relative"
className="w-full space-y-4 relative"
>
<div className="flex flex-col">
<FormField

View File

@ -98,7 +98,7 @@ export const ShowServerMiddlewareConfig = ({ children }: Props) => {
<form
id="hook-form-update-server-traefik-config"
onSubmit={form.handleSubmit(onSubmit)}
className="grid w-full py-4 relative overflow-auto"
className="w-full space-y-4 relative overflow-auto"
>
<div className="flex flex-col">
<FormField

View File

@ -98,7 +98,7 @@ export const ShowServerTraefikConfig = ({ children }: Props) => {
<form
id="hook-form-update-server-traefik-config"
onSubmit={form.handleSubmit(onSubmit)}
className="grid w-full py-4 relative overflow-auto"
className="w-full space-y-4 relative overflow-auto"
>
<div className="flex flex-col">
<FormField

View File

@ -46,7 +46,7 @@ export const CodeEditor = ({
)}
/>
{props.disabled && (
<div className="absolute top-0 left-0 w-full h-full flex items-center justify-center z-[10] [background:var(--overlay)]" />
<div className="absolute top-0 rounded-md left-0 w-full h-full flex items-center justify-center z-[10] [background:var(--overlay)]" />
)}
</div>
);

View File

@ -36,12 +36,14 @@ const DialogContent = React.forwardRef<
<DialogPrimitive.Content
ref={ref}
className={cn(
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
"fixed left-[50%] top-[50%] z-50 w-full max-w-lg translate-x-[-50%] translate-y-[-50%] border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
className,
)}
{...props}
>
{children}
<div className="space-y-4 w-full">
{children}
</div>
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>

View File

@ -1,6 +1,6 @@
{
"name": "dokploy",
"version": "v0.2.2",
"version": "v0.2.3",
"private": true,
"license": "AGPL-3.0-only",
"type": "module",

View File

@ -8,7 +8,7 @@ import { getServiceContainer } from "../docker/utils";
// mongodb://mongo:Bqh7AQl-PRbnBu@localhost:27017/?tls=false&directConnection=true
export const runMongoBackup = async (mongo: Mongo, backup: BackupSchedule) => {
const { appName, databasePassword } = mongo;
const { appName, databasePassword, databaseUser } = mongo;
const { prefix, database } = backup;
const destination = backup.destination;
const backupFileName = `${new Date().toISOString()}.dump.gz`;
@ -23,7 +23,7 @@ export const runMongoBackup = async (mongo: Mongo, backup: BackupSchedule) => {
);
await execAsync(
`docker exec ${containerId} sh -c "mongodump -d '${database}' -u 'mongo' -p '${databasePassword}' --authenticationDatabase=admin --archive=${containerPath} --gzip"`,
`docker exec ${containerId} sh -c "mongodump -d '${database}' -u '${databaseUser}' -p '${databasePassword}' --authenticationDatabase=admin --archive=${containerPath} --gzip"`,
);
await execAsync(`docker cp ${containerId}:${containerPath} ${hostPath}`);
await uploadToS3(destination, bucketDestination, hostPath);

View File

@ -127,10 +127,8 @@
background-color: transparent;
}
.compose-file-editor .cm-editor {
@apply min-h-[25rem];
}