mesh/merge-gate pass: builds baserow, grafana, mailu, matrix, mongodb, mosquitto, nodered, postgres, redis, step-ca, supabase, website → ace, novox; no bus…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
mesh/delivery-group group feat/health-the-first-declarations delivered: every member is delivered
Seven modules' images ship a check the mesh never read. Adopted by name where it says healthy on the live mesh today: nine of mail's containers (not its antivirus, whose six-minute start is past the five-minute bound, nor its cache, whose image ships none), the certificate authority, the spreadsheet app, four of the database suite's (the studio among them, with the address it binds fixed), the flow editor and the chat client. And the endpoints four services already declare, looked at from the machine: tcp on the database, the cache, the document store and the broker; http on the website and the dashboards. The count of undeclared falls from 93 to 70.
677 lines
19 KiB
JSON
677 lines
19 KiB
JSON
{
|
|
"module": "mailu",
|
|
"version": "1",
|
|
"capabilities": [
|
|
"container-runtime"
|
|
],
|
|
"requires": [
|
|
"postgres-database",
|
|
"route",
|
|
"secret"
|
|
],
|
|
"contributes": {
|
|
"postgres-database": {
|
|
"name": "mailu"
|
|
},
|
|
"route": {
|
|
"web": {
|
|
"label": "mail",
|
|
"endpoint": "web-tls",
|
|
"scheme": "https",
|
|
"insecure": true
|
|
},
|
|
"acme": {
|
|
"label": "mail",
|
|
"path": "/.well-known/acme-challenge",
|
|
"endpoint": "web",
|
|
"priority": 100
|
|
},
|
|
"autoconfig": {
|
|
"label": "autoconfig",
|
|
"endpoint": "autoconfig"
|
|
},
|
|
"autodiscover": {
|
|
"label": "autodiscover",
|
|
"endpoint": "autoconfig"
|
|
},
|
|
"automx": {
|
|
"label": "automx",
|
|
"endpoint": "autoconfig"
|
|
}
|
|
}
|
|
},
|
|
"binds": {
|
|
"postgres-database": "${dir:state}/database.json",
|
|
"route": "${dir:state}/route.json"
|
|
},
|
|
"secrets": {
|
|
"postgres-database": "${dir:state}/database.secret",
|
|
"secret": {
|
|
"secret-key": "${dir:state}/secret-key.secret",
|
|
"admin": "${dir:state}/admin.secret",
|
|
"api-token": "${dir:state}/api-token.secret"
|
|
}
|
|
},
|
|
"emits": [
|
|
"user.created",
|
|
"user.deleted",
|
|
"alias.created",
|
|
"alias.deleted"
|
|
],
|
|
"listens": [
|
|
{
|
|
"name": "smtp",
|
|
"port": 25,
|
|
"protocol": "tcp",
|
|
"from": "anywhere",
|
|
"why": "mail from other mail servers",
|
|
"fixed": true
|
|
},
|
|
{
|
|
"name": "pop3",
|
|
"port": 110,
|
|
"protocol": "tcp",
|
|
"from": "anywhere",
|
|
"why": "POP3, kept at parity with the predecessor; pruning legacy protocols is its own deliberate change",
|
|
"fixed": true
|
|
},
|
|
{
|
|
"name": "imap",
|
|
"port": 143,
|
|
"protocol": "tcp",
|
|
"from": "anywhere",
|
|
"why": "IMAP with STARTTLS, kept at parity",
|
|
"fixed": true
|
|
},
|
|
{
|
|
"name": "smtps",
|
|
"port": 465,
|
|
"protocol": "tcp",
|
|
"from": "anywhere",
|
|
"why": "submission over TLS",
|
|
"fixed": true
|
|
},
|
|
{
|
|
"name": "submission",
|
|
"port": 587,
|
|
"protocol": "tcp",
|
|
"from": "anywhere",
|
|
"why": "submission; also what the smtp provision serves consumers",
|
|
"fixed": true
|
|
},
|
|
{
|
|
"name": "imaps",
|
|
"port": 993,
|
|
"protocol": "tcp",
|
|
"from": "anywhere",
|
|
"why": "IMAP over TLS",
|
|
"fixed": true
|
|
},
|
|
{
|
|
"name": "pop3s",
|
|
"port": 995,
|
|
"protocol": "tcp",
|
|
"from": "anywhere",
|
|
"why": "POP3 over TLS, kept at parity",
|
|
"fixed": true
|
|
},
|
|
{
|
|
"name": "web",
|
|
"port": 7080,
|
|
"protocol": "tcp",
|
|
"from": "mesh",
|
|
"why": "the web front over http; only the ACME HTTP-01 passthrough is routed here — everything else 301s to https and would loop a proxy"
|
|
},
|
|
{
|
|
"name": "web-tls",
|
|
"port": 7443,
|
|
"protocol": "tcp",
|
|
"from": "mesh",
|
|
"why": "the web front over its own TLS (admin, webmail, API); its public name is a route grant reaching it here"
|
|
},
|
|
{
|
|
"name": "autoconfig",
|
|
"port": 4243,
|
|
"protocol": "tcp",
|
|
"from": "mesh",
|
|
"why": "automx: mail client autoconfiguration; the autoconfig, autodiscover and automx names are route grants reaching it here"
|
|
},
|
|
{
|
|
"name": "admin-api",
|
|
"port": 8080,
|
|
"protocol": "tcp",
|
|
"from": "machine",
|
|
"why": "the admin API, which this module's own code reaches on loopback from the node's runtime now that it runs outside the mailu network"
|
|
}
|
|
],
|
|
"data": {
|
|
"own": [
|
|
{
|
|
"id": "mail",
|
|
"path": "${dir:data-mail}",
|
|
"class": "valuable",
|
|
"why": "every mailbox"
|
|
},
|
|
{
|
|
"id": "dkim",
|
|
"path": "${dir:data-dkim}",
|
|
"class": "valuable",
|
|
"why": "the domain's signing keys; a new one means a new DNS record"
|
|
},
|
|
{
|
|
"id": "data",
|
|
"path": "${dir:data-data}",
|
|
"class": "valuable",
|
|
"why": "the server's own data"
|
|
},
|
|
{
|
|
"id": "dav",
|
|
"path": "${dir:data-dav}",
|
|
"class": "valuable",
|
|
"why": "calendars and contacts"
|
|
},
|
|
{
|
|
"id": "webmail",
|
|
"path": "${dir:data-webmail}",
|
|
"class": "valuable",
|
|
"why": "the webmail's own data: its users' settings and address books"
|
|
},
|
|
{
|
|
"id": "queue",
|
|
"path": "${dir:data-mailqueue}",
|
|
"class": "valuable",
|
|
"why": "mail accepted and not yet delivered, kept nowhere else"
|
|
},
|
|
{
|
|
"id": "filter",
|
|
"path": "${dir:data-filter}",
|
|
"class": "rebuildable",
|
|
"why": "the spam filter's learned statistics; it learns again"
|
|
},
|
|
{
|
|
"id": "certs",
|
|
"path": "${dir:data-certs}",
|
|
"class": "rebuildable",
|
|
"why": "certificates, issued again"
|
|
},
|
|
{
|
|
"id": "automx",
|
|
"path": "${dir:data-automx}",
|
|
"class": "rebuildable",
|
|
"why": "client autoconfiguration, written again"
|
|
},
|
|
{
|
|
"id": "fetchmail",
|
|
"path": "${dir:data-fetchmail}",
|
|
"class": "rebuildable",
|
|
"why": "which remote messages were fetched; lost, some are fetched twice"
|
|
},
|
|
{
|
|
"id": "clamav",
|
|
"path": "${dir:data-clamav}",
|
|
"class": "cache",
|
|
"why": "virus signatures, downloaded again"
|
|
},
|
|
{
|
|
"id": "redis",
|
|
"path": "${dir:data-redis}",
|
|
"class": "cache",
|
|
"why": "the filter's working set"
|
|
}
|
|
],
|
|
"consumers": {
|
|
"smtp": {
|
|
"class": "valuable",
|
|
"in": "mail",
|
|
"why": "a consumer's mailbox holds the only copy of its mail"
|
|
}
|
|
}
|
|
},
|
|
"resources": [
|
|
{
|
|
"id": "mesh-state",
|
|
"type": "directory",
|
|
"mode": "0700",
|
|
"place": "mesh"
|
|
},
|
|
{
|
|
"id": "state",
|
|
"type": "directory",
|
|
"mode": "0700",
|
|
"place": "."
|
|
},
|
|
{
|
|
"id": "grants",
|
|
"type": "directory",
|
|
"mode": "0700"
|
|
},
|
|
{
|
|
"id": "data-automx",
|
|
"type": "directory",
|
|
"mode": "0700"
|
|
},
|
|
{
|
|
"id": "config-env",
|
|
"type": "file",
|
|
"path": "${dir:state}/mailu.env",
|
|
"mode": "0644",
|
|
"content": "ADMIN_ADDRESS=mailu-admin\nANTISPAM_ADDRESS=mailu-antispam\nANTIVIRUS_ADDRESS=mailu-antivirus\nIMAP_ADDRESS=mailu-imap\nSMTP_ADDRESS=mailu-smtp\nFRONT_ADDRESS=mailu-front\nWEBMAIL_ADDRESS=mailu-webmail\nWEBDAV_ADDRESS=mailu-webdav\nREDIS_ADDRESS=mailu-redis\nPORTS=25,80,443,465,993,995,4190,110,143,587\nDOMAIN=${setting:domain}\nHOSTNAMES=${bound:route:name-web}\nPOSTMASTER=admin\nSITENAME=${setting:sitename}\nWEBSITE=${setting:website}\nTLS_FLAVOR=letsencrypt\nSUBNET=192.168.203.0/24\nCOMPOSE_PROJECT_NAME=mailu\nANTIVIRUS=clamav\nWEBMAIL=roundcube\nWEBDAV=radicale\nFETCHMAIL_ENABLED=True\nFETCHMAIL_DELAY=600\nADMIN=true\nWEB_ADMIN=/admin\nWEB_WEBMAIL=/webmail\nWEBROOT_REDIRECT=/webmail\nAPI=true\nWEB_API=/api\nAUTH_RATELIMIT_IP=6000/hour\nAUTH_RATELIMIT_USER=1000/day\nCREDENTIAL_ROUNDS=12\nPASSWORD_SCHEME=PBKDF2\nDISABLE_STATISTICS=True\nMESSAGE_SIZE_LIMIT=50000000\nMESSAGE_RATELIMIT=200/day\nRECIPIENT_DELIMITER=+\nPOSTFIX_MYNETWORKS=127.0.0.0/8 [::1]/128\nRELAYNETS=\nRELAYHOST=\nREJECT_UNLISTED_RECIPIENT=\nDB_FLAVOR=postgresql\nINITIAL_ADMIN_ACCOUNT=admin\nINITIAL_ADMIN_DOMAIN=${setting:domain}\nINITIAL_ADMIN_MODE=ifmissing\nSMTP_PORT=25\nSMTPS_PORT=465\nSUBMISSION_PORT=587\nPOP3_PORT=110\nPOP3S_PORT=995\nIMAP_PORT=143\nIMAPS_PORT=993\nHTTP_PORT=7080\nHTTPS_PORT=7443\nAUTOMX_PORT=4243\nAMX_SMTP_ADDRESS=${bound:route:name-web}\nAMX_SMTP_PORT=587\nAMX_IMAP_ADDRESS=${bound:route:name-web}\nAMX_IMAP_PORT=143\nAMX_MAIL_DOMAINS=${setting:domain}\nDMARC_RUA=admin\nDMARC_RUF=admin\nLETSENCRYPT_SHORTCHAIN=True\nTZ=Etc/UTC\nLOG_LEVEL=INFO\nWELCOME=false\nREAL_IP_HEADER=X-Real-IP\nREAL_IP_FROM=${setting:proxy-address}\nCOMPRESSION=\nCOMPRESS_LEVEL=\nCOMPRESSION_LEVEL=\nBIND_ADDRESS4=127.0.0.1\nBIND_ADDRESS6=::1\nMAILU_VERSION=1.9\nDOCKER_ORG=mailu\nDOCKER_PREFIX=\nWELCOME_SUBJECT=Welcome to your new email account\nWELCOME_BODY=Welcome to your new email account, if you can read this, then it is configured properly!\n"
|
|
},
|
|
{
|
|
"id": "secret-env",
|
|
"type": "file",
|
|
"path": "${dir:state}/secret.env",
|
|
"mode": "0600",
|
|
"content": "SECRET_KEY=${secret:secret-key}\n"
|
|
},
|
|
{
|
|
"id": "database-env",
|
|
"type": "file",
|
|
"path": "${dir:state}/database.env",
|
|
"mode": "0600",
|
|
"content": "DB_FLAVOR=postgresql\nDB_HOST=${bound:postgres-database:at}:${bound:postgres-database:port}\nDB_USER=${bound:postgres-database:as}\nDB_NAME=${bound:postgres-database:as}\nDB_PW=${secret:postgres-database}\n"
|
|
},
|
|
{
|
|
"id": "admin-env",
|
|
"type": "file",
|
|
"path": "${dir:state}/admin.env",
|
|
"mode": "0600",
|
|
"content": "INITIAL_ADMIN_PW=${secret:admin}\nAPI_TOKEN=${secret:api-token}\n"
|
|
},
|
|
{
|
|
"id": "data-certs",
|
|
"type": "directory",
|
|
"mode": "0700"
|
|
},
|
|
{
|
|
"id": "data-data",
|
|
"type": "directory",
|
|
"mode": "0700"
|
|
},
|
|
{
|
|
"id": "data-dkim",
|
|
"type": "directory",
|
|
"mode": "0700"
|
|
},
|
|
{
|
|
"id": "data-mail",
|
|
"type": "directory",
|
|
"mode": "0700"
|
|
},
|
|
{
|
|
"id": "data-mailqueue",
|
|
"type": "directory",
|
|
"mode": "0755"
|
|
},
|
|
{
|
|
"id": "data-filter",
|
|
"type": "directory",
|
|
"mode": "0700"
|
|
},
|
|
{
|
|
"id": "data-clamav",
|
|
"type": "directory",
|
|
"mode": "0700"
|
|
},
|
|
{
|
|
"id": "data-redis",
|
|
"type": "directory",
|
|
"mode": "0700"
|
|
},
|
|
{
|
|
"id": "data-webmail",
|
|
"type": "directory",
|
|
"mode": "0700"
|
|
},
|
|
{
|
|
"id": "data-dav",
|
|
"type": "directory",
|
|
"mode": "0700"
|
|
},
|
|
{
|
|
"id": "data-fetchmail",
|
|
"type": "directory",
|
|
"mode": "0700"
|
|
},
|
|
{
|
|
"id": "data-overrides-nginx",
|
|
"type": "directory",
|
|
"mode": "0700"
|
|
},
|
|
{
|
|
"id": "data-overrides-dovecot",
|
|
"type": "directory",
|
|
"mode": "0700"
|
|
},
|
|
{
|
|
"id": "data-overrides-postfix",
|
|
"type": "directory",
|
|
"mode": "0700"
|
|
},
|
|
{
|
|
"id": "data-overrides-rspamd",
|
|
"type": "directory",
|
|
"mode": "0700"
|
|
},
|
|
{
|
|
"id": "data-overrides-roundcube",
|
|
"type": "directory",
|
|
"mode": "0700"
|
|
},
|
|
{
|
|
"id": "net",
|
|
"type": "network",
|
|
"name": "mailu"
|
|
},
|
|
{
|
|
"id": "resolver",
|
|
"type": "container",
|
|
"name": "mailu-resolver",
|
|
"image": "ghcr.io/mailu/unbound@sha256:3a0fdfb364a63f4f9259526e013c1ef40f5f14de3621ce1560804b3a5909584a",
|
|
"health": {
|
|
"kind": "runtime"
|
|
},
|
|
"network": "mailu",
|
|
"env-file": [
|
|
"${dir:state}/mailu.env",
|
|
"${dir:state}/secret.env"
|
|
],
|
|
"secrets-in-environment": "mailu-admin honours SECRET_KEY_FILE, DB_PW_FILE and API_TOKEN_FILE (configuration.py) but INITIAL_ADMIN_PW is env-only (start.py); the remaining containers' need for SECRET_KEY is unverified",
|
|
"ip": "192.168.203.254"
|
|
},
|
|
{
|
|
"id": "redis",
|
|
"type": "container",
|
|
"name": "mailu-redis",
|
|
"image": "redis@sha256:4bed291aa5efb9f0d77b76ff7d4ab71eee410962965d052552db1fb80576431d",
|
|
"network": "mailu",
|
|
"volumes": [
|
|
"${dir:data-redis}:/data"
|
|
]
|
|
},
|
|
{
|
|
"id": "admin",
|
|
"type": "container",
|
|
"name": "mailu-admin",
|
|
"image": "ghcr.io/mailu/admin@sha256:6dbfdadc4a9590dcb7652357b505200115b689b74008653bbf369e4599a3be5a",
|
|
"health": {
|
|
"kind": "runtime"
|
|
},
|
|
"network": "mailu",
|
|
"ports": [
|
|
"8080"
|
|
],
|
|
"env-file": [
|
|
"${dir:state}/mailu.env",
|
|
"${dir:state}/secret.env",
|
|
"${dir:state}/database.env",
|
|
"${dir:state}/admin.env"
|
|
],
|
|
"volumes": [
|
|
"${dir:data-data}:/data",
|
|
"${dir:data-dkim}:/dkim"
|
|
],
|
|
"secrets-in-environment": "mailu-admin honours SECRET_KEY_FILE, DB_PW_FILE and API_TOKEN_FILE (configuration.py) but INITIAL_ADMIN_PW is env-only (start.py); the remaining containers' need for SECRET_KEY is unverified"
|
|
},
|
|
{
|
|
"id": "imap",
|
|
"type": "container",
|
|
"name": "mailu-imap",
|
|
"image": "ghcr.io/mailu/dovecot@sha256:7f0ed5db996fbdc00adc5c5e38a08492e04f7eb4a9fbd66a03aa9a28ddf23993",
|
|
"health": {
|
|
"kind": "runtime"
|
|
},
|
|
"network": "mailu",
|
|
"env-file": [
|
|
"${dir:state}/mailu.env"
|
|
],
|
|
"volumes": [
|
|
"${dir:data-mail}:/mail",
|
|
"${dir:data-overrides-dovecot}:/overrides:ro"
|
|
],
|
|
"dns": [
|
|
"192.168.203.254"
|
|
]
|
|
},
|
|
{
|
|
"id": "smtp",
|
|
"type": "container",
|
|
"name": "mailu-smtp",
|
|
"image": "ghcr.io/mailu/postfix@sha256:e2e49f39e53b80eac9e7a2f18d9df11edeb4914fd62dbba89b3155e8e034f62e",
|
|
"health": {
|
|
"kind": "runtime"
|
|
},
|
|
"network": "mailu",
|
|
"env-file": [
|
|
"${dir:state}/mailu.env"
|
|
],
|
|
"volumes": [
|
|
"${dir:data-mailqueue}:/queue",
|
|
"${dir:data-overrides-postfix}:/overrides:ro"
|
|
],
|
|
"dns": [
|
|
"192.168.203.254"
|
|
]
|
|
},
|
|
{
|
|
"id": "antispam",
|
|
"type": "container",
|
|
"name": "mailu-antispam",
|
|
"image": "ghcr.io/mailu/rspamd@sha256:ff3666d8a61f17d309c5c6f6bcf4d40470b82299ca706ac650301175bb1a079d",
|
|
"health": {
|
|
"kind": "runtime"
|
|
},
|
|
"network": "mailu",
|
|
"env-file": [
|
|
"${dir:state}/mailu.env"
|
|
],
|
|
"volumes": [
|
|
"${dir:data-filter}:/var/lib/rspamd",
|
|
"${dir:data-overrides-rspamd}:/etc/rspamd/override.d:ro"
|
|
],
|
|
"dns": [
|
|
"192.168.203.254"
|
|
]
|
|
},
|
|
{
|
|
"id": "antivirus",
|
|
"type": "container",
|
|
"name": "mailu-antivirus",
|
|
"image": "clamav/clamav-debian@sha256:b12ef8fefddbba7d88de59bea8a32622f365339154adf02d38fd089112e6745a",
|
|
"network": "mailu",
|
|
"volumes": [
|
|
"${dir:data-clamav}:/var/lib/clamav"
|
|
],
|
|
"dns": [
|
|
"192.168.203.254"
|
|
]
|
|
},
|
|
{
|
|
"id": "webmail",
|
|
"type": "container",
|
|
"name": "mailu-webmail",
|
|
"image": "ghcr.io/mailu/webmail@sha256:bdbee44cdb05a4658f0e3b62cc448de55ca8f8aea172279fda594826144c04f6",
|
|
"health": {
|
|
"kind": "runtime"
|
|
},
|
|
"network": "mailu",
|
|
"env-file": [
|
|
"${dir:state}/mailu.env",
|
|
"${dir:state}/secret.env"
|
|
],
|
|
"volumes": [
|
|
"${dir:data-webmail}:/data",
|
|
"${dir:data-overrides-roundcube}:/overrides:ro"
|
|
],
|
|
"secrets-in-environment": "mailu-admin honours SECRET_KEY_FILE, DB_PW_FILE and API_TOKEN_FILE (configuration.py) but INITIAL_ADMIN_PW is env-only (start.py); the remaining containers' need for SECRET_KEY is unverified",
|
|
"dns": [
|
|
"192.168.203.254"
|
|
]
|
|
},
|
|
{
|
|
"id": "webdav",
|
|
"type": "container",
|
|
"name": "mailu-webdav",
|
|
"image": "ghcr.io/mailu/radicale@sha256:690ed6edf189dfef100a5a8b37c195ebf5d9241ac5f23f2f44b8b7b75726e3de",
|
|
"health": {
|
|
"kind": "runtime"
|
|
},
|
|
"network": "mailu",
|
|
"env-file": [
|
|
"${dir:state}/mailu.env",
|
|
"${dir:state}/secret.env"
|
|
],
|
|
"volumes": [
|
|
"${dir:data-dav}:/data"
|
|
],
|
|
"secrets-in-environment": "mailu-admin honours SECRET_KEY_FILE, DB_PW_FILE and API_TOKEN_FILE (configuration.py) but INITIAL_ADMIN_PW is env-only (start.py); the remaining containers' need for SECRET_KEY is unverified",
|
|
"dns": [
|
|
"192.168.203.254"
|
|
]
|
|
},
|
|
{
|
|
"id": "fetchmail",
|
|
"type": "container",
|
|
"name": "mailu-fetchmail",
|
|
"image": "ghcr.io/mailu/fetchmail@sha256:f881c8412d3bbe73d638469b48321558d6403a9d45bfa043c1e52c752103d42d",
|
|
"health": {
|
|
"kind": "runtime"
|
|
},
|
|
"network": "mailu",
|
|
"env-file": [
|
|
"${dir:state}/mailu.env",
|
|
"${dir:state}/secret.env"
|
|
],
|
|
"volumes": [
|
|
"${dir:data-fetchmail}:/data"
|
|
],
|
|
"secrets-in-environment": "mailu-admin honours SECRET_KEY_FILE, DB_PW_FILE and API_TOKEN_FILE (configuration.py) but INITIAL_ADMIN_PW is env-only (start.py); the remaining containers' need for SECRET_KEY is unverified",
|
|
"dns": [
|
|
"192.168.203.254"
|
|
]
|
|
},
|
|
{
|
|
"id": "front",
|
|
"type": "container",
|
|
"name": "mailu-front",
|
|
"image": "ghcr.io/mailu/nginx@sha256:36f98897cd1bc9d27628bbb4e04bdf60147af2ec7507d6da77f002c4f256896d",
|
|
"health": {
|
|
"kind": "runtime"
|
|
},
|
|
"network": "mailu",
|
|
"env-file": [
|
|
"${dir:state}/mailu.env"
|
|
],
|
|
"ports": [
|
|
"25",
|
|
"110",
|
|
"143",
|
|
"465",
|
|
"587",
|
|
"993",
|
|
"995",
|
|
"7080:80",
|
|
"7443:443"
|
|
],
|
|
"volumes": [
|
|
"${dir:data-certs}:/certs",
|
|
"${dir:data-overrides-nginx}:/overrides:ro"
|
|
],
|
|
"dns": [
|
|
"192.168.203.254"
|
|
],
|
|
"logging": "journald"
|
|
},
|
|
{
|
|
"id": "runtime-config",
|
|
"type": "file",
|
|
"path": "${dir:mesh-state}/config.json",
|
|
"mode": "0600",
|
|
"content": "{}\n",
|
|
"merge": "json"
|
|
},
|
|
{
|
|
"id": "automx",
|
|
"type": "container",
|
|
"name": "mailu-automx",
|
|
"artifact": "automx",
|
|
"network": "mailu",
|
|
"env-file": [
|
|
"${dir:state}/mailu.env"
|
|
],
|
|
"ports": [
|
|
"4243"
|
|
],
|
|
"volumes": [
|
|
"${dir:data-automx}:/data"
|
|
]
|
|
}
|
|
],
|
|
"build": {
|
|
"on": [
|
|
{
|
|
"arg": "PYTHON_BASE",
|
|
"image": "python@sha256:25f3cfeaceca14921366af4d1240b56457ef46273bdb508c7b0e8f469f6fd228"
|
|
}
|
|
],
|
|
"artifacts": [
|
|
{
|
|
"name": "code",
|
|
"kind": "bundle",
|
|
"language": "typescript",
|
|
"entrypoints": [
|
|
"index.js",
|
|
"tools/index.js",
|
|
"provisioner/index.js"
|
|
],
|
|
"loads": [
|
|
"index.js",
|
|
"tools/index.js",
|
|
"provisioner/index.js"
|
|
],
|
|
"env": {
|
|
"MESH_MAILU_URL": "http://127.0.0.1:${port:8080}/api/v1",
|
|
"MESH_MAILU_API_KEY_FILE": "${dir:state}/api-token.secret",
|
|
"MESH_MAILU_IMAP_CONTAINER": "mailu-imap",
|
|
"MESH_MAILU_CONFIG_FILE": "${dir:mesh-state}/config.json",
|
|
"MESH_RECEIVES": "${dir:grants}/mesh.json"
|
|
}
|
|
},
|
|
{
|
|
"name": "automx",
|
|
"kind": "image",
|
|
"from": "automx/Dockerfile"
|
|
}
|
|
]
|
|
},
|
|
"provides": [
|
|
{
|
|
"name": "smtp",
|
|
"scope": "mesh",
|
|
"identity": {
|
|
"max": 64,
|
|
"in": "a mailbox's local part"
|
|
}
|
|
}
|
|
],
|
|
"serves": {
|
|
"smtp": {
|
|
"port": 587,
|
|
"domain": "${setting:domain}"
|
|
}
|
|
},
|
|
"receives": {
|
|
"smtp": "${dir:grants}/mesh.json"
|
|
},
|
|
"grants": {
|
|
"smtp": "${dir:grants}"
|
|
},
|
|
"jails": [
|
|
{
|
|
"name": "mailu-front",
|
|
"failregex": "^.*(?:imap|pop3|submission|managesieve)-login: .*\\(auth failed, \\d+ attempts(?: in \\d+ secs)?\\):.*rip=<HOST>(?:,|$)",
|
|
"jail": "backend = systemd\njournalmatch = CONTAINER_NAME=mailu-front\nport = smtp,submission,submissions,imap,imaps,pop3,pop3s\nmaxretry = 3\nfindtime = 1d\nbantime = 1d"
|
|
}
|
|
]
|
|
}
|