{"id":38145986,"url":"https://github.com/gottaeat/mserv","last_synced_at":"2026-01-16T22:56:00.548Z","repository":{"id":282747699,"uuid":"949533197","full_name":"gottaeat/mserv","owner":"gottaeat","description":"Dockerized secure-out-of-the-box production quality SMTP+IMAP4 server","archived":false,"fork":false,"pushed_at":"2025-12-15T00:18:07.000Z","size":35,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-17T14:52:01.773Z","etag":null,"topics":["docker","dovecot","imap","mail","mailserver","opendkim","postfix","smtp"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gottaeat.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-03-16T17:09:23.000Z","updated_at":"2025-12-15T00:17:06.000Z","dependencies_parsed_at":"2025-03-16T18:48:48.244Z","dependency_job_id":"6341d223-4393-4b04-9d49-ea83a3a7e878","html_url":"https://github.com/gottaeat/mserv","commit_stats":null,"previous_names":["gottaeat/mserv"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/gottaeat/mserv","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gottaeat%2Fmserv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gottaeat%2Fmserv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gottaeat%2Fmserv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gottaeat%2Fmserv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gottaeat","download_url":"https://codeload.github.com/gottaeat/mserv/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gottaeat%2Fmserv/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28486939,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T22:54:02.790Z","status":"ssl_error","status_checked_at":"2026-01-16T22:50:10.344Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["docker","dovecot","imap","mail","mailserver","opendkim","postfix","smtp"],"created_at":"2026-01-16T22:56:00.494Z","updated_at":"2026-01-16T22:56:00.542Z","avatar_url":"https://github.com/gottaeat.png","language":"Shell","readme":"# mserv\nmserv provides a secure out of the box production quality mail server, utilizing\npostfix, dovecot and opendkim.\n\n__WARNING__: mserv assumes that you are intending to run a bare domain mail\nserver, meaning that you have your MX record set to the domain itself e.g.:\n```\nexample.com. 300 IN MX 10 example.com.\n```\n\n## features\n1. sasl auth is allowed only on submission{,s} ports, auth on smtp is rejected.\n2. dovecot only serves imap4, and does so only on tcp port 993.\n3. ingress messages are checked for dkim, egress is signed with.\n4. user spoofing is mitigated with postfix sender restictions and envelope\n   sender mappings.\n\n## versions\n| component         | version              |\n| ----------------- | -------------------- |\n| docker base image | alpine:3.22.1        |\n| postfix           | 3.10.3               |\n| dovecot           | 2.4.1-4 (7d8c0e5759) |\n| opendkim          | v2.11.0              |\n\n## installation\n### 1. prerequisites\n#### 1.1. pull repo\n```sh\ngit clone --depth=1 https://github.com/gottaeat/mserv\ncd mserv/\n```\n\n#### 1.2. set a domain and define its public v4\n```sh\n_MYDOMAIN=\"example.com\"\n_MYPUBIP=\"1.1.1.1\"\n```\n\n#### 1.3. gen a letsencrypt cert\nmserv expects valid certs for `$_MYDOMAIN` to be present under\n`/etc/letsencrypt`.\n\n#### 1.4. create the bind-mount volume structure\n```sh\nmkdir -pv ./data/config/{postfix,dovecot/keys,opendkim}\n```\n\n### 2. postfix\n#### 2.1. register your domain\n```sh\necho \"${_MYDOMAIN} 20080428\" \u003e data/config/postfix/virtual_mailbox_domains\n```\n\n#### 2.2. define users and their mailboxes\ncreate as many users as necessary. `admin` is used here so we can alias\n`postmaster` to it, can be arbitrary, just ensure that you alias `postmaster` to\nit.\n```sh\ncat \u003c\u003c EOF \u003e data/config/postfix/virtual_mailbox_maps\nadmin@${_MYDOMAIN} ${_MYDOMAIN}/admin/\nEOF\n```\n\n#### 2.3. map the user(s) to themselves in the envelope senders\n```sh\ncat \u003c\u003c EOF \u003e data/config/postfix/controlled_envelope_senders\nadmin@${_MYDOMAIN} admin@${_MYDOMAIN}\nEOF\n```\n\n#### 2.4. define aliases\nthe `postmaster` alias is necessary.\n```sh\ncat \u003c\u003c EOF \u003e data/config/postfix/virtual_alias_maps\npostmaster@${_MYDOMAIN} admin@${_MYDOMAIN}\nEOF\n```\n\n### 3. dovecot\n#### 3.1. create `userdb` entries for the user(s)\nget the hashed password via `docker compose run --rm -it mserv doveadm pw -s\nSHA512-CRYPT`, edit the `data/config/dovecot/userdb` manually to avoid having\nto escape the `$` characters. the end result should look similar to:\n```sh\nadmin@${_MYDOMAIN}:\u003chash_here\u003e\n```\n\n### 4. opendkim\n#### 4.1. create the DKIM privkey\nset the output as the DKIM record for your domain.\n```sh\nmkdir -pv data/config/opendkim/keys/\"${_MYDOMAIN}\"\ndocker compose run --rm -it mserv ash -c \"\n    cd /opendkim/keys/${_MYDOMAIN}\n    opendkim-genkey -s mail -d ${_MYDOMAIN}\n    cat mail.txt\"\n```\n\n#### 4.2. create KeyTable, SigningTable and TrustedHosts\n```sh\ncat \u003c\u003c EOF \u003e data/config/opendkim/KeyTable\nmail._domainkey.${_MYDOMAIN} ${_MYDOMAIN}:mail:/opendkim/keys/${_MYDOMAIN}/mail.private\nEOF\n\ncat \u003c\u003c EOF \u003e data/config/opendkim/SigningTable\n*@${_MYDOMAIN} mail._domainkey.${_MYDOMAIN}\nEOF\n\ncat \u003c\u003c EOF \u003e data/config/opendkim/TrustedHosts\n127.0.0.1\nlocalhost\n${_MYDOMAIN}\n${_MYPUBIP}\nEOF\n```\n\n### 5. bringup\n#### 5.1. add SPF and DMARC records for maximum deliverability\nadd the following records to your DNS:\n```zone\n_dmarc.${_MYDOMAIN}. 300 IN TXT \"v=DMARC1; p=reject; rua=mailto:postmaster@${_MYDOMAIN}; ruf=mailto:postmaster@${_MYDOMAIN}; sp=reject; aspf=s; adkim=s; fo=1;\"\n${_MYDOMAIN}.        300 IN TXT \"v=spf1 a mx ip4:${_MYPUBIP} ra=postmaster -all\"\n```\n#### 5.2. action\nedit `docker-compose.yml` and set the `hostname:` key to the value of\n`$_MYDOMAIN`, then fire up the mail server with:\n```sh\ndocker compose up -d\n```\n\n## maintenance\nyou can follow the steps for postfix and dovecot for adding and removing users\nand aliases without bringing the container down. once the files are to your\nliking, pop into the container via `docker exec -it mserv ash` and do:\n```sh\nfor i in \\\n    virtual_mailbox_domains \\\n    controlled_envelope_senders \\\n    virtual_mailbox_maps \\\n    virtual_alias_maps; do\n        postmap \"/postfix/${i}\"\ndone\n\npostfix reload\ndovecot reload\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgottaeat%2Fmserv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgottaeat%2Fmserv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgottaeat%2Fmserv/lists"}