Merge pull request #363 from Dokploy/fix/domains-schema-templates

refactor(templates): use domains tab instead of envs
This commit is contained in:
Mauricio Siu
2024-08-18 19:58:23 -06:00
committed by GitHub
58 changed files with 371 additions and 541 deletions

View File

@@ -166,20 +166,26 @@ import {
generateRandomDomain,
type Template,
type Schema,
type DomainSchema,
} from "../utils";
export function generate(schema: Schema): Template {
// do your stuff here, like create a new domain, generate random passwords, mounts.
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const mainDomain = generateRandomDomain(schema);
const secretBase = generateBase64(64);
const toptKeyBase = generateBase64(32);
const domains: DomainSchema[] = [
{
host: mainDomain,
port: 8000,
serviceName: "plausible",
},
];
const envs = [
// If you want to show a domain in the UI, please add the prefix _HOST at the end of the variable name.
`PLAUSIBLE_HOST=${randomDomain}`,
"PLAUSIBLE_PORT=8000",
`BASE_URL=http://${randomDomain}`,
`BASE_URL=http://${mainDomain}`,
`SECRET_KEY_BASE=${secretBase}`,
`TOTP_VAULT_KEY=${toptKeyBase}`,
`HASH=${mainServiceHash}`,
@@ -195,6 +201,7 @@ export function generate(schema: Schema): Template {
return {
envs,
mounts,
domains,
};
}
```

26
LICENSE.MD Normal file
View File

@@ -0,0 +1,26 @@
# License
## Core License (Apache License 2.0)
Copyright 2024 Mauricio Siu.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.
## Additional Terms for Specific Features
The following additional terms apply to the multi-node support and Docker Compose file support features of Dokploy. In the event of a conflict, these provisions shall take precedence over those in the Apache License:
- **Self-Hosted Version Free**: All features of Dokploy, including multi-node support and Docker Compose file support, will always be free to use in the self-hosted version.
- **Restriction on Resale**: The multi-node support and Docker Compose file support features cannot be sold or offered as a service by any party other than the copyright holder without prior written consent.
- **Modification Distribution**: Any modifications to the multi-node support and Docker Compose file support features must be distributed freely and cannot be sold or offered as a service.
For further inquiries or permissions, please contact us directly.

View File

@@ -41,7 +41,7 @@ import {
updateCompose,
} from "../services/compose";
import { removeDeploymentsByComposeId } from "../services/deployment";
import { findDomainsByComposeId } from "../services/domain";
import { createDomain, findDomainsByComposeId } from "../services/domain";
import { createMount } from "../services/mount";
import { findProjectById } from "../services/project";
import { addNewService, checkServiceAccess } from "../services/user";
@@ -236,7 +236,7 @@ export const composeRouter = createTRPCRouter({
const project = await findProjectById(input.projectId);
const projectName = slugify(`${project.name} ${input.id}`);
const { envs, mounts } = generate({
const { envs, mounts, domains } = generate({
serverIp: admin.serverIp,
projectName: projectName,
});
@@ -244,7 +244,7 @@ export const composeRouter = createTRPCRouter({
const compose = await createComposeByTemplate({
...input,
composeFile: composeFile,
env: envs.join("\n"),
env: envs?.join("\n"),
name: input.id,
sourceType: "raw",
appName: `${projectName}-${generatePassword(6)}`,
@@ -267,6 +267,17 @@ export const composeRouter = createTRPCRouter({
}
}
if (domains && domains?.length > 0) {
for (const domain of domains) {
await createDomain({
...domain,
domainType: "compose",
certificateType: "none",
composeId: compose.composeId,
});
}
}
return null;
}),

View File

@@ -2,17 +2,5 @@ version: "3.8"
services:
appsmith:
image: index.docker.io/appsmith/appsmith-ee:v1.29
networks:
- dokploy-network
ports:
- ${APP_SMITH_PORT}
labels:
- "traefik.enable=true"
- "traefik.http.routers.${HASH}.rule=Host(`${APP_SMITH_HOST}`)"
- "traefik.http.services.${HASH}.loadbalancer.server.port=${APP_SMITH_PORT}"
volumes:
- ../files/stacks:/appsmith-stacks
networks:
dokploy-network:
external: true

View File

@@ -1,4 +1,5 @@
import {
type DomainSchema,
type Schema,
type Template,
generateHash,
@@ -7,14 +8,16 @@ import {
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const envs = [
`APP_SMITH_HOST=${randomDomain}`,
"APP_SMITH_PORT=80",
`HASH=${mainServiceHash}`,
const domains: DomainSchema[] = [
{
host: generateRandomDomain(schema),
port: 80,
serviceName: "appsmith",
},
];
return {
envs,
domains,
};
}

View File

@@ -2,21 +2,9 @@ version: "3.8"
services:
baserow:
image: baserow/baserow:1.25.2
networks:
- dokploy-network
environment:
BASEROW_PUBLIC_URL: "http://${BASEROW_HOST}"
ports:
- ${BASEROW_PORT}
labels:
- traefik.enable=true
- traefik.http.routers.${HASH}.rule=Host(`${BASEROW_HOST}`)
- traefik.http.services.${HASH}.loadbalancer.server.port=${BASEROW_PORT}
volumes:
- baserow_data:/baserow/data
volumes:
baserow_data:
networks:
dokploy-network:
external: true

View File

@@ -1,20 +1,24 @@
import {
type DomainSchema,
type Schema,
type Template,
generateHash,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const envs = [
`BASEROW_HOST=${randomDomain}`,
"BASEROW_PORT=80",
`HASH=${mainServiceHash}`,
const mainHost = generateRandomDomain(schema);
const domains: DomainSchema[] = [
{
host: mainHost,
port: 80,
serviceName: "baserow",
},
];
const envs = [`BASEROW_HOST=${mainHost}`];
return {
envs,
domains,
};
}

View File

@@ -21,16 +21,6 @@ services:
- DATABASE_URL=postgres://postgres:password@postgres:5432/db
- NEXT_PUBLIC_WEBAPP_URL=http://${CALCOM_HOST}
- NEXTAUTH_URL=http://${CALCOM_HOST}/api/auth
networks:
- dokploy-network
labels:
- "traefik.enable=true"
- "traefik.http.routers.${HASH}.rule=Host(`${CALCOM_HOST}`)"
- "traefik.http.services.${HASH}.loadbalancer.server.port=${CALCOM_PORT}"
networks:
dokploy-network:
external: true
volumes:
calcom-data:

View File

@@ -1,27 +1,32 @@
import {
type DomainSchema,
type Schema,
type Template,
generateBase64,
generateHash,
generateRandomDomain,
} from "../utils";
// https://cal.com/
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const mainDomain = generateRandomDomain(schema);
const calcomEncryptionKey = generateBase64(32);
const nextAuthSecret = generateBase64(32);
const domains: DomainSchema[] = [
{
host: mainDomain,
port: 3000,
serviceName: "calcom",
},
];
const envs = [
`CALCOM_HOST=${randomDomain}`,
"CALCOM_PORT=3000",
`HASH=${mainServiceHash}`,
`CALCOM_HOST=${mainDomain}`,
`NEXTAUTH_SECRET=${nextAuthSecret}`,
`CALENDSO_ENCRYPTION_KEY=${calcomEncryptionKey}`,
];
return {
envs,
domains,
};
}

View File

@@ -18,8 +18,6 @@ services:
directus:
image: directus/directus:10.12.1
networks:
- dokploy-network
ports:
- 8055
volumes:
@@ -28,10 +26,6 @@ services:
depends_on:
- cache
- database
labels:
- traefik.enable=true
- traefik.http.routers.${HASH}.rule=Host(`${DIRECTUS_HOST}`)
- traefik.http.services.${HASH}.loadbalancer.server.port=${DIRECTUS_PORT}
environment:
SECRET: "replace-with-secure-random-value"
@@ -49,8 +43,5 @@ services:
ADMIN_EMAIL: "admin@example.com"
ADMIN_PASSWORD: "d1r3ctu5"
networks:
dokploy-network:
external: true
volumes:
directus:

View File

@@ -1,20 +1,20 @@
import {
type DomainSchema,
type Schema,
type Template,
generateHash,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const envs = [
`DIRECTUS_HOST=${randomDomain}`,
"DIRECTUS_PORT=8055",
`HASH=${mainServiceHash}`,
const domains: DomainSchema[] = [
{
host: generateRandomDomain(schema),
port: 8055,
serviceName: "directus",
},
];
return {
envs,
domains,
};
}

View File

@@ -19,8 +19,6 @@ services:
documenso:
image: documenso/documenso:1.5.6-rc.2
networks:
- dokploy-network
depends_on:
postgres:
condition: service_healthy
@@ -38,16 +36,8 @@ services:
- NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH=/opt/documenso/cert.p12
ports:
- ${DOCUMENSO_PORT}
labels:
- "traefik.enable=true"
- "traefik.http.routers.${HASH}.rule=Host(`${DOCUMENSO_HOST}`)"
- "traefik.http.services.${HASH}.loadbalancer.server.port=${DOCUMENSO_PORT}"
volumes:
- /opt/documenso/cert.p12:/opt/documenso/cert.p12
networks:
dokploy-network:
external: true
volumes:
documenso-data:

View File

@@ -1,24 +1,29 @@
import {
type DomainSchema,
type Schema,
type Template,
generateBase64,
generateHash,
generatePassword,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const mainDomain = generateRandomDomain(schema);
const nextAuthSecret = generateBase64(32);
const documensoEncryptionKey = generatePassword(32);
const documensoSecondaryEncryptionKey = generatePassword(64);
const domains: DomainSchema[] = [
{
host: mainDomain,
port: 3000,
serviceName: "documenso",
},
];
const envs = [
`DOCUMENSO_HOST=${randomDomain}`,
`DOCUMENSO_HOST=${mainDomain}`,
"DOCUMENSO_PORT=3000",
`HASH=${mainServiceHash}`,
`NEXTAUTH_SECRET=${nextAuthSecret}`,
`NEXT_PRIVATE_ENCRYPTION_KEY=${documensoEncryptionKey}`,
`NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY=${documensoSecondaryEncryptionKey}`,
@@ -26,5 +31,6 @@ export function generate(schema: Schema): Template {
return {
envs,
domains,
};
}

View File

@@ -2,10 +2,6 @@ services:
doublezero:
restart: always
image: liltechnomancer/double-zero:0.2.1
ports:
- ${DOUBLEZERO_PORT}
networks:
- dokploy-network
volumes:
- db-data:/var/lib/doublezero/data
environment:
@@ -17,15 +13,7 @@ services:
SECRET_KEY_BASE: ${SECRET_KEY_BASE}
PHX_HOST: ${DOUBLEZERO_HOST}
DATABASE_PATH: ./00.db
labels:
- "traefik.enable=true"
- "traefik.http.routers.${HASH}.rule=Host(`${DOUBLEZERO_HOST}`)"
- "traefik.http.services.${HASH}.loadbalancer.server.port=${DOUBLEZERO_PORT}"
volumes:
db-data:
driver: local
networks:
dokploy-network:
external: true

View File

@@ -1,20 +1,26 @@
import {
type DomainSchema,
type Schema,
type Template,
generateBase64,
generateHash,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const mainDomain = generateRandomDomain(schema);
const secretKeyBase = generateBase64(64);
const domains: DomainSchema[] = [
{
host: mainDomain,
port: 4000,
serviceName: "doublezero",
},
];
const envs = [
`DOUBLEZERO_HOST=${randomDomain}`,
`DOUBLEZERO_HOST=${mainDomain}`,
"DOUBLEZERO_PORT=4000",
`HASH=${mainServiceHash}`,
`SECRET_KEY_BASE=${secretKeyBase}`,
"AWS_ACCESS_KEY_ID=your-aws-access-key",
"AWS_SECRET_ACCESS_KEY=your-aws-secret-key",
@@ -25,5 +31,6 @@ export function generate(schema: Schema): Template {
return {
envs,
domains,
};
}

View File

@@ -1,17 +1,7 @@
version: '3.8'
version: "3.8"
services:
excalidraw:
networks:
- dokploy-network
image: excalidraw/excalidraw:latest
ports:
- ${EXCALIDRAW_PORT}
labels:
- traefik.enable=true
- traefik.http.routers.${HASH}.rule=Host(`${EXCALIDRAW_HOST}`)
- traefik.http.services.${HASH}.loadbalancer.server.port=${EXCALIDRAW_PORT}
networks:
dokploy-network:
external: true

View File

@@ -1,4 +1,5 @@
import {
type DomainSchema,
type Schema,
type Template,
generateHash,
@@ -6,15 +7,17 @@ import {
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const envs = [
`EXCALIDRAW_HOST=${randomDomain}`,
"EXCALIDRAW_PORT=80",
`HASH=${mainServiceHash}`,
const mainDomain = generateRandomDomain(schema);
const domains: DomainSchema[] = [
{
host: mainDomain,
port: 80,
serviceName: "excalidraw",
},
];
return {
envs,
domains,
};
}

View File

@@ -1,13 +1,8 @@
version: "3.8"
services:
ghost:
image: ghost:5-alpine
restart: always
networks:
- dokploy-network
ports:
- ${GHOST_PORT}
environment:
database__client: mysql
database__connection__host: db
@@ -15,10 +10,7 @@ services:
database__connection__password: example
database__connection__database: ghost
url: http://${GHOST_HOST}
labels:
- traefik.enable=true
- traefik.http.routers.${HASH}.rule=Host(`${GHOST_HOST}`)
- traefik.http.services.${HASH}.loadbalancer.server.port=${GHOST_PORT}
volumes:
- ghost:/var/lib/ghost/content
@@ -35,7 +27,3 @@ services:
volumes:
ghost:
db:
networks:
dokploy-network:
external: true

View File

@@ -1,4 +1,5 @@
import {
type DomainSchema,
type Schema,
type Template,
generateHash,
@@ -6,15 +7,19 @@ import {
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const envs = [
`GHOST_HOST=${randomDomain}`,
"GHOST_PORT=2368",
`HASH=${mainServiceHash}`,
const mainDomain = generateRandomDomain(schema);
const domains: DomainSchema[] = [
{
host: mainDomain,
port: 2368,
serviceName: "ghost",
},
];
const envs = [`GHOST_HOST=${mainDomain}`];
return {
envs,
domains,
};
}

View File

@@ -1,16 +1,14 @@
x-environment:
&default-environment
x-environment: &default-environment
DATABASE_URL: postgres://postgres:postgres@postgres:5432/postgres
SECRET_KEY: ${SECRET_KEY}
PORT: ${GLITCHTIP_PORT}
EMAIL_URL: consolemail://
GLITCHTIP_DOMAIN: http://${GLITCHTIP_HOST}
GLITCHTIP_DOMAIN: http://${GLITCHTIP_HOST}
DEFAULT_FROM_EMAIL: email@glitchtip.com
CELERY_WORKER_AUTOSCALE: "1,3"
CELERY_WORKER_AUTOSCALE: "1,3"
CELERY_WORKER_MAX_TASKS_PER_CHILD: "10000"
x-depends_on:
&default-depends_on
x-depends_on: &default-depends_on
- postgres
- redis
@@ -18,7 +16,7 @@ services:
postgres:
image: postgres:16
environment:
POSTGRES_HOST_AUTH_METHOD: "trust"
POSTGRES_HOST_AUTH_METHOD: "trust"
restart: unless-stopped
volumes:
- pg-data:/var/lib/postgresql/data
@@ -36,21 +34,15 @@ services:
- ${GLITCHTIP_PORT}
environment: *default-environment
restart: unless-stopped
volumes:
volumes:
- uploads:/code/uploads
networks:
- dokploy-network
labels:
- traefik.enable=true
- traefik.http.routers.${HASH}.rule=Host(`${GLITCHTIP_HOST}`)
- traefik.http.services.${HASH}.loadbalancer.server.port=${GLITCHTIP_PORT}
worker:
image: glitchtip/glitchtip:v4.0
command: ./bin/run-celery-with-beat.sh
depends_on: *default-depends_on
environment: *default-environment
restart: unless-stopped
volumes:
volumes:
- uploads:/code/uploads
networks:
- dokploy-network
@@ -65,7 +57,3 @@ services:
volumes:
pg-data:
uploads:
networks:
dokploy-network:
external: true

View File

@@ -1,23 +1,30 @@
import {
type DomainSchema,
type Schema,
type Template,
generateBase64,
generateHash,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const mainDomain = generateRandomDomain(schema);
const secretKey = generateBase64(32);
const domains: DomainSchema[] = [
{
host: mainDomain,
port: 8000,
serviceName: "web",
},
];
const envs = [
`GLITCHTIP_HOST=${randomDomain}`,
`GLITCHTIP_HOST=${mainDomain}`,
"GLITCHTIP_PORT=8000",
`SECRET_KEY=${secretKey}`,
`HASH=${mainServiceHash}`,
];
return {
envs,
domains,
};
}

View File

@@ -1,20 +1,9 @@
version: "3.8"
services:
grafana:
networks:
- dokploy-network
image: grafana/grafana-enterprise:9.5.20
restart: unless-stopped
ports:
- ${GRAFANA_PORT}
labels:
- traefik.enable=true
- traefik.http.routers.${HASH}.rule=Host(`${GRAFANA_HOST}`)
- traefik.http.services.${HASH}.loadbalancer.server.port=${GRAFANA_PORT}
volumes:
- grafana-storage:/var/lib/grafana
networks:
dokploy-network:
external: true
volumes:
grafana-storage: {}
grafana-storage: {}

View File

@@ -1,20 +1,19 @@
import {
type DomainSchema,
type Schema,
type Template,
generateHash,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const envs = [
`GRAFANA_HOST=${randomDomain}`,
"GRAFANA_PORT=3000",
`HASH=${mainServiceHash}`,
const domains: DomainSchema[] = [
{
host: generateRandomDomain(schema),
port: 3000,
serviceName: "grafana",
},
];
return {
envs,
domains,
};
}

View File

@@ -1,30 +1,19 @@
version: '3.8'
version: "3.8"
services:
jellyfin:
image: jellyfin/jellyfin:10
networks:
- dokploy-network
ports:
- ${JELLYFIN_PORT}
labels:
- "traefik.enable=true"
- "traefik.http.routers.${HASH}.rule=Host(`${JELLYFIN_HOST}`)"
- "traefik.http.services.${HASH}.loadbalancer.server.port=${JELLYFIN_PORT}"
volumes:
- config:/config
- cache:/cache
- media:/media
restart: 'unless-stopped'
restart: "unless-stopped"
# Optional - alternative address used for autodiscovery
environment:
- JELLYFIN_PublishedServerUrl=http://${JELLYFIN_HOST}
# Optional - may be necessary for docker healthcheck to pass if running in host network mode
extra_hosts:
- 'host.docker.internal:host-gateway'
- "host.docker.internal:host-gateway"
volumes:
config:
cache:
media:
networks:
dokploy-network:
external: true

View File

@@ -1,22 +1,25 @@
// EXAMPLE
import {
type DomainSchema,
type Schema,
type Template,
generateHash,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const port = 8096;
const envs = [
`JELLYFIN_HOST=${randomDomain}`,
`HASH=${mainServiceHash}`,
`JELLYFIN_PORT=${port}`,
const domain = generateRandomDomain(schema);
const domains: DomainSchema[] = [
{
host: domain,
port: 8096,
serviceName: "jellyfin",
},
];
const envs = [`JELLYFIN_HOST=${domain}`];
return {
envs,
domains,
};
}

View File

@@ -36,10 +36,6 @@ services:
app:
restart: unless-stopped
image: listmonk/listmonk:v3.0.0
ports:
- "${LISTMONK_PORT}"
networks:
- dokploy-network
environment:
- TZ=Etc/UTC
depends_on:
@@ -47,15 +43,7 @@ services:
- setup
volumes:
- ../files/config.toml:/listmonk/config.toml
labels:
- "traefik.enable=true"
- "traefik.http.routers.${HASH}.rule=Host(`${LISTMONK_HOST}`)"
- "traefik.http.services.${HASH}.loadbalancer.server.port=${LISTMONK_PORT}"
volumes:
listmonk-data:
driver: local
networks:
dokploy-network:
external: true

View File

@@ -1,20 +1,24 @@
import {
type DomainSchema,
type Schema,
type Template,
generateHash,
generatePassword,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const adminPassword = generatePassword(32);
const domains: DomainSchema[] = [
{
host: randomDomain,
port: 9000,
serviceName: "app",
},
];
const envs = [
`LISTMONK_HOST=${randomDomain}`,
"LISTMONK_PORT=9000",
`HASH=${mainServiceHash}`,
`# login with admin:${adminPassword}`,
"# check config.toml in Advanced / Volumes for more options",
];
@@ -48,5 +52,6 @@ params = ""
return {
envs,
mounts,
domains,
};
}

View File

@@ -1,25 +1,14 @@
version: '3.8'
version: "3.8"
services:
meilisearch:
networks:
- dokploy-network
image: getmeili/meilisearch:v1.8.3
ports:
- ${MEILISEARCH_PORT}
volumes:
- meili_data:/meili_data
environment:
MEILI_MASTER_KEY: ${MEILI_MASTER_KEY}
MEILI_ENV: ${MEILI_ENV}
labels:
- traefik.enable=true
- traefik.http.routers.${HASH}.rule=Host(`${MEILISEARCH_HOST}`)
- traefik.http.services.${HASH}.loadbalancer.server.port=${MEILISEARCH_PORT}
volumes:
meili_data:
driver: local
networks:
dokploy-network:
external: true

View File

@@ -1,24 +1,26 @@
import {
type DomainSchema,
type Schema,
type Template,
generateBase64,
generateHash,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const mainDomain = generateRandomDomain(schema);
const masterKey = generateBase64(32);
const envs = [
`MEILISEARCH_HOST=${randomDomain}`,
"MEILISEARCH_PORT=7700",
"MEILI_ENV=development",
`MEILI_MASTER_KEY=${masterKey}`,
`HASH=${mainServiceHash}`,
const domains: DomainSchema[] = [
{
host: mainDomain,
port: 7700,
serviceName: "meilisearch",
},
];
const envs = ["MEILI_ENV=development", `MEILI_MASTER_KEY=${masterKey}`];
return {
envs,
domains,
};
}

View File

@@ -4,8 +4,6 @@ services:
image: metabase/metabase:v0.50.8
volumes:
- /dev/urandom:/dev/random:ro
ports:
- ${METABASE_PORT}
environment:
MB_DB_TYPE: postgres
MB_DB_DBNAME: metabaseappdb
@@ -13,17 +11,11 @@ services:
MB_DB_USER: metabase
MB_DB_PASS: mysecretpassword
MB_DB_HOST: postgres
networks:
- dokploy-network
healthcheck:
test: curl --fail -I http://localhost:3000/api/health || exit 1
interval: 15s
timeout: 5s
retries: 5
labels:
- traefik.enable=true
- traefik.http.routers.${HASH}.rule=Host(`${METABASE_HOST}`)
- traefik.http.services.${HASH}.loadbalancer.server.port=${METABASE_PORT}
postgres:
image: postgres:14
environment:
@@ -32,7 +24,3 @@ services:
POSTGRES_PASSWORD: mysecretpassword
networks:
- dokploy-network
networks:
dokploy-network:
external: true

View File

@@ -1,20 +1,22 @@
import {
type DomainSchema,
type Schema,
type Template,
generateHash,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const envs = [
`METABASE_HOST=${randomDomain}`,
"METABASE_PORT=3000",
`HASH=${mainServiceHash}`,
const domains: DomainSchema[] = [
{
host: randomDomain,
port: 3000,
serviceName: "metabase",
},
];
return {
envs,
domains,
};
}

View File

@@ -1,31 +1,13 @@
version: '3.8'
version: "3.8"
services:
minio:
image: minio/minio
ports:
- ${MINIO_API_PORT}
- ${MINIO_DASHBOARD_PORT}
volumes:
- minio-data:/data
environment:
- MINIO_ROOT_USER=minioadmin
- MINIO_ROOT_PASSWORD=minioadmin123
command: server /data --console-address ":9001"
networks:
- dokploy-network
labels:
- traefik.enable=true
- traefik.http.routers.${HASH}.service=${HASH}
- traefik.http.routers.${HASH}.rule=Host(`${MINIO_DASHBOARD_HOST}`)
- traefik.http.services.${HASH}.loadbalancer.server.port=${MINIO_DASHBOARD_PORT}
# API router and service
- traefik.http.routers.${HASH}-api.service=${HASH}-api
- traefik.http.routers.${HASH}-api.rule=Host(`${MINIO_API_HOST}`)
- traefik.http.services.${HASH}-api.loadbalancer.server.port=${MINIO_API_PORT}
volumes:
minio-data:
networks:
dokploy-network:
external: true

View File

@@ -1,23 +1,28 @@
import {
type DomainSchema,
type Schema,
type Template,
generateHash,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const mainDomain = generateRandomDomain(schema);
const apiDomain = generateRandomDomain(schema);
const envs = [
`MINIO_DASHBOARD_HOST=${randomDomain}`,
"MINIO_DASHBOARD_PORT=9001",
`MINIO_API_HOST=${apiDomain}`,
"MINIO_API_PORT=9000",
`HASH=${mainServiceHash}`,
const domains: DomainSchema[] = [
{
host: mainDomain,
port: 9001,
serviceName: "minio",
},
{
host: apiDomain,
port: 9000,
serviceName: "minio",
},
];
return {
envs,
domains,
};
}

View File

@@ -3,17 +3,9 @@ services:
n8n:
image: docker.n8n.io/n8nio/n8n:1.48.1
restart: always
networks:
- dokploy-network
ports:
- ${N8N_PORT}
labels:
- traefik.enable=true
- traefik.http.routers.${HASH}.rule=Host(`${N8N_HOST}`)
- traefik.http.services.${HASH}.loadbalancer.server.port=${N8N_PORT}
environment:
- N8N_HOST=${N8N_HOST}
- N8N_PORT=5678
- N8N_PORT=${N8N_PORT}
- N8N_PROTOCOL=http
- NODE_ENV=production
- WEBHOOK_URL=https://${N8N_HOST}/
@@ -23,7 +15,4 @@ services:
- n8n_data:/home/node/.n8n
volumes:
n8n_data:
networks:
dokploy-network:
external: true
n8n_data:

View File

@@ -1,21 +1,28 @@
import {
type DomainSchema,
type Schema,
type Template,
generateHash,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const mainDomain = generateRandomDomain(schema);
const domains: DomainSchema[] = [
{
host: mainDomain,
port: 5678,
serviceName: "n8n",
},
];
const envs = [
`N8N_HOST=${randomDomain}`,
`N8N_HOST=${mainDomain}`,
"N8N_PORT=5678",
`HASH=${mainServiceHash}`,
"GENERIC_TIMEZONE=Europe/Berlin",
];
return {
envs,
domains,
};
}

View File

@@ -3,18 +3,10 @@ services:
nocodb:
image: nocodb/nocodb:0.251.1
restart: always
networks:
- dokploy-network
ports:
- ${NOCODB_PORT}
environment:
NC_DB : "pg://root_db?u=postgres&p=password&d=root_db"
PORT : ${NOCODB_PORT}
NC_DB: "pg://root_db?u=postgres&p=password&d=root_db"
PORT: ${NOCODB_PORT}
NC_REDIS_URL: ${NC_REDIS_URL}
labels:
- traefik.enable=true
- traefik.http.routers.${HASH}.rule=Host(`${NOCODB_HOST}`)
- traefik.http.services.${HASH}.loadbalancer.server.port=${NOCODB_PORT}
volumes:
- nc_data:/usr/app/data
@@ -30,15 +22,11 @@ services:
healthcheck:
interval: 10s
retries: 10
test: "pg_isready -U \"$$POSTGRES_USER\" -d \"$$POSTGRES_DB\""
test: 'pg_isready -U "$$POSTGRES_USER" -d "$$POSTGRES_DB"'
timeout: 2s
volumes:
- "db_data:/var/lib/postgresql/data"
networks:
dokploy-network:
external: true
volumes:
db_data: {}
nc_data: {}
nc_data: {}

View File

@@ -1,26 +1,28 @@
// EXAMPLE
import {
type DomainSchema,
type Schema,
type Template,
generateBase64,
generateHash,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const secretBase = generateBase64(64);
const toptKeyBase = generateBase64(32);
const envs = [
`NOCODB_HOST=${randomDomain}`,
"NOCODB_PORT=8000",
`NC_AUTH_JWT_SECRET=${secretBase}`,
`HASH=${mainServiceHash}`,
const domains: DomainSchema[] = [
{
host: randomDomain,
port: 8000,
serviceName: "nocodb",
},
];
const envs = ["NOCODB_PORT=8000", `NC_AUTH_JWT_SECRET=${secretBase}`];
return {
envs,
domains,
};
}

View File

@@ -2,20 +2,12 @@ version: "3.8"
services:
web:
image: odoo:16.0
networks:
- dokploy-network
depends_on:
- db
ports:
- ${ODOO_PORT}
environment:
- HOST=db
- USER=odoo
- PASSWORD=odoo
labels:
- "traefik.enable=true"
- "traefik.http.routers.${HASH}.rule=Host(`${ODOO_HOST}`)"
- "traefik.http.services.${HASH}.loadbalancer.server.port=${ODOO_PORT}"
volumes:
- odoo-web-data:/var/lib/odoo
- ../files/config:/etc/odoo
@@ -35,7 +27,3 @@ services:
volumes:
odoo-web-data:
odoo-db-data:
networks:
dokploy-network:
external: true

View File

@@ -1,20 +1,22 @@
import {
type DomainSchema,
type Schema,
type Template,
generateHash,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const envs = [
`ODOO_HOST=${randomDomain}`,
"ODOO_PORT=8069",
`HASH=${mainServiceHash}`,
const domains: DomainSchema[] = [
{
host: randomDomain,
port: 8069,
serviceName: "web",
},
];
return {
envs,
domains,
};
}

View File

@@ -1,6 +1,5 @@
version: '3.8'
version: "3.8"
services:
ollama:
volumes:
- ollama:/root/.ollama
@@ -13,24 +12,14 @@ services:
open-webui:
image: ghcr.io/open-webui/open-webui:${WEBUI_DOCKER_TAG-main}
networks:
- dokploy-network
volumes:
- open-webui:/app/backend/data
depends_on:
- ollama
environment:
- 'OLLAMA_BASE_URL=http://ollama:11434'
- 'WEBUI_SECRET_KEY='
- "OLLAMA_BASE_URL=http://ollama:11434"
- "WEBUI_SECRET_KEY="
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.${HASH}.rule=Host(`${OPEN_WEBUI_HOST}`)"
- "traefik.http.services.${HASH}.loadbalancer.server.port=${OPEN_WEBUI_PORT}"
networks:
dokploy-network:
external: true
volumes:
ollama: {}

View File

@@ -1,22 +1,24 @@
import {
type DomainSchema,
type Schema,
type Template,
generateHash,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const envs = [
`OPEN_WEBUI_HOST=${randomDomain}`,
"OPEN_WEBUI_PORT=8080",
`HASH=${mainServiceHash}`,
"OLLAMA_DOCKER_TAG=0.1.47",
"WEBUI_DOCKER_TAG=0.3.7",
const domains: DomainSchema[] = [
{
host: randomDomain,
port: 8080,
serviceName: "open-webui",
},
];
const envs = ["OLLAMA_DOCKER_TAG=0.1.47", "WEBUI_DOCKER_TAG=0.3.7"];
return {
envs,
domains,
};
}

View File

@@ -1,4 +1,4 @@
version: '3.8'
version: "3.8"
services:
db:
@@ -20,21 +20,9 @@ services:
PMA_USER: ${MYSQL_USER}
PMA_PASSWORD: ${MYSQL_PASSWORD}
PMA_ARBITRARY: 1
ports:
- ${PHPMYADMIN_PORT}
depends_on:
- db
labels:
- traefik.enable=true
- traefik.http.routers.${HASH}.rule=Host(`${PHPMYADMIN_HOST}`)
- traefik.http.services.${HASH}.loadbalancer.server.port=${PHPMYADMIN_PORT}
networks:
- dokploy-network
volumes:
db_data:
driver: local
networks:
dokploy-network:
external: true

View File

@@ -1,20 +1,24 @@
import {
type DomainSchema,
type Schema,
type Template,
generateHash,
generatePassword,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const mainDomain = generateRandomDomain(schema);
const rootPassword = generatePassword(32);
const password = generatePassword(32);
const domains: DomainSchema[] = [
{
host: mainDomain,
port: 80,
serviceName: "phpmyadmin",
},
];
const envs = [
`PHPMYADMIN_HOST=${randomDomain}`,
"PHPMYADMIN_PORT=80",
`HASH=${mainServiceHash}`,
`MYSQL_ROOT_PASSWORD=${rootPassword}`,
"MYSQL_DATABASE=mysql",
"MYSQL_USER=phpmyadmin",
@@ -23,5 +27,6 @@ export function generate(schema: Schema): Template {
return {
envs,
domains,
};
}

View File

@@ -32,17 +32,9 @@ services:
depends_on:
- plausible_db
- plausible_events_db
ports:
- ${PLAUSIBLE_PORT}
networks:
- dokploy-network
env_file:
- .env
labels:
- "traefik.enable=true"
- "traefik.http.routers.${HASH}.rule=Host(`${PLAUSIBLE_HOST}`)"
- "traefik.http.services.${HASH}.loadbalancer.server.port=${PLAUSIBLE_PORT}"
volumes:
db-data:
driver: local
@@ -50,7 +42,3 @@ volumes:
driver: local
event-logs:
driver: local
networks:
dokploy-network:
external: true

View File

@@ -1,24 +1,28 @@
import {
type DomainSchema,
type Schema,
type Template,
generateBase64,
generateHash,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const mainDomain = generateRandomDomain(schema);
const secretBase = generateBase64(64);
const toptKeyBase = generateBase64(32);
const domains: DomainSchema[] = [
{
host: mainDomain,
port: 8000,
serviceName: "plausible",
},
];
const envs = [
`PLAUSIBLE_HOST=${randomDomain}`,
"PLAUSIBLE_PORT=8000",
`BASE_URL=http://${randomDomain}`,
`BASE_URL=http://${mainDomain}`,
`SECRET_KEY_BASE=${secretBase}`,
`TOTP_VAULT_KEY=${toptKeyBase}`,
`HASH=${mainServiceHash}`,
];
const mounts: Template["mounts"] = [
@@ -62,5 +66,6 @@ export function generate(schema: Schema): Template {
return {
envs,
mounts,
domains,
};
}

View File

@@ -3,19 +3,7 @@ services:
pocketbase:
image: spectado/pocketbase:0.22.12
restart: unless-stopped
ports:
- ${POCKETBASE_PORT}
networks:
- dokploy-network
labels:
- traefik.enable=true
- traefik.http.routers.${HASH}.rule=Host(`${POCKETBASE_HOST}`)
- traefik.http.services.${HASH}.loadbalancer.server.port=${POCKETBASE_PORT}
volumes:
- /etc/dokploy/templates/${HASH}/data:/pb_data
- /etc/dokploy/templates/${HASH}/public:/pb_public
- /etc/dokploy/templates/${HASH}/migrations:/pb_migrations
networks:
dokploy-network:
external: true

View File

@@ -1,21 +1,22 @@
import {
type DomainSchema,
type Schema,
type Template,
generateHash,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const mainDomain = generateRandomDomain(schema);
const envs = [
`POCKETBASE_HOST=${randomDomain}`,
"POCKETBASE_PORT=80",
`HASH=${mainServiceHash}`,
const domains: DomainSchema[] = [
{
host: mainDomain,
port: 80,
serviceName: "pocketbase",
},
];
return {
envs,
domains,
};
}

View File

@@ -9,18 +9,10 @@ services:
ROOT_URL: ${ROOT_URL:-http://${ROCKETCHAT_HOST}:${ROCKETCHAT_PORT}}
PORT: ${ROCKETCHAT_PORT}
DEPLOY_METHOD: docker
DEPLOY_PLATFORM:
REG_TOKEN:
DEPLOY_PLATFORM:
REG_TOKEN:
depends_on:
- mongodb
ports:
- ${ROCKETCHAT_PORT}
networks:
- dokploy-network
labels:
- traefik.enable=true
- traefik.http.routers.${HASH}.rule=Host(`${ROCKETCHAT_HOST}`)
- traefik.http.services.${HASH}.loadbalancer.server.port=${ROCKETCHAT_PORT}
mongodb:
image: docker.io/bitnami/mongodb:5.0
@@ -41,8 +33,3 @@ services:
volumes:
mongodb_data: { driver: local }
networks:
dokploy-network:
external: true

View File

@@ -1,21 +1,25 @@
import {
type DomainSchema,
type Schema,
type Template,
generateHash,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const mainDomain = generateRandomDomain(schema);
const envs = [
`ROCKETCHAT_HOST=${randomDomain}`,
"ROCKETCHAT_PORT=3000",
`HASH=${mainServiceHash}`,
const domains: DomainSchema[] = [
{
host: mainDomain,
port: 3000,
serviceName: "rocketchat",
},
];
const envs = [`ROCKETCHAT_HOST=${mainDomain}`, "ROCKETCHAT_PORT=3000"];
return {
envs,
domains,
};
}

View File

@@ -4,8 +4,6 @@ services:
teable:
image: ghcr.io/teableio/teable:1.3.1-alpha-build.460
restart: always
ports:
- ${TEABLE_PORT}
volumes:
- teable-data:/app/.assets
# you may use a bind-mounted host directory instead,
@@ -24,12 +22,6 @@ services:
- BACKEND_MAIL_SENDER_NAME=${BACKEND_MAIL_SENDER_NAME}
- BACKEND_MAIL_AUTH_USER=${BACKEND_MAIL_AUTH_USER}
- BACKEND_MAIL_AUTH_PASS=${BACKEND_MAIL_AUTH_PASS}
networks:
- dokploy-network
labels:
- "traefik.enable=true"
- "traefik.http.routers.${HASH}.rule=Host(`${TEABLE_HOST}`)"
- "traefik.http.services.${HASH}.loadbalancer.server.port=${TEABLE_PORT}"
depends_on:
teable-db-migrate:
condition: service_completed_successfully
@@ -72,10 +64,6 @@ services:
teable-db:
condition: service_healthy
networks:
dokploy-network:
external: true
volumes:
teable-data: {}
teable-db: {}

View File

@@ -1,25 +1,30 @@
import {
type DomainSchema,
type Schema,
type Template,
generateHash,
generatePassword,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const password = generatePassword();
const randomDomain = generateRandomDomain(schema);
const mainDomain = generateRandomDomain(schema);
const publicDbPort = ((min: number, max: number) => {
return Math.round(Math.random() * (max - min) + min);
})(32769, 65534);
const domains: DomainSchema[] = [
{
host: mainDomain,
port: 3000,
serviceName: "teable",
},
];
const envs = [
`TEABLE_HOST=${randomDomain}`,
"TEABLE_PORT=3000",
`TEABLE_HOST=${mainDomain}`,
`TEABLE_DB_PORT=${publicDbPort}`,
`HASH=${mainServiceHash}`,
"TIMEZONE=UTC",
"# Postgres",
"POSTGRES_HOST=teable-db",
@@ -44,5 +49,6 @@ export function generate(schema: Schema): Template {
return {
envs,
domains,
};
}

View File

@@ -10,18 +10,10 @@ services:
depends_on:
db:
condition: service_healthy
ports:
- ${UMAMI_PORT}
networks:
- dokploy-network
environment:
DATABASE_URL: postgresql://umami:umami@db:5432/umami
DATABASE_TYPE: postgresql
APP_SECRET: ${APP_SECRET}
labels:
- "traefik.enable=true"
- "traefik.http.routers.${HASH}.rule=Host(`${UMAMI_HOST}`)"
- "traefik.http.services.${HASH}.loadbalancer.server.port=${UMAMI_PORT}"
db:
image: postgres:15-alpine
restart: always
@@ -39,8 +31,5 @@ services:
POSTGRES_USER: umami
POSTGRES_PASSWORD: umami
networks:
dokploy-network:
external: true
volumes:
db-data:

View File

@@ -1,24 +1,27 @@
import {
type DomainSchema,
type Schema,
type Template,
generateBase64,
generateHash,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const randomSecret = generateBase64();
const envs = [
`UMAMI_HOST=${randomDomain}`,
"UMAMI_PORT=3000",
`APP_SECRET=${randomSecret}`,
`HASH=${mainServiceHash}`,
const domains: DomainSchema[] = [
{
host: randomDomain,
port: 3000,
serviceName: "umami",
},
];
const envs = [`APP_SECRET=${randomSecret}`];
return {
envs,
domains,
};
}

View File

@@ -1,21 +1,10 @@
version: "3.8"
services:
uptime-kuma:
networks:
- dokploy-network
image: louislam/uptime-kuma:1
restart: always
ports:
- ${UPTIME_KUMA_PORT}
volumes:
- uptime-kuma-data:/app/data
labels:
- traefik.enable=true
- traefik.http.routers.${HASH}.rule=Host(`${UPTIME_KUMA_HOST}`)
- traefik.http.services.${HASH}.loadbalancer.server.port=${UPTIME_KUMA_PORT}
volumes:
uptime-kuma-data:
networks:
dokploy-network:
external: true

View File

@@ -1,20 +1,22 @@
import {
type DomainSchema,
type Schema,
type Template,
generateHash,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const envs = [
`UPTIME_KUMA_HOST=${randomDomain}`,
"UPTIME_KUMA_PORT=3001",
`HASH=${mainServiceHash}`,
const domains: DomainSchema[] = [
{
host: randomDomain,
port: 3001,
serviceName: "uptime-kuma",
},
];
return {
envs,
domains,
};
}

View File

@@ -1,6 +1,7 @@
import { randomBytes } from "node:crypto";
import { readFile } from "node:fs/promises";
import { join } from "node:path";
import type { Domain } from "@/server/api/services/domain";
import { TRPCError } from "@trpc/server";
import { templates } from "../templates";
import type { TemplatesKeys } from "../types/templates-data.type";
@@ -10,12 +11,15 @@ export interface Schema {
projectName: string;
}
export type DomainSchema = Pick<Domain, "host" | "port" | "serviceName">;
export interface Template {
envs: string[];
envs?: string[];
mounts?: {
filePath: string;
content?: string;
}[];
domains?: DomainSchema[];
}
export const generateRandomDomain = ({

View File

@@ -1,20 +1,12 @@
version: '3.8'
version: "3.8"
services:
wordpress:
image: wordpress:5.8.3
networks:
- dokploy-network
ports:
- ${WORDPRESS_PORT}
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: exampleuser
WORDPRESS_DB_PASSWORD: examplepass
WORDPRESS_DB_NAME: exampledb
labels:
- "traefik.enable=true"
- "traefik.http.routers.${HASH}.rule=Host(`${WORDPRESS_HOST}`)"
- "traefik.http.services.${HASH}.loadbalancer.server.port=${WORDPRESS_PORT}"
volumes:
- wordpress_data:/var/www/html
@@ -33,7 +25,3 @@ services:
volumes:
wordpress_data:
db_data:
networks:
dokploy-network:
external: true

View File

@@ -1,20 +1,22 @@
import {
type DomainSchema,
type Schema,
type Template,
generateHash,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const envs = [
`WORDPRESS_HOST=${randomDomain}`,
"WORDPRESS_PORT=80",
`HASH=${mainServiceHash}`,
const domains: DomainSchema[] = [
{
host: randomDomain,
port: 80,
serviceName: "wordpress",
},
];
return {
envs,
domains,
};
}