diff --git a/apps/dokploy/public/templates/mailserver.svg b/apps/dokploy/public/templates/mailserver.svg new file mode 100644 index 00000000..7ec0dbb3 --- /dev/null +++ b/apps/dokploy/public/templates/mailserver.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/dokploy/templates/mailserver/docker-compose.yml b/apps/dokploy/templates/mailserver/docker-compose.yml new file mode 100644 index 00000000..8ab044a8 --- /dev/null +++ b/apps/dokploy/templates/mailserver/docker-compose.yml @@ -0,0 +1,54 @@ +services: + mailserver: + image: ghcr.io/docker-mailserver/docker-mailserver:latest + hostname: ${DMS_HOSTNAME} + ports: + - "25:25" # SMTP (STARTTLS) + - "465:465" # SMTP (Implicit TLS) + - "587:587" # SMTP (STARTTLS) + - "143:143" # IMAP (STARTTLS) + - "993:993" # IMAP (Implicit TLS) + volumes: + - dms-mail-data:/var/mail/ + - dms-mail-state:/var/mail-state/ + - dms-mail-logs:/var/log/mail/ + - dms-mail-config:/tmp/docker-mailserver/ + - /etc/dokploy/traefik/dynamic/acme.json:/etc/letsencrypt/acme.json:ro + - /etc/localtime:/etc/localtime:ro + environment: + - ENABLE_FAIL2BAN=${DMS_ENABLE_FAIL2BAN} + - PERMIT_DOCKER=${DMS_PERMIT_DOCKER} + - SPOOF_PROTECTION=${DMS_SPOOF_PROTECTION} + - SSL_TYPE=${DMS_SSL_TYPE} + - SSL_DOMAIN=${DMS_SSL_DOMAIN} + - POSTMASTER_ADDRESS=${DMS_POSTMASTER_ADDRESS} + cap_add: + - NET_ADMIN + restart: always + stop_grace_period: 1m + healthcheck: + test: ${DMS_HEALTHCHECK_CMD} + timeout: ${DMS_HEALTHCHECK_TIMEOUT} + retries: ${DMS_HEALTHCHECK_RETRIES} + command: > + sh -c ' + if [ ! -s /tmp/docker-mailserver/postfix-accounts.cf ]; then + echo "File does not exist or is empty. Running setup command..."; + setup email add "${DMS_DEFAULT_USER}" "${DMS_DEFAULT_USER_PASS}"; + else + echo "File exists and is not empty. Skipping setup command."; + fi + exec supervisord -c /etc/supervisor/supervisord.conf + ' + networks: + - dokploy-network + +networks: + dokploy-network: + external: true + +volumes: + dms-mail-data: + dms-mail-state: + dms-mail-logs: + dms-mail-config: \ No newline at end of file diff --git a/apps/dokploy/templates/mailserver/index.ts b/apps/dokploy/templates/mailserver/index.ts new file mode 100644 index 00000000..6796800e --- /dev/null +++ b/apps/dokploy/templates/mailserver/index.ts @@ -0,0 +1,20 @@ +import type { Schema, Template } from "../utils"; + +export async function generate(schema: Schema): Template { + const envs = [ + "DMS_HOSTNAME=mail.example.com", + "DMS_HEALTHCHECK_CMD='ss --listening --tcp | grep -P 'LISTEN.+:smtp' || exit 1'", + "DMS_HEALTHCHECK_TIMEOUT=3s", + "DMS_HEALTHCHECK_RETRIES=0", + "DMS_POSTMASTER_ADDRESS=postmaster@example.com", + "DMS_DEFAULT_USER=admin@example.com", + "DMS_DEFAULT_USER_PASS=password", + "DMS_ENABLE_FAIL2BAN=1", + "DMS_PERMIT_DOCKER=network", + "DMS_SPOOF_PROTECTION=0", + "DMS_SSL_TYPE=letsencrypt", + "DMS_SSL_DOMAIN=example.com", + ]; + + return { envs }; +} diff --git a/apps/dokploy/templates/templates.ts b/apps/dokploy/templates/templates.ts index 5603b188..05f1ec3c 100644 --- a/apps/dokploy/templates/templates.ts +++ b/apps/dokploy/templates/templates.ts @@ -497,4 +497,18 @@ export const templates: TemplateData[] = [ tags: ["self-hosted", "storage"], load: () => import("./gitea/index").then((m) => m.generate), }, + { + id: "mailserver", + name: "Mailserver", + version: "14.0", + description: "A fullstack but simple mail server with SMTP, IMAP, LDAP, Antispam, Antivirus, etc.", + logo: "mailserver.svg", + links: { + github: "https://github.com/docker-mailserver/docker-mailserver", + website: "https://docker-mailserver.github.io/docker-mailserver/v14.0/", + docs: "https://docker-mailserver.github.io/docker-mailserver/v14.0/config/environment/", + }, + tags: ["self-hosted", "email"], + load: () => import("./mailserver/index").then((m) => m.generate), + }, ];