mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
feat: add deploy databases to external server
This commit is contained in:
@@ -35,6 +35,15 @@ import { useState } from "react";
|
|||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectGroup,
|
||||||
|
SelectItem,
|
||||||
|
SelectLabel,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from "@/components/ui/select";
|
||||||
|
|
||||||
type DbType = typeof mySchema._type.type;
|
type DbType = typeof mySchema._type.type;
|
||||||
|
|
||||||
@@ -71,6 +80,9 @@ const baseDatabaseSchema = z.object({
|
|||||||
databasePassword: z.string(),
|
databasePassword: z.string(),
|
||||||
dockerImage: z.string(),
|
dockerImage: z.string(),
|
||||||
description: z.string().nullable(),
|
description: z.string().nullable(),
|
||||||
|
serverId: z.string().min(1, {
|
||||||
|
message: "Server is required",
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const mySchema = z.discriminatedUnion("type", [
|
const mySchema = z.discriminatedUnion("type", [
|
||||||
@@ -145,6 +157,7 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
|
|||||||
const utils = api.useUtils();
|
const utils = api.useUtils();
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
const slug = slugify(projectName);
|
const slug = slugify(projectName);
|
||||||
|
const { data: servers } = api.server.all.useQuery();
|
||||||
const postgresMutation = api.postgres.create.useMutation();
|
const postgresMutation = api.postgres.create.useMutation();
|
||||||
const mongoMutation = api.mongo.create.useMutation();
|
const mongoMutation = api.mongo.create.useMutation();
|
||||||
const redisMutation = api.redis.create.useMutation();
|
const redisMutation = api.redis.create.useMutation();
|
||||||
@@ -183,6 +196,7 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
|
|||||||
appName: data.appName,
|
appName: data.appName,
|
||||||
dockerImage: defaultDockerImage,
|
dockerImage: defaultDockerImage,
|
||||||
projectId,
|
projectId,
|
||||||
|
serverId: data.serverId,
|
||||||
description: data.description,
|
description: data.description,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -191,8 +205,10 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
|
|||||||
...commonParams,
|
...commonParams,
|
||||||
databasePassword: data.databasePassword,
|
databasePassword: data.databasePassword,
|
||||||
databaseName: data.databaseName,
|
databaseName: data.databaseName,
|
||||||
|
|
||||||
databaseUser:
|
databaseUser:
|
||||||
data.databaseUser || databasesUserDefaultPlaceholder[data.type],
|
data.databaseUser || databasesUserDefaultPlaceholder[data.type],
|
||||||
|
serverId: data.serverId,
|
||||||
});
|
});
|
||||||
} else if (data.type === "mongo") {
|
} else if (data.type === "mongo") {
|
||||||
promise = mongoMutation.mutateAsync({
|
promise = mongoMutation.mutateAsync({
|
||||||
@@ -200,6 +216,7 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
|
|||||||
databasePassword: data.databasePassword,
|
databasePassword: data.databasePassword,
|
||||||
databaseUser:
|
databaseUser:
|
||||||
data.databaseUser || databasesUserDefaultPlaceholder[data.type],
|
data.databaseUser || databasesUserDefaultPlaceholder[data.type],
|
||||||
|
serverId: data.serverId,
|
||||||
});
|
});
|
||||||
} else if (data.type === "redis") {
|
} else if (data.type === "redis") {
|
||||||
promise = redisMutation.mutateAsync({
|
promise = redisMutation.mutateAsync({
|
||||||
@@ -215,6 +232,7 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
|
|||||||
databaseName: data.databaseName,
|
databaseName: data.databaseName,
|
||||||
databaseUser:
|
databaseUser:
|
||||||
data.databaseUser || databasesUserDefaultPlaceholder[data.type],
|
data.databaseUser || databasesUserDefaultPlaceholder[data.type],
|
||||||
|
serverId: data.serverId,
|
||||||
});
|
});
|
||||||
} else if (data.type === "mysql") {
|
} else if (data.type === "mysql") {
|
||||||
promise = mysqlMutation.mutateAsync({
|
promise = mysqlMutation.mutateAsync({
|
||||||
@@ -224,6 +242,7 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
|
|||||||
databaseUser:
|
databaseUser:
|
||||||
data.databaseUser || databasesUserDefaultPlaceholder[data.type],
|
data.databaseUser || databasesUserDefaultPlaceholder[data.type],
|
||||||
databaseRootPassword: data.databaseRootPassword,
|
databaseRootPassword: data.databaseRootPassword,
|
||||||
|
serverId: data.serverId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,6 +371,39 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="serverId"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Select a Server</FormLabel>
|
||||||
|
<Select
|
||||||
|
onValueChange={field.onChange}
|
||||||
|
defaultValue={field.value}
|
||||||
|
>
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="Select a Server" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectGroup>
|
||||||
|
{servers?.map((server) => (
|
||||||
|
<SelectItem
|
||||||
|
key={server.serverId}
|
||||||
|
value={server.serverId}
|
||||||
|
>
|
||||||
|
{server.name}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
<SelectLabel>
|
||||||
|
Servers ({servers?.length})
|
||||||
|
</SelectLabel>
|
||||||
|
</SelectGroup>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="appName"
|
name="appName"
|
||||||
|
|||||||
34
apps/dokploy/drizzle/0042_wandering_inhumans.sql
Normal file
34
apps/dokploy/drizzle/0042_wandering_inhumans.sql
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
ALTER TABLE "postgres" ADD COLUMN "serverId" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "mariadb" ADD COLUMN "serverId" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "mongo" ADD COLUMN "serverId" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "mysql" ADD COLUMN "serverId" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "redis" ADD COLUMN "serverId" text;--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "postgres" ADD CONSTRAINT "postgres_serverId_server_serverId_fk" FOREIGN KEY ("serverId") REFERENCES "public"."server"("serverId") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "mariadb" ADD CONSTRAINT "mariadb_serverId_server_serverId_fk" FOREIGN KEY ("serverId") REFERENCES "public"."server"("serverId") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "mongo" ADD CONSTRAINT "mongo_serverId_server_serverId_fk" FOREIGN KEY ("serverId") REFERENCES "public"."server"("serverId") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "mysql" ADD CONSTRAINT "mysql_serverId_server_serverId_fk" FOREIGN KEY ("serverId") REFERENCES "public"."server"("serverId") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "redis" ADD CONSTRAINT "redis_serverId_server_serverId_fk" FOREIGN KEY ("serverId") REFERENCES "public"."server"("serverId") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
3823
apps/dokploy/drizzle/meta/0042_snapshot.json
Normal file
3823
apps/dokploy/drizzle/meta/0042_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -295,6 +295,13 @@
|
|||||||
"when": 1725830160928,
|
"when": 1725830160928,
|
||||||
"tag": "0041_mute_polaris",
|
"tag": "0041_mute_polaris",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 42,
|
||||||
|
"version": "6",
|
||||||
|
"when": 1725856996201,
|
||||||
|
"tag": "0042_wandering_inhumans",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,6 @@ import {
|
|||||||
stopService,
|
stopService,
|
||||||
} from "@/server/utils/docker/utils";
|
} from "@/server/utils/docker/utils";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { z } from "zod";
|
|
||||||
import { createMount } from "../services/mount";
|
import { createMount } from "../services/mount";
|
||||||
import {
|
import {
|
||||||
createMysql,
|
createMysql,
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
import {
|
import { createTRPCRouter, protectedProcedure } from "@/server/api/trpc";
|
||||||
cliProcedure,
|
|
||||||
createTRPCRouter,
|
|
||||||
protectedProcedure,
|
|
||||||
} from "@/server/api/trpc";
|
|
||||||
import { db } from "@/server/db";
|
import { db } from "@/server/db";
|
||||||
import {
|
import {
|
||||||
applications,
|
applications,
|
||||||
@@ -34,7 +30,6 @@ import {
|
|||||||
checkProjectAccess,
|
checkProjectAccess,
|
||||||
findUserByAuthId,
|
findUserByAuthId,
|
||||||
} from "../services/user";
|
} from "../services/user";
|
||||||
import { findAdmin, findAdminByAuthId } from "../services/admin";
|
|
||||||
|
|
||||||
export const projectRouter = createTRPCRouter({
|
export const projectRouter = createTRPCRouter({
|
||||||
create: protectedProcedure
|
create: protectedProcedure
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { generatePassword } from "@/templates/utils";
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { eq, getTableColumns } from "drizzle-orm";
|
import { eq, getTableColumns } from "drizzle-orm";
|
||||||
import { validUniqueServerAppName } from "./project";
|
import { validUniqueServerAppName } from "./project";
|
||||||
|
import { executeCommand } from "@/server/utils/servers/command";
|
||||||
|
|
||||||
export type Mariadb = typeof mariadb.$inferSelect;
|
export type Mariadb = typeof mariadb.$inferSelect;
|
||||||
|
|
||||||
@@ -56,6 +57,7 @@ export const findMariadbById = async (mariadbId: string) => {
|
|||||||
with: {
|
with: {
|
||||||
project: true,
|
project: true,
|
||||||
mounts: true,
|
mounts: true,
|
||||||
|
server: true,
|
||||||
backups: {
|
backups: {
|
||||||
with: {
|
with: {
|
||||||
destination: true,
|
destination: true,
|
||||||
@@ -118,7 +120,15 @@ export const findMariadbByBackupId = async (backupId: string) => {
|
|||||||
export const deployMariadb = async (mariadbId: string) => {
|
export const deployMariadb = async (mariadbId: string) => {
|
||||||
const mariadb = await findMariadbById(mariadbId);
|
const mariadb = await findMariadbById(mariadbId);
|
||||||
try {
|
try {
|
||||||
await pullImage(mariadb.dockerImage);
|
if (mariadb.serverId) {
|
||||||
|
await executeCommand(
|
||||||
|
mariadb.serverId,
|
||||||
|
`docker pull ${mariadb.dockerImage}`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
await pullImage(mariadb.dockerImage);
|
||||||
|
}
|
||||||
|
|
||||||
await buildMariadb(mariadb);
|
await buildMariadb(mariadb);
|
||||||
await updateMariadbById(mariadbId, {
|
await updateMariadbById(mariadbId, {
|
||||||
applicationStatus: "done",
|
applicationStatus: "done",
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { generatePassword } from "@/templates/utils";
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { eq, getTableColumns } from "drizzle-orm";
|
import { eq, getTableColumns } from "drizzle-orm";
|
||||||
import { validUniqueServerAppName } from "./project";
|
import { validUniqueServerAppName } from "./project";
|
||||||
|
import { executeCommand } from "@/server/utils/servers/command";
|
||||||
|
|
||||||
export type Mongo = typeof mongo.$inferSelect;
|
export type Mongo = typeof mongo.$inferSelect;
|
||||||
|
|
||||||
@@ -52,6 +53,7 @@ export const findMongoById = async (mongoId: string) => {
|
|||||||
with: {
|
with: {
|
||||||
project: true,
|
project: true,
|
||||||
mounts: true,
|
mounts: true,
|
||||||
|
server: true,
|
||||||
backups: {
|
backups: {
|
||||||
with: {
|
with: {
|
||||||
destination: true,
|
destination: true,
|
||||||
@@ -114,7 +116,12 @@ export const removeMongoById = async (mongoId: string) => {
|
|||||||
export const deployMongo = async (mongoId: string) => {
|
export const deployMongo = async (mongoId: string) => {
|
||||||
const mongo = await findMongoById(mongoId);
|
const mongo = await findMongoById(mongoId);
|
||||||
try {
|
try {
|
||||||
await pullImage(mongo.dockerImage);
|
if (mongo.serverId) {
|
||||||
|
await executeCommand(mongo.serverId, `docker pull ${mongo.dockerImage}`);
|
||||||
|
} else {
|
||||||
|
await pullImage(mongo.dockerImage);
|
||||||
|
}
|
||||||
|
|
||||||
await buildMongo(mongo);
|
await buildMongo(mongo);
|
||||||
await updateMongoById(mongoId, {
|
await updateMongoById(mongoId, {
|
||||||
applicationStatus: "done",
|
applicationStatus: "done",
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { generatePassword } from "@/templates/utils";
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { eq, getTableColumns } from "drizzle-orm";
|
import { eq, getTableColumns } from "drizzle-orm";
|
||||||
import { validUniqueServerAppName } from "./project";
|
import { validUniqueServerAppName } from "./project";
|
||||||
|
import { executeCommand } from "@/server/utils/servers/command";
|
||||||
|
|
||||||
export type MySql = typeof mysql.$inferSelect;
|
export type MySql = typeof mysql.$inferSelect;
|
||||||
|
|
||||||
@@ -57,6 +58,7 @@ export const findMySqlById = async (mysqlId: string) => {
|
|||||||
with: {
|
with: {
|
||||||
project: true,
|
project: true,
|
||||||
mounts: true,
|
mounts: true,
|
||||||
|
server: true,
|
||||||
backups: {
|
backups: {
|
||||||
with: {
|
with: {
|
||||||
destination: true,
|
destination: true,
|
||||||
@@ -119,7 +121,12 @@ export const removeMySqlById = async (mysqlId: string) => {
|
|||||||
export const deployMySql = async (mysqlId: string) => {
|
export const deployMySql = async (mysqlId: string) => {
|
||||||
const mysql = await findMySqlById(mysqlId);
|
const mysql = await findMySqlById(mysqlId);
|
||||||
try {
|
try {
|
||||||
await pullImage(mysql.dockerImage);
|
if (mysql.serverId) {
|
||||||
|
await executeCommand(mysql.serverId, `docker pull ${mysql.dockerImage}`);
|
||||||
|
} else {
|
||||||
|
await pullImage(mysql.dockerImage);
|
||||||
|
}
|
||||||
|
|
||||||
await buildMysql(mysql);
|
await buildMysql(mysql);
|
||||||
await updateMySqlById(mysqlId, {
|
await updateMySqlById(mysqlId, {
|
||||||
applicationStatus: "done",
|
applicationStatus: "done",
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { generatePassword } from "@/templates/utils";
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { eq, getTableColumns } from "drizzle-orm";
|
import { eq, getTableColumns } from "drizzle-orm";
|
||||||
import { validUniqueServerAppName } from "./project";
|
import { validUniqueServerAppName } from "./project";
|
||||||
|
import { executeCommand } from "@/server/utils/servers/command";
|
||||||
|
|
||||||
export type Postgres = typeof postgres.$inferSelect;
|
export type Postgres = typeof postgres.$inferSelect;
|
||||||
|
|
||||||
@@ -45,13 +46,13 @@ export const createPostgres = async (input: typeof apiCreatePostgres._type) => {
|
|||||||
|
|
||||||
return newPostgres;
|
return newPostgres;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const findPostgresById = async (postgresId: string) => {
|
export const findPostgresById = async (postgresId: string) => {
|
||||||
const result = await db.query.postgres.findFirst({
|
const result = await db.query.postgres.findFirst({
|
||||||
where: eq(postgres.postgresId, postgresId),
|
where: eq(postgres.postgresId, postgresId),
|
||||||
with: {
|
with: {
|
||||||
project: true,
|
project: true,
|
||||||
mounts: true,
|
mounts: true,
|
||||||
|
server: true,
|
||||||
backups: {
|
backups: {
|
||||||
with: {
|
with: {
|
||||||
destination: true,
|
destination: true,
|
||||||
@@ -114,7 +115,15 @@ export const removePostgresById = async (postgresId: string) => {
|
|||||||
export const deployPostgres = async (postgresId: string) => {
|
export const deployPostgres = async (postgresId: string) => {
|
||||||
const postgres = await findPostgresById(postgresId);
|
const postgres = await findPostgresById(postgresId);
|
||||||
try {
|
try {
|
||||||
await pullImage(postgres.dockerImage);
|
if (postgres.serverId) {
|
||||||
|
await executeCommand(
|
||||||
|
postgres.serverId,
|
||||||
|
`docker pull ${postgres.dockerImage}`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
await pullImage(postgres.dockerImage);
|
||||||
|
}
|
||||||
|
|
||||||
await buildPostgres(postgres);
|
await buildPostgres(postgres);
|
||||||
await updatePostgresById(postgresId, {
|
await updatePostgresById(postgresId, {
|
||||||
applicationStatus: "done",
|
applicationStatus: "done",
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { generatePassword } from "@/templates/utils";
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
import { validUniqueServerAppName } from "./project";
|
import { validUniqueServerAppName } from "./project";
|
||||||
|
import { executeCommand } from "@/server/utils/servers/command";
|
||||||
|
|
||||||
export type Redis = typeof redis.$inferSelect;
|
export type Redis = typeof redis.$inferSelect;
|
||||||
|
|
||||||
@@ -53,6 +54,7 @@ export const findRedisById = async (redisId: string) => {
|
|||||||
with: {
|
with: {
|
||||||
project: true,
|
project: true,
|
||||||
mounts: true,
|
mounts: true,
|
||||||
|
server: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (!result) {
|
if (!result) {
|
||||||
@@ -91,7 +93,12 @@ export const removeRedisById = async (redisId: string) => {
|
|||||||
export const deployRedis = async (redisId: string) => {
|
export const deployRedis = async (redisId: string) => {
|
||||||
const redis = await findRedisById(redisId);
|
const redis = await findRedisById(redisId);
|
||||||
try {
|
try {
|
||||||
await pullImage(redis.dockerImage);
|
if (redis.serverId) {
|
||||||
|
await executeCommand(redis.serverId, `docker pull ${redis.dockerImage}`);
|
||||||
|
} else {
|
||||||
|
await pullImage(redis.dockerImage);
|
||||||
|
}
|
||||||
|
|
||||||
await buildRedis(redis);
|
await buildRedis(redis);
|
||||||
await updateRedisById(redisId, {
|
await updateRedisById(redisId, {
|
||||||
applicationStatus: "done",
|
applicationStatus: "done",
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { mounts } from "./mount";
|
|||||||
import { projects } from "./project";
|
import { projects } from "./project";
|
||||||
import { applicationStatus } from "./shared";
|
import { applicationStatus } from "./shared";
|
||||||
import { generateAppName } from "./utils";
|
import { generateAppName } from "./utils";
|
||||||
|
import { server } from "./server";
|
||||||
|
|
||||||
export const mariadb = pgTable("mariadb", {
|
export const mariadb = pgTable("mariadb", {
|
||||||
mariadbId: text("mariadbId")
|
mariadbId: text("mariadbId")
|
||||||
@@ -44,6 +45,9 @@ export const mariadb = pgTable("mariadb", {
|
|||||||
projectId: text("projectId")
|
projectId: text("projectId")
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => projects.projectId, { onDelete: "cascade" }),
|
.references(() => projects.projectId, { onDelete: "cascade" }),
|
||||||
|
serverId: text("serverId").references(() => server.serverId, {
|
||||||
|
onDelete: "cascade",
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const mariadbRelations = relations(mariadb, ({ one, many }) => ({
|
export const mariadbRelations = relations(mariadb, ({ one, many }) => ({
|
||||||
@@ -53,6 +57,10 @@ export const mariadbRelations = relations(mariadb, ({ one, many }) => ({
|
|||||||
}),
|
}),
|
||||||
backups: many(backups),
|
backups: many(backups),
|
||||||
mounts: many(mounts),
|
mounts: many(mounts),
|
||||||
|
server: one(server, {
|
||||||
|
fields: [mariadb.serverId],
|
||||||
|
references: [server.serverId],
|
||||||
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const createSchema = createInsertSchema(mariadb, {
|
const createSchema = createInsertSchema(mariadb, {
|
||||||
@@ -88,6 +96,7 @@ export const apiCreateMariaDB = createSchema
|
|||||||
databaseName: true,
|
databaseName: true,
|
||||||
databaseUser: true,
|
databaseUser: true,
|
||||||
databasePassword: true,
|
databasePassword: true,
|
||||||
|
serverId: true,
|
||||||
})
|
})
|
||||||
.required();
|
.required();
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { mounts } from "./mount";
|
|||||||
import { projects } from "./project";
|
import { projects } from "./project";
|
||||||
import { applicationStatus } from "./shared";
|
import { applicationStatus } from "./shared";
|
||||||
import { generateAppName } from "./utils";
|
import { generateAppName } from "./utils";
|
||||||
|
import { server } from "./server";
|
||||||
|
|
||||||
export const mongo = pgTable("mongo", {
|
export const mongo = pgTable("mongo", {
|
||||||
mongoId: text("mongoId")
|
mongoId: text("mongoId")
|
||||||
@@ -40,6 +41,9 @@ export const mongo = pgTable("mongo", {
|
|||||||
projectId: text("projectId")
|
projectId: text("projectId")
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => projects.projectId, { onDelete: "cascade" }),
|
.references(() => projects.projectId, { onDelete: "cascade" }),
|
||||||
|
serverId: text("serverId").references(() => server.serverId, {
|
||||||
|
onDelete: "cascade",
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const mongoRelations = relations(mongo, ({ one, many }) => ({
|
export const mongoRelations = relations(mongo, ({ one, many }) => ({
|
||||||
@@ -49,6 +53,10 @@ export const mongoRelations = relations(mongo, ({ one, many }) => ({
|
|||||||
}),
|
}),
|
||||||
backups: many(backups),
|
backups: many(backups),
|
||||||
mounts: many(mounts),
|
mounts: many(mounts),
|
||||||
|
server: one(server, {
|
||||||
|
fields: [mongo.serverId],
|
||||||
|
references: [server.serverId],
|
||||||
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const createSchema = createInsertSchema(mongo, {
|
const createSchema = createInsertSchema(mongo, {
|
||||||
@@ -80,6 +88,7 @@ export const apiCreateMongo = createSchema
|
|||||||
description: true,
|
description: true,
|
||||||
databaseUser: true,
|
databaseUser: true,
|
||||||
databasePassword: true,
|
databasePassword: true,
|
||||||
|
serverId: true,
|
||||||
})
|
})
|
||||||
.required();
|
.required();
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { generatePassword } from "@/templates/utils";
|
|
||||||
import { relations } from "drizzle-orm";
|
import { relations } from "drizzle-orm";
|
||||||
import { integer, pgTable, text } from "drizzle-orm/pg-core";
|
import { integer, pgTable, text } from "drizzle-orm/pg-core";
|
||||||
import { createInsertSchema } from "drizzle-zod";
|
import { createInsertSchema } from "drizzle-zod";
|
||||||
@@ -9,6 +8,7 @@ import { mounts } from "./mount";
|
|||||||
import { projects } from "./project";
|
import { projects } from "./project";
|
||||||
import { applicationStatus } from "./shared";
|
import { applicationStatus } from "./shared";
|
||||||
import { generateAppName } from "./utils";
|
import { generateAppName } from "./utils";
|
||||||
|
import { server } from "./server";
|
||||||
|
|
||||||
export const mysql = pgTable("mysql", {
|
export const mysql = pgTable("mysql", {
|
||||||
mysqlId: text("mysqlId")
|
mysqlId: text("mysqlId")
|
||||||
@@ -42,6 +42,9 @@ export const mysql = pgTable("mysql", {
|
|||||||
projectId: text("projectId")
|
projectId: text("projectId")
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => projects.projectId, { onDelete: "cascade" }),
|
.references(() => projects.projectId, { onDelete: "cascade" }),
|
||||||
|
serverId: text("serverId").references(() => server.serverId, {
|
||||||
|
onDelete: "cascade",
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const mysqlRelations = relations(mysql, ({ one, many }) => ({
|
export const mysqlRelations = relations(mysql, ({ one, many }) => ({
|
||||||
@@ -51,6 +54,10 @@ export const mysqlRelations = relations(mysql, ({ one, many }) => ({
|
|||||||
}),
|
}),
|
||||||
backups: many(backups),
|
backups: many(backups),
|
||||||
mounts: many(mounts),
|
mounts: many(mounts),
|
||||||
|
server: one(server, {
|
||||||
|
fields: [mysql.serverId],
|
||||||
|
references: [server.serverId],
|
||||||
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const createSchema = createInsertSchema(mysql, {
|
const createSchema = createInsertSchema(mysql, {
|
||||||
@@ -86,6 +93,7 @@ export const apiCreateMySql = createSchema
|
|||||||
databaseUser: true,
|
databaseUser: true,
|
||||||
databasePassword: true,
|
databasePassword: true,
|
||||||
databaseRootPassword: true,
|
databaseRootPassword: true,
|
||||||
|
serverId: true,
|
||||||
})
|
})
|
||||||
.required();
|
.required();
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { mounts } from "./mount";
|
|||||||
import { projects } from "./project";
|
import { projects } from "./project";
|
||||||
import { applicationStatus } from "./shared";
|
import { applicationStatus } from "./shared";
|
||||||
import { generateAppName } from "./utils";
|
import { generateAppName } from "./utils";
|
||||||
|
import { server } from "./server";
|
||||||
|
|
||||||
export const postgres = pgTable("postgres", {
|
export const postgres = pgTable("postgres", {
|
||||||
postgresId: text("postgresId")
|
postgresId: text("postgresId")
|
||||||
@@ -41,6 +42,9 @@ export const postgres = pgTable("postgres", {
|
|||||||
projectId: text("projectId")
|
projectId: text("projectId")
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => projects.projectId, { onDelete: "cascade" }),
|
.references(() => projects.projectId, { onDelete: "cascade" }),
|
||||||
|
serverId: text("serverId").references(() => server.serverId, {
|
||||||
|
onDelete: "cascade",
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const postgresRelations = relations(postgres, ({ one, many }) => ({
|
export const postgresRelations = relations(postgres, ({ one, many }) => ({
|
||||||
@@ -50,6 +54,10 @@ export const postgresRelations = relations(postgres, ({ one, many }) => ({
|
|||||||
}),
|
}),
|
||||||
backups: many(backups),
|
backups: many(backups),
|
||||||
mounts: many(mounts),
|
mounts: many(mounts),
|
||||||
|
server: one(server, {
|
||||||
|
fields: [postgres.serverId],
|
||||||
|
references: [server.serverId],
|
||||||
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const createSchema = createInsertSchema(postgres, {
|
const createSchema = createInsertSchema(postgres, {
|
||||||
@@ -82,6 +90,7 @@ export const apiCreatePostgres = createSchema
|
|||||||
dockerImage: true,
|
dockerImage: true,
|
||||||
projectId: true,
|
projectId: true,
|
||||||
description: true,
|
description: true,
|
||||||
|
serverId: true,
|
||||||
})
|
})
|
||||||
.required();
|
.required();
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { generatePassword } from "@/templates/utils";
|
|
||||||
import { relations } from "drizzle-orm";
|
import { relations } from "drizzle-orm";
|
||||||
import { integer, pgTable, text } from "drizzle-orm/pg-core";
|
import { integer, pgTable, text } from "drizzle-orm/pg-core";
|
||||||
import { createInsertSchema } from "drizzle-zod";
|
import { createInsertSchema } from "drizzle-zod";
|
||||||
@@ -8,6 +7,7 @@ import { mounts } from "./mount";
|
|||||||
import { projects } from "./project";
|
import { projects } from "./project";
|
||||||
import { applicationStatus } from "./shared";
|
import { applicationStatus } from "./shared";
|
||||||
import { generateAppName } from "./utils";
|
import { generateAppName } from "./utils";
|
||||||
|
import { server } from "./server";
|
||||||
|
|
||||||
export const redis = pgTable("redis", {
|
export const redis = pgTable("redis", {
|
||||||
redisId: text("redisId")
|
redisId: text("redisId")
|
||||||
@@ -38,6 +38,9 @@ export const redis = pgTable("redis", {
|
|||||||
projectId: text("projectId")
|
projectId: text("projectId")
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => projects.projectId, { onDelete: "cascade" }),
|
.references(() => projects.projectId, { onDelete: "cascade" }),
|
||||||
|
serverId: text("serverId").references(() => server.serverId, {
|
||||||
|
onDelete: "cascade",
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const redisRelations = relations(redis, ({ one, many }) => ({
|
export const redisRelations = relations(redis, ({ one, many }) => ({
|
||||||
@@ -46,6 +49,10 @@ export const redisRelations = relations(redis, ({ one, many }) => ({
|
|||||||
references: [projects.projectId],
|
references: [projects.projectId],
|
||||||
}),
|
}),
|
||||||
mounts: many(mounts),
|
mounts: many(mounts),
|
||||||
|
server: one(server, {
|
||||||
|
fields: [redis.serverId],
|
||||||
|
references: [server.serverId],
|
||||||
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const createSchema = createInsertSchema(redis, {
|
const createSchema = createInsertSchema(redis, {
|
||||||
@@ -75,6 +82,7 @@ export const apiCreateRedis = createSchema
|
|||||||
dockerImage: true,
|
dockerImage: true,
|
||||||
projectId: true,
|
projectId: true,
|
||||||
description: true,
|
description: true,
|
||||||
|
serverId: true,
|
||||||
})
|
})
|
||||||
.required();
|
.required();
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,15 @@ import { admins } from "./admin";
|
|||||||
import { generateAppName } from "./utils";
|
import { generateAppName } from "./utils";
|
||||||
import { deployments } from "./deployment";
|
import { deployments } from "./deployment";
|
||||||
import { sshKeys } from "./ssh-key";
|
import { sshKeys } from "./ssh-key";
|
||||||
import { applications, compose } from ".";
|
import {
|
||||||
|
applications,
|
||||||
|
compose,
|
||||||
|
mariadb,
|
||||||
|
mongo,
|
||||||
|
mysql,
|
||||||
|
postgres,
|
||||||
|
redis,
|
||||||
|
} from ".";
|
||||||
|
|
||||||
export const server = pgTable("server", {
|
export const server = pgTable("server", {
|
||||||
serverId: text("serverId")
|
serverId: text("serverId")
|
||||||
@@ -46,6 +54,11 @@ export const serverRelations = relations(server, ({ one, many }) => ({
|
|||||||
}),
|
}),
|
||||||
applications: many(applications),
|
applications: many(applications),
|
||||||
compose: many(compose),
|
compose: many(compose),
|
||||||
|
redis: many(redis),
|
||||||
|
mariadb: many(mariadb),
|
||||||
|
mongo: many(mongo),
|
||||||
|
mysql: many(mysql),
|
||||||
|
postgres: many(postgres),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const createSchema = createInsertSchema(server, {
|
const createSchema = createInsertSchema(server, {
|
||||||
|
|||||||
@@ -130,20 +130,6 @@ export const mechanizeDockerContainer = async (
|
|||||||
const image = getImageName(application);
|
const image = getImageName(application);
|
||||||
const authConfig = getAuthConfig(application);
|
const authConfig = getAuthConfig(application);
|
||||||
const docker = await getRemoteDocker(application.serverId);
|
const docker = await getRemoteDocker(application.serverId);
|
||||||
// const server = await findServerById(application.serverId);
|
|
||||||
// if (!server.sshKeyId) return;
|
|
||||||
// const keys = await readSSHKey(server.sshKeyId);
|
|
||||||
// const docker = new Dockerode({
|
|
||||||
// host: server.ipAddress,
|
|
||||||
// port: server.port,
|
|
||||||
// username: server.username,
|
|
||||||
// protocol: "ssh",
|
|
||||||
// sshOptions: {
|
|
||||||
// privateKey: keys.privateKey,
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
// const results = await docker2.listContainers();
|
|
||||||
// console.log(results);
|
|
||||||
|
|
||||||
const settings: CreateServiceOptions = {
|
const settings: CreateServiceOptions = {
|
||||||
authconfig: authConfig,
|
authconfig: authConfig,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import type { Mariadb } from "@/server/api/services/mariadb";
|
import type { Mariadb } from "@/server/api/services/mariadb";
|
||||||
import type { Mount } from "@/server/api/services/mount";
|
import type { Mount } from "@/server/api/services/mount";
|
||||||
import { docker } from "@/server/constants";
|
|
||||||
import type { CreateServiceOptions } from "dockerode";
|
import type { CreateServiceOptions } from "dockerode";
|
||||||
import {
|
import {
|
||||||
calculateResources,
|
calculateResources,
|
||||||
@@ -9,6 +8,7 @@ import {
|
|||||||
generateVolumeMounts,
|
generateVolumeMounts,
|
||||||
prepareEnvironmentVariables,
|
prepareEnvironmentVariables,
|
||||||
} from "../docker/utils";
|
} from "../docker/utils";
|
||||||
|
import { getRemoteDocker } from "../servers/remote-docker";
|
||||||
|
|
||||||
type MariadbWithMounts = Mariadb & {
|
type MariadbWithMounts = Mariadb & {
|
||||||
mounts: Mount[];
|
mounts: Mount[];
|
||||||
@@ -45,6 +45,8 @@ export const buildMariadb = async (mariadb: MariadbWithMounts) => {
|
|||||||
const bindsMount = generateBindMounts(mounts);
|
const bindsMount = generateBindMounts(mounts);
|
||||||
const filesMount = generateFileMounts(appName, mounts);
|
const filesMount = generateFileMounts(appName, mounts);
|
||||||
|
|
||||||
|
const docker = await getRemoteDocker(mariadb.serverId);
|
||||||
|
|
||||||
const settings: CreateServiceOptions = {
|
const settings: CreateServiceOptions = {
|
||||||
Name: appName,
|
Name: appName,
|
||||||
TaskTemplate: {
|
TaskTemplate: {
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import type { Mongo } from "@/server/api/services/mongo";
|
import type { Mongo } from "@/server/api/services/mongo";
|
||||||
import type { Mount } from "@/server/api/services/mount";
|
import type { Mount } from "@/server/api/services/mount";
|
||||||
import type { Postgres } from "@/server/api/services/postgres";
|
|
||||||
import { docker } from "@/server/constants";
|
|
||||||
import type { CreateServiceOptions } from "dockerode";
|
import type { CreateServiceOptions } from "dockerode";
|
||||||
import {
|
import {
|
||||||
calculateResources,
|
calculateResources,
|
||||||
@@ -10,6 +8,7 @@ import {
|
|||||||
generateVolumeMounts,
|
generateVolumeMounts,
|
||||||
prepareEnvironmentVariables,
|
prepareEnvironmentVariables,
|
||||||
} from "../docker/utils";
|
} from "../docker/utils";
|
||||||
|
import { getRemoteDocker } from "../servers/remote-docker";
|
||||||
|
|
||||||
type MongoWithMounts = Mongo & {
|
type MongoWithMounts = Mongo & {
|
||||||
mounts: Mount[];
|
mounts: Mount[];
|
||||||
@@ -45,6 +44,8 @@ export const buildMongo = async (mongo: MongoWithMounts) => {
|
|||||||
const bindsMount = generateBindMounts(mounts);
|
const bindsMount = generateBindMounts(mounts);
|
||||||
const filesMount = generateFileMounts(appName, mounts);
|
const filesMount = generateFileMounts(appName, mounts);
|
||||||
|
|
||||||
|
const docker = await getRemoteDocker(mongo.serverId);
|
||||||
|
|
||||||
const settings: CreateServiceOptions = {
|
const settings: CreateServiceOptions = {
|
||||||
Name: appName,
|
Name: appName,
|
||||||
TaskTemplate: {
|
TaskTemplate: {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
generateVolumeMounts,
|
generateVolumeMounts,
|
||||||
prepareEnvironmentVariables,
|
prepareEnvironmentVariables,
|
||||||
} from "../docker/utils";
|
} from "../docker/utils";
|
||||||
|
import { getRemoteDocker } from "../servers/remote-docker";
|
||||||
|
|
||||||
type MysqlWithMounts = MySql & {
|
type MysqlWithMounts = MySql & {
|
||||||
mounts: Mount[];
|
mounts: Mount[];
|
||||||
@@ -51,6 +52,8 @@ export const buildMysql = async (mysql: MysqlWithMounts) => {
|
|||||||
const bindsMount = generateBindMounts(mounts);
|
const bindsMount = generateBindMounts(mounts);
|
||||||
const filesMount = generateFileMounts(appName, mounts);
|
const filesMount = generateFileMounts(appName, mounts);
|
||||||
|
|
||||||
|
const docker = await getRemoteDocker(mysql.serverId);
|
||||||
|
|
||||||
const settings: CreateServiceOptions = {
|
const settings: CreateServiceOptions = {
|
||||||
Name: appName,
|
Name: appName,
|
||||||
TaskTemplate: {
|
TaskTemplate: {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import type { Mount } from "@/server/api/services/mount";
|
import type { Mount } from "@/server/api/services/mount";
|
||||||
import type { Postgres } from "@/server/api/services/postgres";
|
import type { Postgres } from "@/server/api/services/postgres";
|
||||||
import { docker } from "@/server/constants";
|
|
||||||
import type { CreateServiceOptions } from "dockerode";
|
import type { CreateServiceOptions } from "dockerode";
|
||||||
import {
|
import {
|
||||||
calculateResources,
|
calculateResources,
|
||||||
@@ -9,6 +8,7 @@ import {
|
|||||||
generateVolumeMounts,
|
generateVolumeMounts,
|
||||||
prepareEnvironmentVariables,
|
prepareEnvironmentVariables,
|
||||||
} from "../docker/utils";
|
} from "../docker/utils";
|
||||||
|
import { getRemoteDocker } from "../servers/remote-docker";
|
||||||
|
|
||||||
type PostgresWithMounts = Postgres & {
|
type PostgresWithMounts = Postgres & {
|
||||||
mounts: Mount[];
|
mounts: Mount[];
|
||||||
@@ -45,6 +45,8 @@ export const buildPostgres = async (postgres: PostgresWithMounts) => {
|
|||||||
const bindsMount = generateBindMounts(mounts);
|
const bindsMount = generateBindMounts(mounts);
|
||||||
const filesMount = generateFileMounts(appName, mounts);
|
const filesMount = generateFileMounts(appName, mounts);
|
||||||
|
|
||||||
|
const docker = await getRemoteDocker(postgres.serverId);
|
||||||
|
|
||||||
const settings: CreateServiceOptions = {
|
const settings: CreateServiceOptions = {
|
||||||
Name: appName,
|
Name: appName,
|
||||||
TaskTemplate: {
|
TaskTemplate: {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
generateVolumeMounts,
|
generateVolumeMounts,
|
||||||
prepareEnvironmentVariables,
|
prepareEnvironmentVariables,
|
||||||
} from "../docker/utils";
|
} from "../docker/utils";
|
||||||
|
import { getRemoteDocker } from "../servers/remote-docker";
|
||||||
|
|
||||||
type RedisWithMounts = Redis & {
|
type RedisWithMounts = Redis & {
|
||||||
mounts: Mount[];
|
mounts: Mount[];
|
||||||
@@ -43,6 +44,8 @@ export const buildRedis = async (redis: RedisWithMounts) => {
|
|||||||
const bindsMount = generateBindMounts(mounts);
|
const bindsMount = generateBindMounts(mounts);
|
||||||
const filesMount = generateFileMounts(appName, mounts);
|
const filesMount = generateFileMounts(appName, mounts);
|
||||||
|
|
||||||
|
const docker = await getRemoteDocker(redis.serverId);
|
||||||
|
|
||||||
const settings: CreateServiceOptions = {
|
const settings: CreateServiceOptions = {
|
||||||
Name: appName,
|
Name: appName,
|
||||||
TaskTemplate: {
|
TaskTemplate: {
|
||||||
|
|||||||
Reference in New Issue
Block a user