Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| docker_notes:docker-mailserver [2024-01-08 Mon wk02 20:33] – [alias] baumkp | docker_notes:docker-mailserver [2025-08-16 Sat wk33 19:39] (current) – [exim] baumkp | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| {{tag> | {{tag> | ||
| ======Docker mailserver====== | ======Docker mailserver====== | ||
| - | This mailserver setup follows Workaround' | + | This mailserver setup follows Workaround' |
| //As this follows Workaround' | //As this follows Workaround' | ||
| - | <fc # | ||
| - | </ | ||
| - Use of virtual machines is much more common these days than base metal for applications. However Workarounds Debian email server could be loaded on base metal. | - Use of virtual machines is much more common these days than base metal for applications. However Workarounds Debian email server could be loaded on base metal. | ||
| - The database requirements for a small mailserver with a few dozen domains, with each domain having hundreds of emails and aliases is well within the capacity of the sqlite database. The use of a full multi user server / client relational database is not necessary, particularly for a Docker based server implementation. See [[https:// | - The database requirements for a small mailserver with a few dozen domains, with each domain having hundreds of emails and aliases is well within the capacity of the sqlite database. The use of a full multi user server / client relational database is not necessary, particularly for a Docker based server implementation. See [[https:// | ||
| + | |||
| + | <fc # | ||
| + | </fc> | ||
| =====Dockerfile===== | =====Dockerfile===== | ||
| I go annoyed with the messy UID and GID and found this reference to attempt to standardise upon. <fc # | I go annoyed with the messy UID and GID and found this reference to attempt to standardise upon. <fc # | ||
| Line 52: | Line 53: | ||
| ====alias==== | ====alias==== | ||
| I could not get the alias command to work in Alpine shell. | I could not get the alias command to work in Alpine shell. | ||
| - | *create file ++++ll.sh| | + | *create file '' |
| - | < | + | *< |
| exec ls -la " | exec ls -la " | ||
| - | ++++ | + | *chmod |
| + | *Copy the ll.sh file to /bin/ll or link it ''/ | ||
| =====sqlite===== | =====sqlite===== | ||
| Line 221: | Line 223: | ||
| ====ISPmail Admin==== | ====ISPmail Admin==== | ||
| I will setup DNS and Traefik for this to be '' | I will setup DNS and Traefik for this to be '' | ||
| + | Admin user is mailserver with associated password. | ||
| =====adminer===== | =====adminer===== | ||
| **phpMyAdmin** is a web based mysql management interface. | **phpMyAdmin** is a web based mysql management interface. | ||
| Line 248: | Line 251: | ||
| < | < | ||
| mail_version = 3.7.4</ | mail_version = 3.7.4</ | ||
| + | *'' | ||
| + | *'' | ||
| ====Making Postfix get its information from the sqlite database==== | ====Making Postfix get its information from the sqlite database==== | ||
| Line 309: | Line 314: | ||
| *'' | *'' | ||
| *'' | *'' | ||
| - | *'' | + | *'' |
| It looks a shell script is used to control Postfix, in Alpine is is located ++here|/ | It looks a shell script is used to control Postfix, in Alpine is is located ++here|/ | ||
| Line 348: | Line 353: | ||
| Alpine posfix would seem to be setup to use postlogd, as master.cf has the following line already configured: | Alpine posfix would seem to be setup to use postlogd, as master.cf has the following line already configured: | ||
| + | The '' | ||
| + | ====/ | ||
| + | I get an error when recreating the container; " | ||
| ====Postfix References==== | ====Postfix References==== | ||
| *Postfix: | *Postfix: | ||
| Line 363: | Line 371: | ||
| =====dovecot===== | =====dovecot===== | ||
| - | ''/ | + | In Dovecot <2.4.x the main configuration are in files ''/ |
| < | < | ||
| 2.3.20 (80a5ac675d) </ | 2.3.20 (80a5ac675d) </ | ||
| + | *'' | ||
| + | *'' | ||
| + | |||
| + | Alpine Linux version 3.22 from May 2025 used Dovecot 2.4.1 and while I can use an older version of Alpine eventually I would need to upgrade Dovecot to the new configuration file syntax. | ||
| + | ++++Discussion on configuration files| | ||
| + | I suspect the '' | ||
| + | The only other issue is use of override files in '' | ||
| + | ++++ | ||
| + | ====dovecot.conf==== | ||
| + | ++++/ | ||
| + | # Start new configs with the latest Dovecot version numbers here:\\ | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | |||
| + | # | ||
| + | # | ||
| + | [[https:// | ||
| + | |||
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | mail_path = ~/Maildir\\ | ||
| + | |||
| + | mail_plugins {\\ | ||
| + | quota = yes\\ | ||
| + | }\\ | ||
| + | |||
| + | # | ||
| + | # sieve_extprograms = yes\\ | ||
| + | #}\\ | ||
| + | |||
| + | managesieve_notify_capability = mailto\\ | ||
| + | managesieve_sieve_capability = fileinto reject envelope encoded-character vacation subaddress comparator-i; | ||
| + | |||
| + | mbox_write_locks = fcntl\\ | ||
| + | |||
| + | namespace inbox {\\ | ||
| + | inbox = yes\\ | ||
| + | mailbox Drafts {\\ | ||
| + | special_use = \Drafts\\ | ||
| + | }\\ | ||
| + | mailbox Junk {\\ | ||
| + | special_use = \Junk\\ | ||
| + | }\\ | ||
| + | mailbox Sent {\\ | ||
| + | special_use = \Sent\\ | ||
| + | }\\ | ||
| + | mailbox "Sent Messages" | ||
| + | special_use = \Sent\\ | ||
| + | }\\ | ||
| + | mailbox Trash {\\ | ||
| + | special_use = \Trash\\ | ||
| + | }\\ | ||
| + | prefix = \\ | ||
| + | }\\ | ||
| + | |||
| + | quota " | ||
| + | #quota = maildir: | ||
| + | quota_status_nouser = DUNNO\\ | ||
| + | quota_status_overquota = 452 4.2.2 Mailbox is full and cannot receive any more emails\\ | ||
| + | quota_status_success = DUNNO\\ | ||
| + | warning warn-95 {\\ | ||
| + | quota_storage_percentage = 95 \\ | ||
| + | execute quota-warning {\\ | ||
| + | args = 95 %{user}\\ | ||
| + | }\\ | ||
| + | }\\ | ||
| + | warning warn-80 {\\ | ||
| + | quota_storage_percentage = 80\\ | ||
| + | execute quota-warning {\\ | ||
| + | args = 80 %{user}\\ | ||
| + | }\\ | ||
| + | }\\ | ||
| + | }\\ | ||
| + | |||
| + | #sieve = file: | ||
| + | sieve_script_driver = file\\ | ||
| + | sieve_script_active_path = ~/ | ||
| + | sieve_script_type = after \\ | ||
| + | sieve_script_path = / | ||
| + | |||
| + | protocols = imap lmtp\\ | ||
| + | service auth {\\ | ||
| + | unix_listener / | ||
| + | group = postfix\\ | ||
| + | mode = 0660\\ | ||
| + | user = postfix\\ | ||
| + | }\\ | ||
| + | }\\ | ||
| + | service lmtp {\\ | ||
| + | unix_listener / | ||
| + | group = postfix\\ | ||
| + | mode = 0600\\ | ||
| + | user = postfix\\ | ||
| + | }\\ | ||
| + | }\\ | ||
| + | service quota-status {\\ | ||
| + | executable = quota-status -p postfix\\ | ||
| + | unix_listener / | ||
| + | user = postfix\\ | ||
| + | }\\ | ||
| + | }\\ | ||
| + | service quota-warning {\\ | ||
| + | executable = script / | ||
| + | unix_listener quota-warning {\\ | ||
| + | group = vmail\\ | ||
| + | mode = 0660\\ | ||
| + | user = vmail\\ | ||
| + | }\\ | ||
| + | }\\ | ||
| + | ssl = required\\ | ||
| + | ssl_server_cert_file = / | ||
| + | ssl_server_dh_file = / | ||
| + | ssl_server_key_file = / | ||
| + | ssl_server_prefer_ciphers = server\\ | ||
| + | ssl_min_protocol = TLSv1.2\\ | ||
| + | |||
| + | sql_driver = mysql\\ | ||
| + | |||
| + | mysql localhost {\\ | ||
| + | host = mail_db \\ | ||
| + | dbname = mailserver\\ | ||
| + | user = mailserver \\ | ||
| + | password = K6oF4xOZFIo2cYrwTQ03jQWwx7t2my\\ | ||
| + | }\\ | ||
| + | |||
| + | passdb sql {\\ | ||
| + | query = SELECT password FROM virtual_users WHERE email=' | ||
| + | }\\ | ||
| + | |||
| + | userdb sql {\\ | ||
| + | query = SELECT email as user, \ | ||
| + | concat(' | ||
| + | '/ | ||
| + | 5000 AS uid, 5000 AS gid \ | ||
| + | FROM virtual_users WHERE email=' | ||
| + | iterate_query = SELECT email AS user FROM virtual_users\\ | ||
| + | }\\ | ||
| + | |||
| + | protocol lmtp {\\ | ||
| + | mail_plugins = " quota sieve" | ||
| + | }\\ | ||
| + | |||
| + | protocol imap {\\ | ||
| + | mail_plugins = " quota imap_quota" | ||
| + | }\\ | ||
| + | |||
| + | #!include conf.d/ | ||
| + | ++++ | ||
| ====dovecot database configuration and testing==== | ====dovecot database configuration and testing==== | ||
| Line 476: | Line 634: | ||
| ====dovecot testing with mutt==== | ====dovecot testing with mutt==== | ||
| Workaround suggests the following command to be used to test: '' | Workaround suggests the following command to be used to test: '' | ||
| + | |||
| + | ====dovecot ssl_dh==== | ||
| + | |||
| + | I was getting the following error coming up occasionally in my Dovecot log file, "May 25 12:16:05 imap-login: Error: Diffie-Hellman key exchange requested, but no DH parameters provided. Set ssl_dh=</ | ||
| ====dovecot logging==== | ====dovecot logging==== | ||
| + | |||
| + | ====dovecot pigeonhole==== | ||
| + | Pigeonhole is the name of the project that adds support for the [[http:// | ||
| ====Dovecot References==== | ====Dovecot References==== | ||
| *Doc Dovecot: | *Doc Dovecot: | ||
| - | *[[https:// | + | *[[https:// |
| - | *[[https://doc.dovecot.org/ | + | |
| - | *[[https:// | + | |
| - | *[[https://wiki.dovecot.org/ | + | |
| - | *[[https:// | + | |
| - | *[[https://wiki2.dovecot.org/ | + | *[[https://doc.dovecot.org/ |
| - | *[[https:// | + | *[[https:// |
| - | *[[https:// | + | *[[https://doc.dovecot.org/ |
| - | *[[https://wiki.dovecot.org/ | + | *[[https:// |
| - | *[[https:// | + | *[[https:// |
| - | *[[https://wiki1.dovecot.org/ | + | *[[https://doc.dovecot.org/ |
| - | *[[https:// | + | *[[https://doc.dovecot.org/ |
| - | *[[https:// | + | *[[https:// |
| - | *[[https:// | + | *[[https:// |
| - | *Other: | + | *Other: |
| - | *[[http:// | + | *[[http:// |
| - | *[[http:// | + | *[[http:// |
| - | *[[https:// | + | *[[https:// |
| - | | + | ++++ |
| =====Certificates SSL/ | =====Certificates SSL/ | ||
| - | Early on, before 2015 there were not many free SSL certificate providers. I used StartSSL for a free certificate. | + | Early on, before 2015 there were not many free SSL certificate providers. I used StartSSL for a free certificate. |
| =====apache2===== | =====apache2===== | ||
| Alpine apk apache2 distribution seems to follow the Red Hat setup style. The daemon is httpd instead of apache2. | Alpine apk apache2 distribution seems to follow the Red Hat setup style. The daemon is httpd instead of apache2. | ||
| Line 598: | Line 762: | ||
| * https:// | * https:// | ||
| * https:// | * https:// | ||
| + | |||
| + | Places to change php version number: | ||
| + | *In the Docker file us the variable '' | ||
| + | *All the /php82/ paths in the pre_start_script.sh, | ||
| + | *The php-fpm82 reference in '' | ||
| + | *'' | ||
| + | *'' | ||
| + | *'' | ||
| ===Reference=== | ===Reference=== | ||
| Line 754: | Line 926: | ||
| └── www (directory location of Roundcube files, created by Roundcube if empty)</ | └── www (directory location of Roundcube files, created by Roundcube if empty)</ | ||
| ++++ | ++++ | ||
| + | |||
| + | ====Roundcube Docker Plugins==== | ||
| + | See https:// | ||
| + | *'' | ||
| + | *See https:// | ||
| + | *'' | ||
| + | *See https:// | ||
| + | *To use, in Roundcube right click on a mail directory and select '' | ||
| + | *'' | ||
| + | *See https:// | ||
| + | *managesieve - haven' | ||
| Some links: | Some links: | ||
| Line 772: | Line 955: | ||
| *[[https:// | *[[https:// | ||
| *[[https:// | *[[https:// | ||
| + | =====dmarc===== | ||
| + | [[https:// | ||
| + | |||
| + | =====rspamd===== | ||
| + | |||
| + | rspamd -u rspamd -g rspamd | ||
| + | |||
| + | Help from rspamd: ++++rspamd -h| | ||
| + | < | ||
| + | rspamd [OPTION*] - run rspamd daemon | ||
| + | |||
| + | Summary: | ||
| + | Rspamd daemon version 3.7.4 | ||
| + | |||
| + | Help Options: | ||
| + | -h, --help | ||
| + | |||
| + | Application Options: | ||
| + | -f, --no-fork | ||
| + | -c, --config | ||
| + | -u, --user | ||
| + | -g, --group | ||
| + | -p, --pid Path to pidfile | ||
| + | -d, --debug | ||
| + | -i, --insecure | ||
| + | -v, --version | ||
| + | --var | ||
| + | -T, --skip-template | ||
| + | --lua-env | ||
| + | ++++ | ||
| + | |||
| + | [[https:// | ||
| + | |||
| + | =====redis===== | ||
| + | *Load the Alpine package '' | ||
| + | *To start on command line '' | ||
| + | *The redis configuration file ''/ | ||
| + | *The default conf log file is ''/ | ||
| + | *To stop on command line '' | ||
| + | *Redis complains if ' | ||
| + | *This is not set in the container (Docker does have sysctl directive, but not all kernal parameters are support, including this one.) | ||
| + | *This can be set in the host '' | ||
| + | Some reference links: | ||
| + | *Redis | ||
| + | *[[https:// | ||
| + | *[[https:// | ||
| + | *[[https:// | ||
| + | *[[https:// | ||
| + | ====nftables==== | ||
| + | rspamd requires netfilter chains to functions. So a nftables needs to be available and a basic input chain setup to function. | ||
| + | |||
| + | =====Mailserver testing from CLI===== | ||
| + | *'' | ||
| + | *'' | ||
| + | *'' | ||
| + | |||
| + | The mailserver exit control character is ' | ||
| + | The SMTP and mailserver exit control character is ' | ||
| + | |||
| + | |||
| + | =====Errors===== | ||
| + | < | ||
| + | Please check the message recipient " | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | |||
| + | =====Email Clients===== | ||
| + | ====mutt==== | ||
| + | Mutt is a small but very powerful text-based MIME mail client. | ||
| + | *[[http:// | ||
| + | *[[https:// | ||
| + | *[[https:// | ||
| + | |||
| + | ====swaks==== | ||
| + | The swaks command, short for “Swiss Army Knife SMTP,” is an all-purpose SMTP transaction tester. | ||
| + | *[[http:// | ||
| + | *[[https:// | ||
| + | *[[https:// | ||
| + | |||
| + | =====exim===== | ||
| + | After updating my VM from Debian 12 to 13 the mailserver container refused to start as it indicated that port 25 was already in use. | ||
| + | |||
| + | It would seem that Debian 13 automatically installed and starts Exim, some kind of system email client. | ||
| + | |||
| + | The solution was simply to stop and disable Exim from running, '' | ||
| + | |||
| + | The method to find the program using the port was the command '' | ||
| + | |||
| + | |||
| =====References===== | =====References===== | ||
| *Workaround.org [[https:// | *Workaround.org [[https:// | ||