{"id":38261108,"url":"https://github.com/hmlkao/ansible-docker-mailserver","last_synced_at":"2026-01-17T01:36:24.833Z","repository":{"id":43350947,"uuid":"251725105","full_name":"hmlkao/ansible-docker-mailserver","owner":"hmlkao","description":"Ansible role for as simple as possible deploy of docker-mailserver/docker-mailserver.","archived":false,"fork":false,"pushed_at":"2024-06-08T17:39:13.000Z","size":88,"stargazers_count":8,"open_issues_count":6,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-12-23T15:06:38.138Z","etag":null,"topics":["ansible-role","docker","mailer"],"latest_commit_sha":null,"homepage":"","language":"Jinja","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hmlkao.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-03-31T20:35:45.000Z","updated_at":"2025-06-24T16:45:09.000Z","dependencies_parsed_at":"2024-06-08T17:41:05.287Z","dependency_job_id":null,"html_url":"https://github.com/hmlkao/ansible-docker-mailserver","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/hmlkao/ansible-docker-mailserver","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hmlkao%2Fansible-docker-mailserver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hmlkao%2Fansible-docker-mailserver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hmlkao%2Fansible-docker-mailserver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hmlkao%2Fansible-docker-mailserver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hmlkao","download_url":"https://codeload.github.com/hmlkao/ansible-docker-mailserver/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hmlkao%2Fansible-docker-mailserver/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28491617,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T00:50:05.742Z","status":"ssl_error","status_checked_at":"2026-01-17T00:43:11.982Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible-role","docker","mailer"],"created_at":"2026-01-17T01:36:24.712Z","updated_at":"2026-01-17T01:36:24.822Z","avatar_url":"https://github.com/hmlkao.png","language":"Jinja","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ansible Docker mailserver\n\nAnsible role is based on top of project [docker-mailserver/docker-mailserver](https://github.com/docker-mailserver/docker-mailserver).\n\nRole will create all needed prerequisites to run mail server in Docker but doesn't install the Docker itself.\n\nAll data are stored on host to prevent data loss during Docker restart.\n\n## Currently supported\n\n- Account management\n  - [x] Multiple accounts\n  - [ ] Multiple domains\n  - [ ] LDAP\n- Let's Encrypt Key renew automation\n  - [x] Standalone\n  - [ ] [Nginx Proxy](https://docker-mailserver.github.io/docker-mailserver/edge/config/security/ssl/#example-using-nginx-proxy-and-acme-companion-with-docker)\n- Host OS support\n  - [x] Debian based\n  - [ ] Red Hat based\n- Managable features\n  - [ ] ClamAV\n  - [ ] Fail2Ban\n  - [x] OpenDKIM\n  - [x] OpenDMARC\n  - [ ] Postgrey\n  - [ ] Spamassasin\n\n## Test environment\n\n- Ubuntu 18.04 LTS\n\n## Variables\n\n| Variable name         | Default     | Description\n| --------------------- | ----------- | --------------------------------------\n| `mail_accounts`       | `[]`        | List of mail accounts according to [Mail account format](https://github.com/hmlkao/ansible-docker-mailserver#mail-account-format)\n| `mail_domains`        | `[]`        | List of mail domains (the first one should be your MX however certificate will be issued for all of them)\n| `mail_cert_email`     | `\"\"`        | Email used for Let's Encrypt account\n| `mail_persist_folder` | `/opt/mail` | (optional) Persistent folder for mail data, configuration, etc. on host\n| `mail_docker_image`   | `docker.io/mailserver/docker-mailserver` | (optional) Shouldn't be changed\n| `mail_docker_tag`     | `latest`    | (optional) Image Docker tag used to run mail server\n| `mail_dkim_size`      | `2048`      | (optional) DKIM key size (available values are 1024, 2048, 4096)\n| `mail_amavis_config`  | `\"\"`        | (optional) Configure Amavis overrides\n\n## Mail account format\n\nEach account in variable `mail_accounts` has these parameters:\n\n- `username` - part of email before \"@\", eg. `user1`\n- `domain` - part of email after \"@\", eg. `example.com`\n- `password` - user password in plaintext\n- `aliases` - list of aliases, each alias must be full email\n- `restrict` - list of restrictions, may be `send` for suppress mail sending or `receive` for suppress mail receiving\n\n### Example\n\n```yaml\nmail_accounts:\n  - username: user1\n    domain: example.com\n    password: aaaaa\n    aliases:\n      - admin@example.com\n      - abuse@example.com\n    restrict: []\n```\n\n## Quick Start\n\nInstall this Ansible role within the context of playbook\n\n```bash\nansible-galaxy install hmlkao.docker_mailserver\n```\n\nThen create your playbook yaml file\n\n```yaml\n---\n- name: Localhost installation\n  hosts: localhost\n  roles:\n    - role: hmlkao.docker_mailserver\n  vars:\n    mail_accounts:\n      - username: user1\n        domain: example.com\n        password: aaaaa\n        aliases:\n          - admin@example.com\n          - abuse@example.com\n        restrict: []\n      - username: no-reply\n        domain: example.com\n        password: bbbbb\n        aliases: []\n        restrict:\n          - receive\n    mail_domains:\n      - server1.example.com\n    mail_cert_email: my-mail@somewhere.com\n```\n\n## What next?\n\nSuppose that your server host is `server1.example.com`\n\n1. Be sure your public ports are opened\n1. Add MX record to your DNS\n\n    ```txt\n    example.com IN     MX      \"1 server1.example.com.\"\n    ```\n\n1. Add TXT record with SPF to your DNS\n\n    ```txt\n    example.com IN     TXT     \"v=spf1 a mx ~all\"\n    ```\n\n1. Add TXT record with DKIM to your DNS\n    - You can find DKIM key in folder defined by `mail_persist_folder` variable in file `config/opendkim/keys/\u003cdomain.tld\u003e/mail.txt` on your host (server)\n      - Beware of that the record is divided by 250 characters so you have to [concat it together](https://docker-mailserver.github.io/docker-mailserver/edge/config/best-practices/dkim/#configuration-using-a-web-interface)\n    - TXT record should look something like\n\n      ```txt\n      mail._domainkey IN     TXT     \"v=DKIM1; h=sha256; k=rsa; p=MIIB...jwfx\"\n      ```\n\n      - `mail` is DKIM selector, not subdomain so there have to be `mail._domainkey` for all, NO `server1._domainkey` or whatever else\n      - Custom selector [cannot be used](https://github.com/docker-mailserver/docker-mailserver/issues/1304).\n1. Add TXT record with [DMARC](https://dmarc.org/) to your DNS\n    What happen with mails which doesn't meet SPF and DKIM validation.\n\n    ```txt\n    _DMARC IN     TXT     \"v=DMARC1; p=quarantine; pct=100; rua=mailto:abuse+rua@example.com; ruf=mailto:abuse+ruf@example.com; fo=1\"\n    ```\n\n    - `ruf` - Reporting URI for forensic reports\n    - `rua` - Reporting URI of aggregate reports\n    - Verify in commandline if is TXT applied\n\n      ```txt\n      dig mail._domainkey.example.com TXT\n      ```\n\n1. Configure reverse DNS for host public IP\n    - Ask your provider to configure reverse DNS\n    - You should get something similar (where `\u003c1.2.3.4\u003e` is your public server IP)\n\n      ```bash\n      $ dig -x \u003c1.2.3.4\u003e +short\n      server1.example.com.\n      ```\n\n## Test your configuration\n\nThere are many tools to test your mail server, eg.:\n\n- [dkimvalidator.com](https://dkimvalidator.com)\n  - Generate email address which you can use to verify your SPF/DKIM config\n- check-auth@verifier.port25.com\n  - Just send mail to this mail address from your account mail and your will receive report back to your mail address\n- [mxtoolbox.com](https://mxtoolbox.com)\n  - Test your SMTP configuration\n  - Especially [Deliverability test](https://mxtoolbox.com/deliverability) is useful (test SPF and DKIM)\n  - Just send mail to ping@tools.mxtoolbox.com from your account mail and your will receive report back to your mail address\n  - NOTE: MXToolBox DKIM validation fails (eg. [docker-mailserver/docker-mailserver](https://github.com/docker-mailserver/docker-mailserver/issues/1172), [serverfault.com](https://serverfault.com/questions/1005818/dkim-validating-but-mxtoolbox-reports-as-dkim-signature-not-verified) even if another validators works well, don't know why but it looks that Google DKIM validation fails too (just send mail to any Gmail adrress and you will get report to mail according to your [DMARC configuration](https://github.com/hmlkao/ansible-docker-mailserver#what-next))\n- [checktls.com](https://www.checktls.com/TestReceiver)\n  - Test connection to your SMTP port\n  - Fill your `domain.tld` (eg. `example.com`) to the field\n- [Google Postmaster tools](https://toolbox.googleapps.com/apps/checkmx/)\n  - Fill your `domain.tld` (eg. `example.com`) to the domain field\n  - Fill `mail` to DKIM selector field\n  - **Doesn't work for me from unknown reason**\n- [Google Toolbox](https://toolbox.googleapps.com/)\n  - Mail troubleshooting\n- Test via [OpenSSL](https://docker-mailserver.github.io/docker-mailserver/edge/config/security/ssl/#testing-a-certificate-is-valid)\n\n## More complex example\n\n1. Create file `host_vars/server1.example.com.yml` encrypted by [`ansible-vault`](https://docs.ansible.com/ansible/latest/user_guide/vault.html) first.\n\n    ```yaml\n    # ansible-vault edit host_vars/server1.example.com.yml\n    mail_accounts:\n      - username: user1\n        domain: example.com\n        password: aaaaa\n        aliases:\n          - admin@example.com\n          - abuse@example.com\n        restrict: []\n      - username: no-reply\n        domain: example.com\n        password: bbbbb\n        aliases: []\n        restrict:\n          - receive\n    ```\n\n1. Create file `vault-pass.txt` with your Ansible Vault\n   (NOTE: You should add this file to `.gitignore` to prevent leak of sensitive data!)\n\n    ```bash\n    echo 'my-secret-vault-password' \u003e vault-pass.txt\n    ```\n\n1. Set up Ansible with ansible.cfg\n\n    ```bash\n    $ cat \u003e ansible.cfg \u003c\u003cEOF\n    [defaults]\n    vault_password_file = vault-pass.txt\n    EOF\n    ```\n\n1. Variable `mail_accounts` is then available in the role for host `server1.example.com`.\n\n    ```yaml\n    ---\n    - name: More complex installation\n      hosts: server1.example.com\n      roles:\n        - role: hmlkao.docker_mailserver\n      vars:\n        mail_domains:\n          - server1.example.com                 \u003c-- my MX server\n          - mail.example.com                    \u003c-- pretty name for email clients\n        mail_cert_email: my-mail@somewhere.com  \u003c-- notification mail for Let's Encrypt\n    ```\n\n## Client configuration\n\nSuppose your mail server is running on domain `server1.example.com` and we have some pretty CNAME like `mail.example.com` which points to our mail server and account with username `user1` is created.\n\n### Evolution (Default Gnome client)\n\nVersion: 3.28.5-0ubuntu0.18.04.1\n\n1. Edit \u003e Accounts\n1. Add \"Mail Account\"\n1. Identity\n   - Email Address: `user1@example.com`\n1. Receiving Email\n   - Server Type: IMAP\n   - Server: `mail.example.com`\n   - Username: `user1@example.com`\n   - Encryption method: TLS on dedicated port\n     - Port should change to 993\n   - Authentication: Password\n1. Sending Email\n   - Server Type: SMTP\n   - Server: `mail.example.com`\n   - Port: 587\n   - Check \"Server requires authentication\"\n   - Encryption method: STARTTLS after connecting\n   - Authentication:\n     - Type: Login\n     - Username: `user1@example.com`\n\n### Gmail app for Android\n\nVersion: 2020.03.01.300951155.release\n\n1. Add another account\n1. Other\n1. Fill your email \u003e Manual setup\n1. What type of account is this?: Personal (IMAP)\n1. Fill your password \u003e Next\n1. Server: `mail.example.com`\n1. IMAP port: 465 (SSL/TLS)\n1. Outgoing server\n   - Server: `mail.example.com`\n\nYou would be able to receive/send mails now.\n\n### Mail (Default MacOS client)\n\nVersion: 15.0 (3693.40.0.1.81) / 2022-02-14\n\n1. Choose a Mail account provider... \u003e Other Mail Account...\n1. Fill\n    - Name: \u003c your name \u003e\n    - Email address: \u003c the whole email address \u003e\n    - Password: \u003c password to your mail account \u003e\n1. When is error message shown\n    - Choose \"IMAP\"\n    - Fill address of your mail server \u003e according to MX record\n1. Sign in\n\n### Thunderbird (Mozilla client)\n\nTBD\n\n### Mail (Default Windows 10 client)\n\nTBD\n\n## Under the hood\n\n### Ports\n\nThere are published only three ports\n\n- **TCP/25** - SMTP port for receiving emails from other SMTP servers\n- **TCP/587** - SMTP Submission port for sending emails from clients\n- **TCP/993** - IMAP port for downloading emails to clients\n\n### Running server\n\nDocker container named `mail-server` is configured to always restart even after server boot.\n\n### Persistent storage\n\nAll data (mail data, certificates, configuration) are stored on the host in folder defined in Ansible variable `mail_persist_folder`.\n\n### Certificates\n\nTLS certificates are issued by Let's Encrypt issuer by `certbot/certbot` Docker image according to [these instructions](https://docker-mailserver.github.io/docker-mailserver/edge/config/security/ssl/#example-using-docker-for-lets-encrypt).\n\nThis role creates `systemd` renew *service* and *timer* which will run the service once per day. No cronjob configuration needed.\n\n### Mail accounts\n\nThey are generated directly to file `postfix-accounts.cf` according to [these instructions](https://docker-mailserver.github.io/docker-mailserver/edge/config/user-management/accounts/).\n\n## Troubleshooting\n\nYou can see what happen in Docker logs on host\n\n```bash\ndocker logs mail-server\n```\n\n**When you found some bug in the role create an [issue on GitHub](https://github.com/hmlkao/ansible-docker-mailserver/issues) please.**\n\n## Sources\n\n- [RSA sign and verify using Openssl : Behind the scene](https://medium.com/@bn121rajesh/rsa-sign-and-verify-using-openssl-behind-the-scene-bf3cac0aade2)\n  - Interesting article about how RSA signing (used by DKIM) works\n\n## Contributing\n\nAll helping hands are appreciated. Check [CONTRIBUTING.md](https://github.com/hmlkao/ansible-docker-mailserver/blob/master/CONTRIBUTING.md)\n\n## Ansible Galaxy\n\n1. [Local setup](https://ansible.readthedocs.io/projects/galaxy-ng/en/latest/community/userguide/#ansible-core-cli-setup)\n\n    ```bash\n    $ cat ~/.ansible.cfg\n    [galaxy]\n    server_list = beta\n\n    [galaxy_server.beta]\n    url = https://beta-galaxy.ansible.com/api/\n    token = \u003ctoken\u003e\n    ```\n\n2. *(first use)* Create Ansible Galaxy metadata\n\n   - Creates folder `\u003cnamespace\u003e.\u003ccollection\u003e`\n\n    ```bash\n    ansible-galaxy collection init hmlkao.docker_mailserver\n    ```\n\n3. Build collection package\n\n    - Creates tarball with `tar.gz` extension\n\n    ```bash\n    ansible-galaxy collection build\n    ```\n\n4. Upload Collection\n\n    ```bash\n    ansible-galaxy collection publish ./hmlkao-docker_mailserver-\u003cversion\u003e.tar.gz\n    ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhmlkao%2Fansible-docker-mailserver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhmlkao%2Fansible-docker-mailserver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhmlkao%2Fansible-docker-mailserver/lists"}