nomad/jobs/services/mail/mailserver.hcl
2024-10-14 20:21:58 +01:00

236 lines
7.3 KiB
HCL

job "mailserver" {
datacenters = ["aperture"]
type = "service"
meta {
tld = "rb.dcu.ie"
domain = "mail.rb.dcu.ie"
}
group "mail" {
network {
# mode = "bridge"
port "http" {
to = 80
}
port "smtp" {
to = 25
}
port "submissions" {
to = 465
}
port "submission" {
to = 587
}
port "imap" {
to = 143
}
port "imaps" {
to = 993
}
port "pop3" {
to = 110
}
port "pop3s" {
to = 995
}
port "managesieve" {
to = 4190
}
}
task "whoami" {
driver = "docker"
config {
image = "traefik/whoami"
ports = ["http"]
}
service {
name = "whoami"
port = "http"
check {
type = "http"
path = "/"
interval = "10s"
timeout = "2s"
}
tags = [
"traefik.enable=true",
"traefik.port=${NOMAD_PORT_http}",
"traefik.http.routers.mail-http.rule=Host(`${NOMAD_META_domain}`)",
"traefik.http.routers.mail-http.entrypoints=web,websecure",
"traefik.http.routers.mail-http.tls.certresolver=lets-encrypt",
]
}
}
service {
name = "mail"
# port = "http"
tags = [
"traefik.enable=true",
# Explicit TLS (STARTTLS):
# SMTP
"traefik.tcp.routers.mail-smtp.rule=HostSNI(`*`)",
"traefik.tcp.routers.mail-smtp.entrypoints=smtp",
"traefik.tcp.routers.mail-smtp.service=mail-smtp",
"traefik.tcp.services.mail-smtp.loadbalancer.server.port=${NOMAD_HOST_PORT_smtp}",
"traefik.tcp.services.mail-smtp.loadbalancer.proxyProtocol.version=2",
# SMTP Submission
"traefik.tcp.routers.mail-submission.rule=HostSNI(`*`)",
"traefik.tcp.routers.mail-submission.entrypoints=submission",
"traefik.tcp.routers.mail-submission.service=mail-submission",
"traefik.tcp.services.mail-submission.loadbalancer.server.port=${NOMAD_HOST_PORT_submission}",
"traefik.tcp.services.mail-submission.loadbalancer.proxyProtocol.version=2",
# IMAP
"traefik.tcp.routers.mail-imap.rule=HostSNI(`*`)",
"traefik.tcp.routers.mail-imap.entrypoints=imap",
"traefik.tcp.routers.mail-imap.service=mail-imap",
"traefik.tcp.services.mail-imap.loadbalancer.server.port=${NOMAD_HOST_PORT_imap}",
"traefik.tcp.services.mail-imap.loadbalancer.proxyProtocol.version=2",
# POP3
"traefik.tcp.routers.mail-pop3.rule=HostSNI(`*`)",
"traefik.tcp.routers.mail-pop3.entrypoints=pop3",
"traefik.tcp.routers.mail-pop3.service=mail-pop3",
"traefik.tcp.services.mail-pop3.loadbalancer.server.port=${NOMAD_HOST_PORT_pop3}",
"traefik.tcp.services.mail-pop3.loadbalancer.proxyProtocol.version=2",
# ManageSieve
"traefik.tcp.routers.mail-managesieve.rule=HostSNI(`*`)",
"traefik.tcp.routers.mail-managesieve.entrypoints=managesieve",
"traefik.tcp.routers.mail-managesieve.service=mail-managesieve",
"traefik.tcp.services.mail-managesieve.loadbalancer.server.port=${NOMAD_HOST_PORT_managesieve}",
"traefik.tcp.services.mail-managesieve.loadbalancer.proxyProtocol.version=2",
# Implicit TLS is no different, except for optional HostSNI support:
# SMTP Submission Secure
# "traefik.tcp.routers.mail-submissions.rule=HostSNI(`*`)",
"traefik.tcp.routers.mail-submissions.entrypoints=submissions",
"traefik.tcp.routers.mail-submissions.service=mail-submissions",
"traefik.tcp.services.mail-submissions.loadbalancer.server.port=${NOMAD_HOST_PORT_submissions}",
"traefik.tcp.services.mail-submissions.loadbalancer.proxyProtocol.version=2",
# NOTE: Optionally match by SNI rule, this requires TLS passthrough (not compatible with STARTTLS):
"traefik.tcp.routers.mail-submissions.rule=HostSNI(`${NOMAD_META_domain}`)",
"traefik.tcp.routers.mail-submissions.tls.passthrough=true",
# IMAP Secure
# "traefik.tcp.routers.mail-imaps.rule=HostSNI(`*`)",
"traefik.tcp.routers.mail-imaps.entrypoints=imaps",
"traefik.tcp.routers.mail-imaps.service=mail-imaps",
"traefik.tcp.services.mail-imaps.loadbalancer.server.port=${NOMAD_HOST_PORT_imaps}",
"traefik.tcp.services.mail-imaps.loadbalancer.proxyProtocol.version=2",
# NOTE: Optionally match by SNI rule, this requires TLS passthrough (not compatible with STARTTLS):
"traefik.tcp.routers.mail-imaps.rule=HostSNI(`${NOMAD_META_domain}`)",
"traefik.tcp.routers.mail-imaps.tls.passthrough=true",
# POP3 Secure
# "traefik.tcp.routers.mail-pop3s.rule=HostSNI(`*`)",
"traefik.tcp.routers.mail-pop3s.entrypoints=pop3s",
"traefik.tcp.routers.mail-pop3s.service=mail-pop3s",
"traefik.tcp.services.mail-pop3s.loadbalancer.server.port=${NOMAD_HOST_PORT_pop3s}",
"traefik.tcp.services.mail-pop3s.loadbalancer.proxyProtocol.version=2",
# NOTE: Optionally match by SNI rule, this requires TLS passthrough (not compatible with STARTTLS):
"traefik.tcp.routers.mail-pop3s.rule=HostSNI(`${NOMAD_META_domain}`)",
"traefik.tcp.routers.mail-pop3s.tls.passthrough=true",
]
}
task "mail-server" {
driver = "docker"
config {
image = "ghcr.io/docker-mailserver/docker-mailserver:latest"
ports = ["smtp", "submissions", "submission", "imap", "imaps", "pop3", "pop3s", "managesieve"]
hostname = "${NOMAD_META_domain}"
volumes = [
"/storage/nomad/mail/data/:/var/mail/",
"/storage/nomad/mail/state/:/var/mail-state/",
"/storage/nomad/mail/logs/:/var/log/mail/",
"/storage/nomad/mail/config/:/tmp/docker-mailserver/",
# "local/postfix-virtual.cf:/tmp/docker-mailserver/postfix-virtual.cf",
"local/postfix-master.cf:/tmp/docker-mailserver/postfix-master.cf",
"local/dovecot.cf:/tmp/docker-mailserver/dovecot.cf",
"/etc/localtime:/etc/localtime:ro",
"/oldstorage/home:/home/:ro",
"/storage/nomad/traefik/acme/acme.json:/etc/letsencrypt/acme.json:ro",
]
}
resources {
cpu = 2000
memory = 5000
}
template {
data = file("mailserver.env")
destination = "local/mailserver.env"
env = true
}
template {
data = file("postfix-virtual.cf")
destination = "local/postfix-virtual.cf"
}
template {
data = <<EOF
# Enable proxy protocol support for postfix
smtp/inet/postscreen_upstream_proxy_protocol=haproxy
submission/inet/smtpd_upstream_proxy_protocol=haproxy
submissions/inet/smtpd_upstream_proxy_protocol=haproxy
EOF
destination = "local/postfix-master.cf"
}
template {
data = <<EOF
# Enable proxy protocol support for dovecot
haproxy_trusted_networks = 136.206.16.50
service imap-login {
inet_listener imap {
haproxy = yes
}
inet_listener imaps {
haproxy = yes
}
}
service pop3-login {
inet_listener pop3 {
haproxy = yes
}
inet_listener pop3s {
haproxy = yes
}
}
service managesieve-login {
inet_listener sieve {
haproxy = yes
}
}
EOF
destination = "local/dovecot.cf"
}
}
}
}