Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions common.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ services:
tty: true
volumes:
- filestore:/var/lib/odoo
- mailgate:/opt/odoo/custom/src/odoo/addons/mail/static/scripts:rw,z
labels:
traefik.backend.buffering.retryExpression: IsNetworkError() && Attempts() < 5
traefik.docker.network: "inverseproxy_shared"
Expand Down Expand Up @@ -53,29 +54,34 @@ services:
ENABLE_POLICYD_SPF: 0
ENABLE_SRS: 0
ENABLE_QUOTAS: 0
MAILGATE_SMTP_PORT: "13525"
ODOO_RECEIVING_DOMAINS: manmanufacturing.com
entrypoint:
- bash
- /bin/bash
- -c
- |
cp -r /tmp/docker-mailserver-staging/ /tmp/docker-mailserver
chmod 755 /tmp/docker-mailserver/create-config.sh
/tmp/docker-mailserver/create-config.sh
exec supervisord -c /etc/supervisor/supervisord.conf
set -euo pipefail
mkdir -p /tmp/docker-mailserver
echo "$${MAILBOX_USER}@$${MAILBOX_DOMAIN}|{PLAIN}$${ADMIN_PASSWORD}" \
> /tmp/docker-mailserver/postfix-accounts.cf
exec /usr/bin/dumb-init -- supervisord -c /etc/supervisor/supervisord.conf
volumes:
- ./mail-testing-config/docker-mailserver/:/tmp/docker-mailserver-staging/:ro
- ./odoo/custom/src/odoo/addons/mail/static/scripts/odoo-mailgate.py:/tmp/odoo-mailgate.py:ro
- ./mail-testing-config/docker-mailserver/user-patches.sh:/tmp/docker-mailserver/user-patches.sh:ro
- mailgate:/tmp/mailgate:ro,z

email_client_fake:
image: roundcube/roundcubemail
environment:
ROUNDCUBEMAIL_DB_TYPE: sqlite
ROUNDCUBEMAIL_COMPOSER_PLUGINS: "texxasrulez/persistent_login"
ROUNDCUBEMAIL_PLUGINS: "show_additional_headers,persistent_login,autocreate_identity"
depends_on:
- mailserver
volumes:
- ./mail-testing-config/roundcube/roundcube_user_settings.inc.php:/var/roundcube/config/config.inc.php:ro
- ./mail-testing-config/roundcube/config/roundcube_user_settings.inc.php:/var/roundcube/config/config.inc.php:ro
- ./mail-testing-config/roundcube/plugins/autocreate_identity:/var/www/html/plugins/autocreate_identity
- roundcube:/var/www/html:rw
- roundcube_db:/var/roundcube/db:rw

smtpreal:
image: ghcr.io/docker-mailserver/docker-mailserver:latest
Expand All @@ -87,6 +93,7 @@ services:
- maillogs:/var/log/mail
- maillogssupervisord:/var/log/supervisor
- mailstate:/var/mail-state
- mailgate:/tmp/mailgate:ro,z
cap_add:
- SYS_PTRACE
environment:
Expand Down Expand Up @@ -122,3 +129,6 @@ services:
volumes:
- backup_cache:/root
- filestore:/mnt/backup/src/odoo

volumes:
mailgate:
14 changes: 10 additions & 4 deletions devel.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ services:
default:
environment:
ODOO_DB: *dbname
USER_ID: 2
ODOO_USER_ID: 2
MAILGATE_SMTP_PORT: "13525"
MAILBOX_DOMAIN: *mailserver
MAILBOX_USER: admin
ADMIN_PASSWORD: admin
Expand All @@ -117,9 +118,7 @@ services:
ROUNDCUBEMAIL_USERNAME_DOMAIN: *mailserver
ROUNDCUBEMAIL_DEFAULT_HOST: *mailserver
ROUNDCUBEMAIL_SMTP_SERVER: *mailserver
ROUNDCUBEMAIL_SMTP_PORT: 25
volumes:
- roundcube:/var/www/html:rw
ROUNDCUBEMAIL_SMTP_PORT: 13525

wdb:
image: docker.io/kozea/wdb
Expand Down Expand Up @@ -182,3 +181,10 @@ volumes:
filestore:
db:
roundcube:
roundcube_db:
mailgate:
driver: local
driver_opts:
type: none
o: bind
device: ${PWD}/odoo/custom/src/odoo/addons/mail/static/scripts
46 changes: 27 additions & 19 deletions mail-prod-config/user-patches.sh
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
echo "Applying user patches..."

# This lets postfix know that it is ok to relay these domains. Otherwise
# it would just reject the incoming mail with "Relay access denied".
postconf -e "relay_domains = $ODOO_RECEIVING_DOMAINS"

# Copy the standard smtp service and make a new one on port 12525
PORT=${MAILGATE_SMTP_PORT:-12525}

# This lets postfix know that it is ok to relay these domains. Otherwise
# it would just reject the incoming mail with "Relay access denied".
postconf -e "relay_domains = ${ODOO_RECEIVING_DOMAINS}"

# Define a custom cleanup service that disables SRS (canonical maps)
# If we do not do this SRS rewrites the from emal making a bit of a mess.
# ** Note: This is only set on the smtpd-incoming-odoo service,
# so outgoing will continue to work with SRS. **
postconf -Me "cleanup-odoo/unix=cleanup-odoo unix n - n - 0 cleanup"
postconf -Me "cleanup-odoo-incoming/unix=cleanup-odoo-incoming unix n - n - 0 cleanup"
postconf -Pe \
"cleanup-odoo/unix/sender_canonical_maps=" \
"cleanup-odoo/unix/recipient_canonical_maps="
"cleanup-odoo-incoming/unix/sender_canonical_maps=" \
"cleanup-odoo-incoming/unix/recipient_canonical_maps="

postconf -Me "$PORT/inet=$PORT inet n - n - - smtpd"
postconf -Me "${PORT}/inet=${PORT} inet n - n - - smtpd"
# Add configs to this new smtp service
postconf -Pe \
"$PORT/inet/syslog_name=postfix/smtpd-incoming-odoo" \
"$PORT/inet/cleanup_service_name=cleanup-odoo" \
"$PORT/inet/smtpd_upstream_proxy_protocol=haproxy" \
"$PORT/inet/content_filter=odoo_mailgate:dummy" \
"$PORT/inet/local_recipient_maps=" \
"$PORT/inet/smtpd_recipient_restrictions=permit_mynetworks,permit_auth_destination,reject"
"${PORT}/inet/syslog_name=postfix/smtpd-incoming-odoo" \
"${PORT}/inet/cleanup_service_name=cleanup-odoo-incoming" \
"${PORT}/inet/smtpd_upstream_proxy_protocol=haproxy" \
"${PORT}/inet/content_filter=odoo_mailgate:dummy" \
"${PORT}/inet/local_recipient_maps=" \
"${PORT}/inet/smtpd_recipient_restrictions=permit_mynetworks,permit_auth_destination,reject"

postconf -Me "odoo_mailgate/unix=odoo_mailgate unix - n n - - pipe user=nobody argv=/usr/local/bin/odoo-mailgate-wrapper.py"

Expand All @@ -44,10 +44,10 @@ def log_message(level, message):

try:
# Configuration from environment variables
DB = "$ODOO_DB"
USER = "$ODOO_USER_ID"
PASSWORD = "$ADMIN_PASSWORD"
SECRET = "$HEADER_SECRET"
DB = "${ODOO_DB}"
USER = "${ODOO_USER_ID}"
PASSWORD = "${ADMIN_PASSWORD}"
SECRET = "${HEADER_SECRET}"

if not all([DB, USER, PASSWORD, SECRET]):
log_message("err", "Odoo mailgate: Missing one or more required environment variables.")
Expand Down Expand Up @@ -92,7 +92,15 @@ try:
sys.exit(0)

# Pipe to odoo-mailgate
cmd = ['/usr/bin/python3', '/usr/local/bin/odoo-mailgate.py', '-d', DB, '-u', USER, '-p', PASSWORD, '--host', 'odoo', '--port', '8069']
cmd = [
"/usr/bin/python3",
"/usr/local/bin/odoo-mailgate.py",
"-d", DB,
"-u", USER,
"-p", PASSWORD,
"--host", "odoo",
"--port", "8069",
]
proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, text=False)
try:
proc.stdin.writelines(headers)
Expand Down
33 changes: 0 additions & 33 deletions mail-testing-config/docker-mailserver/create-config.sh

This file was deleted.

4 changes: 0 additions & 4 deletions mail-testing-config/docker-mailserver/postfix-main.cf

This file was deleted.

102 changes: 102 additions & 0 deletions mail-testing-config/docker-mailserver/user-patches.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/bin/bash
echo "Applying user patches..."

MAILBOX_USER=${MAILBOX_USER:-admin}
MAILBOX_DOMAIN=${MAILBOX_DOMAIN:-mailserver}
ADMIN_PASSWORD=${ADMIN_PASSWORD:-admin}
SMTP_SERVICE_NAME=${SMTP_SERVICE_NAME:-smtp}
PORT=${MAILGATE_SMTP_PORT:-13525}
POSTFIX_DIR=/etc/postfix

# Port 25: redirect Mailpit (Odoo outgoing) into the Roundcube mailbox
CLIENT_ACCESS="${POSTFIX_DIR}/odoo-outgoing-client-access.cf"
: > "${CLIENT_ACCESS}"
echo "/${SMTP_SERVICE_NAME}/ REDIRECT ${MAILBOX_USER}@${MAILBOX_DOMAIN}" >> "${CLIENT_ACCESS}"
postconf -e "smtpd_client_restrictions = check_client_access regexp:${CLIENT_ACCESS}"

# Transport: Odoo domains -> mailgate; mailbox -> Dovecot LMTP; else discard
# (Mailpit traffic is redirected to the mailbox before transport lookup.)
TRANSPORT_MAP="${POSTFIX_DIR}/odoo-transport-map.cf"
: > "${TRANSPORT_MAP}"
echo "${MAILBOX_USER}@${MAILBOX_DOMAIN} lmtp:unix:/var/run/dovecot/lmtp" >> "${TRANSPORT_MAP}"
for domain in $(echo "${ODOO_RECEIVING_DOMAINS}" | tr ',' ' '); do
echo "${domain} odoo_mailgate:" >> "${TRANSPORT_MAP}"
done
echo "* discard:" >> "${TRANSPORT_MAP}"
postconf -e "transport_maps = texthash:${TRANSPORT_MAP}"

postconf -e "relay_domains = ${ODOO_RECEIVING_DOMAINS}"

# Port 13525: Incoming to odoo from Roundcube — Odoo domains to mailgate, else to Dovecot
CANONICAL="${POSTFIX_DIR}/odoo-incoming-recipient-canonical.cf"
: > "${CANONICAL}"
# Catch ODOO_RECEIVING_DOMAINS addresses and map them to themselves.
# The rest goes to admin@mailserver
for domain in $(echo "${ODOO_RECEIVING_DOMAINS}" | tr ',' ' '); do
domain_re=$(printf '%s' "${domain}" | sed 's/\./\\./g')
echo "/(.*)@${domain_re}\$/ \$1@${domain}" >> "${CANONICAL}"
done
mailbox_re=$(printf '%s' "${MAILBOX_USER}@${MAILBOX_DOMAIN}" | sed 's/\./\\./g')
echo "/^(${mailbox_re})\$/ \$1" >> "${CANONICAL}"
echo "/.+/ ${MAILBOX_USER}@${MAILBOX_DOMAIN}" >> "${CANONICAL}"

postconf -Me "cleanup-odoo-incoming/unix=cleanup-odoo-incoming unix n - n - 0 cleanup"
postconf -Pe \
"cleanup-odoo-incoming/unix/recipient_canonical_maps=regexp:${CANONICAL}" \
"cleanup-odoo-incoming/unix/recipient_canonical_classes=envelope_recipient"

postconf -Me "${PORT}/inet=${PORT} inet n - n - - smtpd"
# Add configs to this new smtp service
postconf -Pe \
"${PORT}/inet/syslog_name=postfix/smtpd-incoming-odoo" \
"${PORT}/inet/cleanup_service_name=cleanup-odoo-incoming" \
"${PORT}/inet/local_recipient_maps=" \
"${PORT}/inet/smtpd_recipient_restrictions=permit_mynetworks,permit_auth_destination,reject"

postconf -Me "odoo_mailgate/unix=odoo_mailgate unix - n n - - pipe user=nobody argv=/usr/local/bin/odoo-mailgate-wrapper.py"

# Setup Odoo mailgate script
cp /tmp/mailgate/odoo-mailgate.py /usr/local/bin/odoo-mailgate.py
chmod 755 /usr/local/bin/odoo-mailgate.py
cat <<EOF > /usr/local/bin/odoo-mailgate-wrapper.py
#!/usr/bin/env python3
import sys
import subprocess

def log_message(level, message):
"""Logs a message to syslog via the logger command."""
subprocess.run(['logger', '-t', 'odoo-mailgate', '-p', f'mail.{level}'], input=message.encode())

try:
# Configuration from environment variables
DB = "${ODOO_DB}"
USER = "${ODOO_USER_ID}"
PASSWORD = "${ADMIN_PASSWORD}"

if not all([DB, USER, PASSWORD]):
log_message("err", "Odoo mailgate: Missing one or more required environment variables.")
sys.exit(78) # EX_CONFIG

# Pipe to odoo-mailgate
cmd = [
"/usr/bin/python3",
"/usr/local/bin/odoo-mailgate.py",
"-d", DB,
"-u", USER,
"-p", PASSWORD,
"--host", "odoo",
"--port", "8069",
]
return_code = subprocess.run(cmd, stdin=sys.stdin.buffer).returncode

if return_code != 0:
log_message("warn", f"Odoo mailgate script failed with exit code {return_code}.")
sys.exit(return_code)

except Exception as e:
# Fail safe: log the error and exit with a temporary failure code
# so the Mail Transfer Agent retries later.
log_message("err", f"Odoo mailgate wrapper failed with an unexpected error: {e}")
sys.exit(75) # EX_TEMPFAIL
EOF
chmod 755 /usr/local/bin/odoo-mailgate-wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
// Reply above the quote
$config['reply_mode'] = 1;

// Turn off SMTP authentication because we are using port 25
// Turn off SMTP authentication: Roundcube sends on the inbound mailgate
// port (13525), allowed via docker-mailserver mynetworks.
// Unfortunately, we cannot set this via environment variables. See:
// https://github.com/roundcube/roundcubemail-docker/blob/9fd84b3e4f7943c7b2046d0a443a39d1a702edf2/fpm/docker-entrypoint.sh#L177-#L188
$config['smtp_user'] = '';
Expand Down
3 changes: 0 additions & 3 deletions prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ services:
service: odoo
restart: unless-stopped
hostname: "manmanufacturing.com"
volumes:
- mailgate:/opt/odoo/custom/src/odoo/addons/mail/static/scripts:rw,z
env_file:
- .docker/odoo.env
- .docker/db-access.env
Expand Down Expand Up @@ -173,7 +171,6 @@ services:
- .docker/odoo.env
volumes:
- inverseproxy_acme:/etc/letsencrypt:rw,z
- mailgate:/tmp/mailgate:ro,z
- ./mail-prod-config/user-patches.sh:/tmp/docker-mailserver/user-patches.sh
environment:
SSL_TYPE: letsencrypt
Expand Down
Loading