diff --git a/.github/sponsors/mandarin.png b/.github/sponsors/mandarin.png
new file mode 100644
index 000000000..f76512920
Binary files /dev/null and b/.github/sponsors/mandarin.png differ
diff --git a/README.md b/README.md
index 2e784812c..72620ef89 100644
--- a/README.md
+++ b/README.md
@@ -39,6 +39,8 @@ Dokploy includes multiple features to make your life easier.
To get started, run the following command on a VPS:
+Want to skip the installation process? [Try the Dokploy Cloud](https://app.dokploy.com).
+
```bash
curl -sSL https://dokploy.com/install.sh | sh
```
@@ -60,12 +62,15 @@ For detailed documentation, visit [docs.dokploy.com](https://docs.dokploy.com).
### Hero Sponsors 🎖
### Premium Supporters 🥇
diff --git a/apps/dokploy/__test__/compose/domain/labels.test.ts b/apps/dokploy/__test__/compose/domain/labels.test.ts
index 5076a2042..4123b2877 100644
--- a/apps/dokploy/__test__/compose/domain/labels.test.ts
+++ b/apps/dokploy/__test__/compose/domain/labels.test.ts
@@ -26,11 +26,30 @@ describe("createDomainLabels", () => {
"traefik.http.routers.test-app-1-web.entrypoints=web",
"traefik.http.services.test-app-1-web.loadbalancer.server.port=8080",
"traefik.http.routers.test-app-1-web.service=test-app-1-web",
+ "traefik.http.routers.test-app-1-web.rule=PathPrefix(`/`)",
]);
});
it("should create labels for websecure entrypoint", async () => {
const labels = await createDomainLabels(appName, baseDomain, "websecure");
+ expect(labels).toEqual([
+ "traefik.http.routers.test-app-1-websecure.rule=Host(`example.com`)",
+ "traefik.http.routers.test-app-1-websecure.entrypoints=websecure",
+ "traefik.http.services.test-app-1-websecure.loadbalancer.server.port=8080",
+ "traefik.http.routers.test-app-1-websecure.service=test-app-1-websecure",
+ "traefik.http.routers.test-app-1-websecure.rule=PathPrefix(`/`)",
+ ]);
+ });
+
+ it("shouldn't add the path prefix if is empty", async () => {
+ const labels = await createDomainLabels(
+ appName,
+ {
+ ...baseDomain,
+ path: "",
+ },
+ "websecure",
+ );
expect(labels).toEqual([
"traefik.http.routers.test-app-1-websecure.rule=Host(`example.com`)",
"traefik.http.routers.test-app-1-websecure.entrypoints=websecure",
diff --git a/apps/dokploy/components/dashboard/application/advanced/ports/update-port.tsx b/apps/dokploy/components/dashboard/application/advanced/ports/update-port.tsx
index 0ed9d2e27..a9f7f32d5 100644
--- a/apps/dokploy/components/dashboard/application/advanced/ports/update-port.tsx
+++ b/apps/dokploy/components/dashboard/application/advanced/ports/update-port.tsx
@@ -140,7 +140,7 @@ export const UpdatePort = ({ portId }: Props) => {
Target Port
-
+
diff --git a/apps/dokploy/components/dashboard/settings/git/github/add-github-provider.tsx b/apps/dokploy/components/dashboard/settings/git/github/add-github-provider.tsx
index 58cc87238..a04a166b0 100644
--- a/apps/dokploy/components/dashboard/settings/git/github/add-github-provider.tsx
+++ b/apps/dokploy/components/dashboard/settings/git/github/add-github-provider.tsx
@@ -53,7 +53,7 @@ export const AddGithubProvider = () => {
-
+
Github
diff --git a/apps/dokploy/components/dashboard/settings/servers/actions/toggle-docker-cleanup.tsx b/apps/dokploy/components/dashboard/settings/servers/actions/toggle-docker-cleanup.tsx
index 17edaa991..78ad12363 100644
--- a/apps/dokploy/components/dashboard/settings/servers/actions/toggle-docker-cleanup.tsx
+++ b/apps/dokploy/components/dashboard/settings/servers/actions/toggle-docker-cleanup.tsx
@@ -23,29 +23,27 @@ export const ToggleDockerCleanup = ({ serverId }: Props) => {
const enabled = data?.enableDockerCleanup || server?.enableDockerCleanup;
const { mutateAsync } = api.settings.updateDockerCleanup.useMutation();
+
+ const handleToggle = async (checked: boolean) => {
+ try {
+ await mutateAsync({
+ enableDockerCleanup: checked,
+ serverId: serverId,
+ });
+ if (serverId) {
+ await refetchServer();
+ } else {
+ await refetch();
+ }
+ toast.success("Docker Cleanup updated");
+ } catch (error) {
+ toast.error("Docker Cleanup Error");
+ }
+ };
+
return (
- {
- await mutateAsync({
- enableDockerCleanup: e,
- serverId: serverId,
- })
- .then(async () => {
- toast.success("Docker Cleanup Enabled");
- })
- .catch(() => {
- toast.error("Docker Cleanup Error");
- });
-
- if (serverId) {
- refetchServer();
- } else {
- refetch();
- }
- }}
- />
+
Daily Docker Cleanup
);
diff --git a/apps/dokploy/components/icons/data-tools-icons.tsx b/apps/dokploy/components/icons/data-tools-icons.tsx
index 43c2b371a..116f5d8aa 100644
--- a/apps/dokploy/components/icons/data-tools-icons.tsx
+++ b/apps/dokploy/components/icons/data-tools-icons.tsx
@@ -161,29 +161,27 @@ export const GitlabIcon = ({ className }: Props) => {
return (
);
@@ -200,7 +198,7 @@ export const GithubIcon = ({ className }: Props) => {
>
@@ -209,30 +207,34 @@ export const GithubIcon = ({ className }: Props) => {
export const BitbucketIcon = ({ className }: Props) => {
return (
-
+
+
+
-
-
+
+
-
-
);
};
diff --git a/apps/dokploy/package.json b/apps/dokploy/package.json
index e62bb1dd8..9573eee5d 100644
--- a/apps/dokploy/package.json
+++ b/apps/dokploy/package.json
@@ -1,6 +1,6 @@
{
"name": "dokploy",
- "version": "v0.10.10",
+ "version": "v0.11.0",
"private": true,
"license": "Apache-2.0",
"type": "module",
@@ -11,7 +11,7 @@
"build-next": "next build",
"setup": "tsx -r dotenv/config setup.ts && sleep 5 && pnpm run migration:run",
"reset-password": "node -r dotenv/config dist/reset-password.mjs",
- "dev": "TURBOPACK=1 tsx -r dotenv/config ./server/server.ts --project tsconfig.server.json ",
+ "dev": "tsx -r dotenv/config ./server/server.ts --project tsconfig.server.json ",
"studio": "drizzle-kit studio --config ./server/db/drizzle.config.ts",
"migration:generate": "drizzle-kit generate --config ./server/db/drizzle.config.ts",
"migration:run": "tsx -r dotenv/config migration.ts",
diff --git a/apps/dokploy/public/templates/coder.svg b/apps/dokploy/public/templates/coder.svg
new file mode 100644
index 000000000..56d2f77c3
--- /dev/null
+++ b/apps/dokploy/public/templates/coder.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/dokploy/public/templates/docmost.png b/apps/dokploy/public/templates/docmost.png
new file mode 100644
index 000000000..9bc8d2103
Binary files /dev/null and b/apps/dokploy/public/templates/docmost.png differ
diff --git a/apps/dokploy/public/templates/hi-events.svg b/apps/dokploy/public/templates/hi-events.svg
new file mode 100644
index 000000000..0e373509b
--- /dev/null
+++ b/apps/dokploy/public/templates/hi-events.svg
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/dokploy/public/templates/infisical.jpg b/apps/dokploy/public/templates/infisical.jpg
new file mode 100644
index 000000000..404f58119
Binary files /dev/null and b/apps/dokploy/public/templates/infisical.jpg differ
diff --git a/apps/dokploy/public/templates/influxdb.png b/apps/dokploy/public/templates/influxdb.png
new file mode 100644
index 000000000..8fc62a7fb
Binary files /dev/null and b/apps/dokploy/public/templates/influxdb.png differ
diff --git a/apps/dokploy/public/templates/macos.png b/apps/dokploy/public/templates/macos.png
new file mode 100644
index 000000000..617122c87
Binary files /dev/null and b/apps/dokploy/public/templates/macos.png differ
diff --git a/apps/dokploy/public/templates/vaultwarden.svg b/apps/dokploy/public/templates/vaultwarden.svg
new file mode 100644
index 000000000..71866afd2
--- /dev/null
+++ b/apps/dokploy/public/templates/vaultwarden.svg
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/dokploy/public/templates/windows.png b/apps/dokploy/public/templates/windows.png
new file mode 100644
index 000000000..61ced4559
Binary files /dev/null and b/apps/dokploy/public/templates/windows.png differ
diff --git a/apps/dokploy/server/server.ts b/apps/dokploy/server/server.ts
index b65446f8b..bf1112333 100644
--- a/apps/dokploy/server/server.ts
+++ b/apps/dokploy/server/server.ts
@@ -24,7 +24,7 @@ import { setupTerminalWebSocketServer } from "./wss/terminal";
config({ path: ".env" });
const PORT = Number.parseInt(process.env.PORT || "3000", 10);
const dev = process.env.NODE_ENV !== "production";
-const app = next({ dev, turbopack: dev });
+const app = next({ dev });
const handle = app.getRequestHandler();
void app.prepare().then(async () => {
try {
diff --git a/apps/dokploy/templates/coder/docker-compose.yml b/apps/dokploy/templates/coder/docker-compose.yml
new file mode 100644
index 000000000..27bb14bd2
--- /dev/null
+++ b/apps/dokploy/templates/coder/docker-compose.yml
@@ -0,0 +1,39 @@
+services:
+ coder:
+ image: ghcr.io/coder/coder:v2.15.3
+ networks:
+ - dokploy-network
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ group_add:
+ - "998"
+ depends_on:
+ db:
+ condition: service_healthy
+ environment:
+ - CODER_ACCESS_URL
+ - CODER_HTTP_ADDRESS
+ - CODER_PG_CONNECTION_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db/${POSTGRES_DB}?sslmode=disable
+
+ db:
+ image: postgres:17
+ networks:
+ - dokploy-network
+ environment:
+ - POSTGRES_PASSWORD
+ - POSTGRES_USER
+ - POSTGRES_DB
+ healthcheck:
+ test:
+ [
+ "CMD-SHELL",
+ "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}",
+ ]
+ interval: 5s
+ timeout: 5s
+ retries: 5
+ volumes:
+ - db_coder_data:/var/lib/postgresql/data
+
+volumes:
+ db_coder_data:
\ No newline at end of file
diff --git a/apps/dokploy/templates/coder/index.ts b/apps/dokploy/templates/coder/index.ts
new file mode 100644
index 000000000..c3f066d63
--- /dev/null
+++ b/apps/dokploy/templates/coder/index.ts
@@ -0,0 +1,30 @@
+import {
+ type DomainSchema,
+ type Schema,
+ type Template,
+ generateRandomDomain,
+} from "../utils";
+
+export function generate(schema: Schema): Template {
+ const domains: DomainSchema[] = [
+ {
+ host: generateRandomDomain(schema),
+ port: 7080,
+ serviceName: "coder",
+ },
+ ];
+
+ const envs = [
+ "CODER_ACCESS_URL=",
+ "CODER_HTTP_ADDRESS=0.0.0.0:7080",
+ "",
+ "POSTGRES_DB=coder",
+ "POSTGRES_USER=coder",
+ "POSTGRES_PASSWORD=VERY_STRONG_PASSWORD",
+ ];
+
+ return {
+ domains,
+ envs,
+ };
+}
diff --git a/apps/dokploy/templates/docmost/docker-compose.yml b/apps/dokploy/templates/docmost/docker-compose.yml
new file mode 100644
index 000000000..a6ebbd4f4
--- /dev/null
+++ b/apps/dokploy/templates/docmost/docker-compose.yml
@@ -0,0 +1,47 @@
+version: "3"
+
+services:
+ docmost:
+ image: docmost/docmost:0.4.1
+ depends_on:
+ - db
+ - redis
+ environment:
+ - APP_URL
+ - APP_SECRET
+ - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public
+ - REDIS_URL=redis://redis:6379
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ volumes:
+ - docmost:/app/data/storage
+
+ db:
+ image: postgres:16-alpine
+ environment:
+ - POSTGRES_DB
+ - POSTGRES_USER
+ - POSTGRES_PASSWORD
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ volumes:
+ - db_docmost_data:/var/lib/postgresql/data
+
+ redis:
+ image: redis:7.2-alpine
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ volumes:
+ - redis_docmost_data:/data
+
+networks:
+ dokploy-network:
+ external: true
+
+volumes:
+ docmost:
+ db_docmost_data:
+ redis_docmost_data:
\ No newline at end of file
diff --git a/apps/dokploy/templates/docmost/index.ts b/apps/dokploy/templates/docmost/index.ts
new file mode 100644
index 000000000..16f7afa66
--- /dev/null
+++ b/apps/dokploy/templates/docmost/index.ts
@@ -0,0 +1,29 @@
+import {
+ type DomainSchema,
+ type Schema,
+ type Template,
+ generateRandomDomain,
+} from "../utils";
+
+export function generate(schema: Schema): Template {
+ const domains: DomainSchema[] = [
+ {
+ host: generateRandomDomain(schema),
+ port: 3000,
+ serviceName: "docmost",
+ },
+ ];
+
+ const envs = [
+ "POSTGRES_DB=docmost",
+ "POSTGRES_USER=docmost",
+ "POSTGRES_PASSWORD=STRONG_DB_PASSWORD",
+ "APP_URL=http://localhost:3000",
+ "APP_SECRET=VERY_STRONG_SECRET",
+ ];
+
+ return {
+ domains,
+ envs,
+ };
+}
diff --git a/apps/dokploy/templates/gitea/docker-compose.yml b/apps/dokploy/templates/gitea/docker-compose.yml
index 679936fb7..72e0754e2 100644
--- a/apps/dokploy/templates/gitea/docker-compose.yml
+++ b/apps/dokploy/templates/gitea/docker-compose.yml
@@ -1,7 +1,7 @@
version: "3.8"
services:
gitea:
- image: gitea/gitea:1.22.2
+ image: gitea/gitea:1.22.3
environment:
- USER_UID=${USER_UID}
- USER_GID=${USER_GID}
@@ -21,7 +21,7 @@ services:
- db
db:
- image: postgres:16
+ image: postgres:17
restart: always
environment:
- POSTGRES_USER=gitea
diff --git a/apps/dokploy/templates/hi-events/docker-compose.yml b/apps/dokploy/templates/hi-events/docker-compose.yml
new file mode 100644
index 000000000..0ce5b7e75
--- /dev/null
+++ b/apps/dokploy/templates/hi-events/docker-compose.yml
@@ -0,0 +1,45 @@
+services:
+ all-in-one:
+ image: daveearley/hi.events-all-in-one:v0.8.0-beta.1
+ restart: always
+ environment:
+ - VITE_FRONTEND_URL=https://${DOMAIN}
+ - APP_FRONTEND_URL=https://${DOMAIN}
+ - VITE_API_URL_CLIENT=https://${DOMAIN}/api
+ - VITE_API_URL_SERVER=http://localhost:80/api
+ - VITE_STRIPE_PUBLISHABLE_KEY
+ - LOG_CHANNEL=stderr
+ - QUEUE_CONNECTION=sync
+ - MAIL_MAILER=array
+ - APP_KEY
+ - JWT_SECRET
+ - FILESYSTEM_PUBLIC_DISK=public
+ - FILESYSTEM_PRIVATE_DISK=local
+ - APP_CDN_URL=https://${DOMAIN}/storage
+ - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
+ - MAIL_MAILER
+ - MAIL_HOST
+ - MAIL_PORT
+ - MAIL_FROM_ADDRESS
+ - MAIL_FROM_NAME
+ depends_on:
+ - postgres
+
+ postgres:
+ image: elestio/postgres:16
+ restart: always
+ networks:
+ - dokploy-network
+ environment:
+ - POSTGRES_DB
+ - POSTGRES_USER
+ - POSTGRES_PASSWORD
+ volumes:
+ - pg_hi-events_data:/var/lib/postgresql/data
+
+networks:
+ dokploy-network:
+ external: true
+
+volumes:
+ pg_hi-events_data:
\ No newline at end of file
diff --git a/apps/dokploy/templates/hi-events/index.ts b/apps/dokploy/templates/hi-events/index.ts
new file mode 100644
index 000000000..f799bb737
--- /dev/null
+++ b/apps/dokploy/templates/hi-events/index.ts
@@ -0,0 +1,41 @@
+import {
+ type DomainSchema,
+ type Schema,
+ type Template,
+ generateRandomDomain,
+} from "../utils";
+
+export function generate(schema: Schema): Template {
+ const domains: DomainSchema[] = [
+ {
+ host: generateRandomDomain(schema),
+ port: 80,
+ serviceName: "all-in-one",
+ },
+ ];
+
+ const envs = [
+ "# change domain here",
+ "DOMAIN=my-events.com",
+ "",
+ "POSTGRES_DB=hievents",
+ "POSTGRES_USER=hievents",
+ "POSTGRES_PASSWORD=VERY_STRONG_PASSWORD",
+ "",
+ "VITE_STRIPE_PUBLISHABLE_KEY=",
+ "",
+ "APP_KEY=my-app-key",
+ "JWT_SECRET=STRONG_JWT_SECRET",
+ "",
+ "MAIL_MAILER=",
+ "MAIL_HOST=",
+ "MAIL_PORT=",
+ "MAIL_FROM_ADDRESS=",
+ "MAIL_FROM_NAME=",
+ ];
+
+ return {
+ domains,
+ envs,
+ };
+}
diff --git a/apps/dokploy/templates/infisical/docker-compose.yml b/apps/dokploy/templates/infisical/docker-compose.yml
new file mode 100644
index 000000000..3baca9265
--- /dev/null
+++ b/apps/dokploy/templates/infisical/docker-compose.yml
@@ -0,0 +1,87 @@
+services:
+ db-migration:
+ depends_on:
+ db:
+ condition: service_healthy
+ image: infisical/infisical:v0.90.1-postgres
+ environment:
+ - NODE_ENV=production
+ - ENCRYPTION_KEY
+ - AUTH_SECRET
+ - SITE_URL
+ - DB_CONNECTION_URI=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}
+ - REDIS_URL=redis://redis:6379
+ - SMTP_HOST
+ - SMTP_PORT
+ - SMTP_FROM_NAME
+ - SMTP_USERNAME
+ - SMTP_PASSWORD
+ - SMTP_SECURE=true
+ command: npm run migration:latest
+ pull_policy: always
+ networks:
+ - dokploy-network
+
+ backend:
+ restart: unless-stopped
+ depends_on:
+ db:
+ condition: service_healthy
+ redis:
+ condition: service_started
+ db-migration:
+ condition: service_completed_successfully
+ image: infisical/infisical:v0.90.1-postgres
+ pull_policy: always
+ environment:
+ - NODE_ENV=production
+ - ENCRYPTION_KEY
+ - AUTH_SECRET
+ - SITE_URL
+ - DB_CONNECTION_URI=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}
+ - REDIS_URL=redis://redis:6379
+ - SMTP_HOST
+ - SMTP_PORT
+ - SMTP_FROM_NAME
+ - SMTP_USERNAME
+ - SMTP_PASSWORD
+ - SMTP_SECURE=true
+ networks:
+ - dokploy-network
+
+ redis:
+ image: redis:7.4.1
+ env_file: .env
+ restart: always
+ environment:
+ - ALLOW_EMPTY_PASSWORD=yes
+ networks:
+ - dokploy-network
+ volumes:
+ - redis_infisical_data:/data
+
+ db:
+ image: postgres:14-alpine
+ restart: always
+ environment:
+ - POSTGRES_PASSWORD
+ - POSTGRES_USER
+ - POSTGRES_DB
+ volumes:
+ - pg_infisical_data:/var/lib/postgresql/data
+ networks:
+ - dokploy-network
+ healthcheck:
+ test: "pg_isready --username=${POSTGRES_USER} && psql --username=${POSTGRES_USER} --list"
+ interval: 5s
+ timeout: 10s
+ retries: 10
+
+volumes:
+ pg_infisical_data:
+ redis_infisical_data:
+
+networks:
+ dokploy-network:
+ external: true
+
diff --git a/apps/dokploy/templates/infisical/index.ts b/apps/dokploy/templates/infisical/index.ts
new file mode 100644
index 000000000..6d2127740
--- /dev/null
+++ b/apps/dokploy/templates/infisical/index.ts
@@ -0,0 +1,93 @@
+import {
+ type DomainSchema,
+ type Schema,
+ type Template,
+ generateRandomDomain,
+} from "../utils";
+
+export function generate(schema: Schema): Template {
+ const domains: DomainSchema[] = [
+ {
+ host: generateRandomDomain(schema),
+ port: 8080,
+ serviceName: "backend",
+ },
+ ];
+
+ const envs = [
+ "# THIS IS A SAMPLE ENCRYPTION KEY AND SHOULD NEVER BE USED FOR PRODUCTION",
+ "ENCRYPTION_KEY=6c1fe4e407b8911c104518103505b218",
+ "",
+ "# THIS IS A SAMPLE AUTH_SECRET KEY AND SHOULD NEVER BE USED FOR PRODUCTION",
+ "AUTH_SECRET=5lrMXKKWCVocS/uerPsl7V+TX/aaUaI7iDkgl3tSmLE=",
+ "# Postgres creds",
+ "POSTGRES_PASSWORD=infisical",
+ "POSTGRES_USER=infisical",
+ "POSTGRES_DB=infisical",
+ "",
+ "# Website URL",
+ "# Required",
+ "SITE_URL=http://localhost:8080",
+ "",
+ "# Mail/SMTP",
+ "SMTP_HOST=",
+ "SMTP_PORT=",
+ "SMTP_NAME=",
+ "SMTP_USERNAME=",
+ "SMTP_PASSWORD=",
+ "",
+ "# Integration",
+ "# Optional only if integration is used",
+ "CLIENT_ID_HEROKU=",
+ "CLIENT_ID_VERCEL=",
+ "CLIENT_ID_NETLIFY=",
+ "CLIENT_ID_GITHUB=",
+ "CLIENT_ID_GITHUB_APP=",
+ "CLIENT_SLUG_GITHUB_APP=",
+ "CLIENT_ID_GITLAB=",
+ "CLIENT_ID_BITBUCKET=",
+ "CLIENT_SECRET_HEROKU=",
+ "CLIENT_SECRET_VERCEL=",
+ "CLIENT_SECRET_NETLIFY=",
+ "CLIENT_SECRET_GITHUB=",
+ "CLIENT_SECRET_GITHUB_APP=",
+ "CLIENT_SECRET_GITLAB=",
+ "CLIENT_SECRET_BITBUCKET=",
+ "CLIENT_SLUG_VERCEL=",
+ "",
+ "CLIENT_PRIVATE_KEY_GITHUB_APP=",
+ "CLIENT_APP_ID_GITHUB_APP=",
+ "",
+ "# Sentry (optional) for monitoring errors",
+ "SENTRY_DSN=",
+ "",
+ "# Infisical Cloud-specific configs",
+ "# Ignore - Not applicable for self-hosted version",
+ "POSTHOG_HOST=",
+ "POSTHOG_PROJECT_API_KEY=",
+ "",
+ "# SSO-specific variables",
+ "CLIENT_ID_GOOGLE_LOGIN=",
+ "CLIENT_SECRET_GOOGLE_LOGIN=",
+ "",
+ "CLIENT_ID_GITHUB_LOGIN=",
+ "CLIENT_SECRET_GITHUB_LOGIN=",
+ "",
+ "CLIENT_ID_GITLAB_LOGIN=",
+ "CLIENT_SECRET_GITLAB_LOGIN=",
+ "",
+ "CAPTCHA_SECRET=",
+ "",
+ "NEXT_PUBLIC_CAPTCHA_SITE_KEY=",
+ "",
+ "PLAIN_API_KEY=",
+ "PLAIN_WISH_LABEL_IDS=",
+ "",
+ "SSL_CLIENT_CERTIFICATE_HEADER_KEY=",
+ ];
+
+ return {
+ domains,
+ envs,
+ };
+}
diff --git a/apps/dokploy/templates/influxdb/docker-compose.yml b/apps/dokploy/templates/influxdb/docker-compose.yml
new file mode 100644
index 000000000..1327c6028
--- /dev/null
+++ b/apps/dokploy/templates/influxdb/docker-compose.yml
@@ -0,0 +1,11 @@
+services:
+ influxdb:
+ image: influxdb:2.7.10
+ restart: unless-stopped
+ volumes:
+ - influxdb2-data:/var/lib/influxdb2
+ - influxdb2-config:/etc/influxdb2
+
+volumes:
+ influxdb2-data:
+ influxdb2-config:
\ No newline at end of file
diff --git a/apps/dokploy/templates/influxdb/index.ts b/apps/dokploy/templates/influxdb/index.ts
new file mode 100644
index 000000000..550b680e7
--- /dev/null
+++ b/apps/dokploy/templates/influxdb/index.ts
@@ -0,0 +1,19 @@
+import {
+ type DomainSchema,
+ type Schema,
+ type Template,
+ generateRandomDomain,
+} from "../utils";
+
+export function generate(schema: Schema): Template {
+ const domains: DomainSchema[] = [
+ {
+ host: generateRandomDomain(schema),
+ port: 8086,
+ serviceName: "influxdb",
+ },
+ ];
+ return {
+ domains,
+ };
+}
diff --git a/apps/dokploy/templates/macos/docker-compose.yml b/apps/dokploy/templates/macos/docker-compose.yml
new file mode 100644
index 000000000..585c1bf97
--- /dev/null
+++ b/apps/dokploy/templates/macos/docker-compose.yml
@@ -0,0 +1,16 @@
+services:
+ macos:
+ image: dockurr/macos:1.14
+ volumes:
+ - macos-storage:/storage
+ environment:
+ - VERSION
+ devices:
+ # If in .env string 'KVM=N' is not commented, you need to comment line below
+ - /dev/kvm
+ cap_add:
+ - NET_ADMIN
+ stop_grace_period: 2m
+
+volumes:
+ macos-storage:
\ No newline at end of file
diff --git a/apps/dokploy/templates/macos/index.ts b/apps/dokploy/templates/macos/index.ts
new file mode 100644
index 000000000..ebda41065
--- /dev/null
+++ b/apps/dokploy/templates/macos/index.ts
@@ -0,0 +1,33 @@
+import {
+ type DomainSchema,
+ type Schema,
+ type Template,
+ generateRandomDomain,
+} from "../utils";
+
+export function generate(schema: Schema): Template {
+ const domains: DomainSchema[] = [
+ {
+ host: generateRandomDomain(schema),
+ port: 8006,
+ serviceName: "macos",
+ },
+ ];
+
+ const envs = [
+ "# https://github.com/dockur/macos?tab=readme-ov-file#how-do-i-select-the-macos-version",
+ "VERSION=15",
+ "",
+ "# Uncomment this if your PC/VM or etc does not support virtualization technology",
+ "# KVM=N",
+ "",
+ "DISK_SIZE=64G",
+ "RAM_SIZE=4G",
+ "CPU_CORES=2",
+ ];
+
+ return {
+ domains,
+ envs,
+ };
+}
diff --git a/apps/dokploy/templates/nocodb/docker-compose.yml b/apps/dokploy/templates/nocodb/docker-compose.yml
index 726cf5e61..3d5c9ee7a 100644
--- a/apps/dokploy/templates/nocodb/docker-compose.yml
+++ b/apps/dokploy/templates/nocodb/docker-compose.yml
@@ -1,7 +1,7 @@
version: "3.8"
services:
nocodb:
- image: nocodb/nocodb:0.251.1
+ image: nocodb/nocodb:0.257.2
restart: always
environment:
NC_DB: "pg://root_db?u=postgres&p=password&d=root_db"
@@ -11,7 +11,7 @@ services:
- nc_data:/usr/app/data
root_db:
- image: postgres:14.7
+ image: postgres:17
restart: always
networks:
- dokploy-network
diff --git a/apps/dokploy/templates/soketi/docker-compose.yml b/apps/dokploy/templates/soketi/docker-compose.yml
index 1784cdc79..d38cbb086 100644
--- a/apps/dokploy/templates/soketi/docker-compose.yml
+++ b/apps/dokploy/templates/soketi/docker-compose.yml
@@ -2,8 +2,7 @@ version: "3"
services:
soketi:
- image: quay.io/soketi/soketi:1.4-16-debian
- container_name: soketi
+ image: quay.io/soketi/soketi:1.6.1-16-debian
environment:
SOKETI_DEBUG: "1"
SOKETI_HOST: "0.0.0.0"
diff --git a/apps/dokploy/templates/templates.ts b/apps/dokploy/templates/templates.ts
index c43ffc200..28af7c56e 100644
--- a/apps/dokploy/templates/templates.ts
+++ b/apps/dokploy/templates/templates.ts
@@ -125,7 +125,7 @@ export const templates: TemplateData[] = [
{
id: "uptime-kuma",
name: "Uptime Kuma",
- version: "1.21.4",
+ version: "1.23.15",
description:
"Uptime Kuma is a free and open source monitoring tool that allows you to monitor your websites and applications.",
logo: "uptime-kuma.png",
@@ -218,7 +218,6 @@ export const templates: TemplateData[] = [
version: "v1.5.6",
description:
"Documenso is the open source alternative to DocuSign for signing documents digitally",
-
links: {
github: "https://github.com/documenso/documenso",
website: "https://documenso.com/",
@@ -231,7 +230,7 @@ export const templates: TemplateData[] = [
{
id: "nocodb",
name: "NocoDB",
- version: "0.251.1",
+ version: "0.257.2",
description:
"NocoDB is an opensource Airtable alternative that turns any MySQL, PostgreSQL, SQL Server, SQLite & MariaDB into a smart spreadsheet.",
@@ -441,7 +440,7 @@ export const templates: TemplateData[] = [
{
id: "soketi",
name: "Soketi",
- version: "v1.4-16",
+ version: "v1.6.1-16",
description:
"Soketi is your simple, fast, and resilient open-source WebSockets server.",
logo: "soketi.png",
@@ -485,7 +484,7 @@ export const templates: TemplateData[] = [
{
id: "gitea",
name: "Gitea",
- version: "1.22.2",
+ version: "1.22.3",
description:
"Git with a cup of tea! Painless self-hosted all-in-one software development service, including Git hosting, code review, team collaboration, package registry and CI/CD.",
logo: "gitea.png",
@@ -557,6 +556,124 @@ export const templates: TemplateData[] = [
tags: ["cloud", "monitoring"],
load: () => import("./portainer/index").then((m) => m.generate),
},
+ {
+ id: "influxdb",
+ name: "InfluxDB",
+ version: "2.7.10",
+ description:
+ "InfluxDB 2.7 is the platform purpose-built to collect, store, process and visualize time series data.",
+ logo: "influxdb.png",
+ links: {
+ github: "https://github.com/influxdata/influxdb",
+ website: "https://www.influxdata.com/",
+ docs: "https://docs.influxdata.com/influxdb/v2/",
+ },
+ tags: ["self-hosted", "open-source", "storage", "database"],
+ load: () => import("./influxdb/index").then((m) => m.generate),
+ },
+ {
+ id: "infisical",
+ name: "Infisical",
+ version: "0.90.1",
+ description:
+ "All-in-one platform to securely manage application configuration and secrets across your team and infrastructure.",
+ logo: "infisical.jpg",
+ links: {
+ github: "https://github.com/Infisical/infisical",
+ website: "https://infisical.com/",
+ docs: "https://infisical.com/docs/documentation/getting-started/introduction",
+ },
+ tags: ["self-hosted", "open-source"],
+ load: () => import("./infisical/index").then((m) => m.generate),
+ },
+ {
+ id: "docmost",
+ name: "Docmost",
+ version: "0.4.1",
+ description:
+ "Docmost, is an open-source collaborative wiki and documentation software.",
+ logo: "docmost.png",
+ links: {
+ github: "https://github.com/docmost/docmost",
+ website: "https://docmost.com/",
+ docs: "https://docmost.com/docs/",
+ },
+ tags: ["self-hosted", "open-source", "manager"],
+ load: () => import("./docmost/index").then((m) => m.generate),
+ },
+ {
+ id: "vaultwarden",
+ name: "Vaultwarden",
+ version: "1.32.3",
+ description:
+ "Unofficial Bitwarden compatible server written in Rust, formerly known as bitwarden_rs",
+ logo: "vaultwarden.svg",
+ links: {
+ github: "https://github.com/dani-garcia/vaultwarden",
+ website: "",
+ docs: "https://github.com/dani-garcia/vaultwarden/wiki",
+ },
+ tags: ["open-source"],
+ load: () => import("./vaultwarden/index").then((m) => m.generate),
+ },
+ {
+ id: "hi-events",
+ name: "Hi.events",
+ version: "0.8.0-beta.1",
+ description:
+ "Hi.Events is a self-hosted event management and ticket selling platform that allows you to create, manage and promote events easily.",
+ logo: "hi-events.svg",
+ links: {
+ github: "https://github.com/HiEventsDev/hi.events",
+ website: "https://hi.events/",
+ docs: "https://hi.events/docs",
+ },
+ tags: ["self-hosted", "open-source", "manager"],
+ load: () => import("./hi-events/index").then((m) => m.generate),
+ },
+ {
+ id: "windows",
+ name: "Windows (dockerized)",
+ version: "4.00",
+ description: "Windows inside a Docker container.",
+ logo: "windows.png",
+ links: {
+ github: "https://github.com/dockur/windows",
+ website: "",
+ docs: "https://github.com/dockur/windows?tab=readme-ov-file#how-do-i-use-it",
+ },
+ tags: ["self-hosted", "open-source", "os"],
+ load: () => import("./windows/index").then((m) => m.generate),
+ },
+ {
+ id: "macos",
+ name: "MacOS (dockerized)",
+ version: "1.14",
+ description: "MacOS inside a Docker container.",
+ logo: "macos.png",
+ links: {
+ github: "https://github.com/dockur/macos",
+ website: "",
+ docs: "https://github.com/dockur/macos?tab=readme-ov-file#how-do-i-use-it",
+ },
+ tags: ["self-hosted", "open-source", "os"],
+ load: () => import("./macos/index").then((m) => m.generate),
+ },
+ {
+ id: "coder",
+ name: "Coder",
+ version: "2.15.3",
+ description:
+ "Coder is an open-source cloud development environment (CDE) that you host in your cloud or on-premises.",
+ logo: "coder.svg",
+ links: {
+ github: "https://github.com/coder/coder",
+ website: "https://coder.com/",
+ docs: "https://coder.com/docs",
+ },
+ tags: ["self-hosted", "open-source", "builder"],
+ load: () => import("./coder/index").then((m) => m.generate),
+ },
{
id: "stirling",
name: "Stirling PDF",
diff --git a/apps/dokploy/templates/uptime-kuma/docker-compose.yml b/apps/dokploy/templates/uptime-kuma/docker-compose.yml
index ccd775526..0d4ade73c 100644
--- a/apps/dokploy/templates/uptime-kuma/docker-compose.yml
+++ b/apps/dokploy/templates/uptime-kuma/docker-compose.yml
@@ -1,7 +1,7 @@
version: "3.8"
services:
uptime-kuma:
- image: louislam/uptime-kuma:1
+ image: louislam/uptime-kuma:1.23.15
restart: always
volumes:
- uptime-kuma-data:/app/data
diff --git a/apps/dokploy/templates/vaultwarden/docker-compose.yml b/apps/dokploy/templates/vaultwarden/docker-compose.yml
new file mode 100644
index 000000000..456f585b2
--- /dev/null
+++ b/apps/dokploy/templates/vaultwarden/docker-compose.yml
@@ -0,0 +1,14 @@
+services:
+ vaultwarden:
+ image: vaultwarden/server:1.32.3
+ restart: always
+ environment:
+ DOMAIN: ${DOMAIN}
+ SIGNUPS_ALLOWED: ${SIGNUPS_ALLOWED}
+ volumes:
+ - vaultwarden:/data
+ ports:
+ - 80
+
+volumes:
+ vaultwarden:
diff --git a/apps/dokploy/templates/vaultwarden/index.ts b/apps/dokploy/templates/vaultwarden/index.ts
new file mode 100644
index 000000000..66aa14657
--- /dev/null
+++ b/apps/dokploy/templates/vaultwarden/index.ts
@@ -0,0 +1,28 @@
+import {
+ type DomainSchema,
+ type Schema,
+ type Template,
+ generateRandomDomain,
+} from "../utils";
+
+export function generate(schema: Schema): Template {
+ const domains: DomainSchema[] = [
+ {
+ host: generateRandomDomain(schema),
+ port: 80,
+ serviceName: "vaultwarden",
+ },
+ ];
+
+ const envs = [
+ "# Deactivate this with 'false' after you have created your account so that no strangers can register",
+ "SIGNUPS_ALLOWED=true",
+ "# required when using a reverse proxy; your domain; vaultwarden needs to know it's https to work properly with attachments",
+ "DOMAIN=https://vaultwarden.example.com",
+ ];
+
+ return {
+ domains,
+ envs,
+ };
+}
diff --git a/apps/dokploy/templates/windows/docker-compose.yml b/apps/dokploy/templates/windows/docker-compose.yml
new file mode 100644
index 000000000..8a0833702
--- /dev/null
+++ b/apps/dokploy/templates/windows/docker-compose.yml
@@ -0,0 +1,17 @@
+services:
+ windows:
+ image: dockurr/windows:4.00
+ volumes:
+ - win-storage:/storage
+ environment:
+ - VERSION
+ - KVM
+ devices:
+ # If in .env string 'KVM=N' is not commented, you need to comment line below
+ - /dev/kvm
+ cap_add:
+ - NET_ADMIN
+ stop_grace_period: 2m
+
+volumes:
+ win-storage:
\ No newline at end of file
diff --git a/apps/dokploy/templates/windows/index.ts b/apps/dokploy/templates/windows/index.ts
new file mode 100644
index 000000000..5e2728cb0
--- /dev/null
+++ b/apps/dokploy/templates/windows/index.ts
@@ -0,0 +1,39 @@
+import {
+ type DomainSchema,
+ type Schema,
+ type Template,
+ generateRandomDomain,
+} from "../utils";
+
+export function generate(schema: Schema): Template {
+ const domains: DomainSchema[] = [
+ {
+ host: generateRandomDomain(schema),
+ port: 8006,
+ serviceName: "windows",
+ },
+ ];
+
+ const envs = [
+ "# https://github.com/dockur/windows?tab=readme-ov-file#how-do-i-select-the-windows-version",
+ "VERSION=win11",
+ "",
+ "# Uncomment this if your PC/VM or etc does not support virtualization technology",
+ "# KVM=N",
+ "",
+ "DISK_SIZE=64G",
+ "RAM_SIZE=4G",
+ "CPU_CORES=2",
+ "",
+ "USERNAME=Dokploy",
+ "PASSWORD=",
+ "",
+ "# https://github.com/dockur/windows?tab=readme-ov-file#how-do-i-select-the-windows-language",
+ "LANGUAGE=English",
+ ];
+
+ return {
+ domains,
+ envs,
+ };
+}
diff --git a/packages/server/src/services/mongo.ts b/packages/server/src/services/mongo.ts
index 1360372da..b87ec4da9 100644
--- a/packages/server/src/services/mongo.ts
+++ b/packages/server/src/services/mongo.ts
@@ -14,7 +14,7 @@ export type Mongo = typeof mongo.$inferSelect;
export const createMongo = async (input: typeof apiCreateMongo._type) => {
input.appName =
- `${input.appName}-${generatePassword(6)}` || generateAppName("postgres");
+ `${input.appName}-${generatePassword(6)}` || generateAppName("mongo");
if (input.appName) {
const valid = await validUniqueServerAppName(input.appName);
@@ -72,12 +72,12 @@ export const findMongoById = async (mongoId: string) => {
export const updateMongoById = async (
mongoId: string,
- postgresData: Partial,
+ mongoData: Partial,
) => {
const result = await db
.update(mongo)
.set({
- ...postgresData,
+ ...mongoData,
})
.where(eq(mongo.mongoId, mongoId))
.returning();
diff --git a/packages/server/src/utils/docker/domain.ts b/packages/server/src/utils/docker/domain.ts
index 28ede3085..a065f31c0 100644
--- a/packages/server/src/utils/docker/domain.ts
+++ b/packages/server/src/utils/docker/domain.ts
@@ -268,6 +268,12 @@ export const createDomainLabels = async (
`traefik.http.routers.${routerName}.service=${routerName}`,
];
+ if (domain.path) {
+ labels.push(
+ `traefik.http.routers.${routerName}.rule=PathPrefix(\`${domain.path}\`)`,
+ );
+ }
+
if (entrypoint === "web" && https) {
labels.push(
`traefik.http.routers.${routerName}.middlewares=redirect-to-https@file`,