├── .editorconfig
├── .gitattributes
├── .github
├── CODEOWNERS
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── bug.yml
│ ├── bug_report.md
│ ├── config.yml
│ └── feature.yml
├── SUPPORT.md
├── dependabot.yml
├── docker-msmtpd.jpg
├── labels.yml
└── workflows
│ ├── build.yml
│ ├── labels.yml
│ └── test.yml
├── Dockerfile
├── LICENSE
├── README.md
├── docker-bake.hcl
├── examples
├── compose
│ └── compose.yml
└── kubernetes
│ └── deployment.yaml
├── rootfs
└── etc
│ └── cont-init.d
│ ├── 00-fix-logs.sh
│ ├── 01-fix-uidgid.sh
│ ├── 02-config.sh
│ └── 03-create-service.sh
└── test
└── compose.yml
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = false
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 | insert_final_newline = true
15 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | /rootfs/** linguist-detectable=false
2 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @crazy-max
2 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: crazy-max
2 | custom: https://www.paypal.me/crazyws
3 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug.yml:
--------------------------------------------------------------------------------
1 | # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema
2 | name: Bug Report
3 | description: Report a bug
4 | labels:
5 | - kind/bug
6 | - status/triage
7 |
8 | body:
9 | - type: checkboxes
10 | attributes:
11 | label: Support guidelines
12 | description: Please read the support guidelines before proceeding.
13 | options:
14 | - label: I've read the [support guidelines](https://github.com/crazy-max/docker-msmtpd/blob/master/.github/SUPPORT.md)
15 | required: true
16 |
17 | - type: checkboxes
18 | attributes:
19 | label: I've found a bug and checked that ...
20 | description: |
21 | Make sure that your request fulfills all of the following requirements. If one requirement cannot be satisfied, explain in detail why.
22 | options:
23 | - label: ... the documentation does not mention anything about my problem
24 | - label: ... there are no open or closed issues that are related to my problem
25 |
26 | - type: textarea
27 | attributes:
28 | label: Description
29 | description: |
30 | Please provide a brief description of the bug in 1-2 sentences.
31 | validations:
32 | required: true
33 |
34 | - type: textarea
35 | attributes:
36 | label: Expected behaviour
37 | description: |
38 | Please describe precisely what you'd expect to happen.
39 | validations:
40 | required: true
41 |
42 | - type: textarea
43 | attributes:
44 | label: Actual behaviour
45 | description: |
46 | Please describe precisely what is actually happening.
47 | validations:
48 | required: true
49 |
50 | - type: textarea
51 | attributes:
52 | label: Steps to reproduce
53 | description: |
54 | Please describe the steps to reproduce the bug.
55 | placeholder: |
56 | 1. ...
57 | 2. ...
58 | 3. ...
59 | validations:
60 | required: true
61 |
62 | - type: textarea
63 | attributes:
64 | label: Docker info
65 | description: |
66 | Output of `docker info` command.
67 | render: text
68 | validations:
69 | required: true
70 |
71 | - type: textarea
72 | attributes:
73 | label: Docker Compose config
74 | description: |
75 | Output of `docker compose config` command.
76 | render: yaml
77 |
78 | - type: textarea
79 | attributes:
80 | label: Logs
81 | description: |
82 | Please provide the container logs (set `LOG_LEVEL=debug` if applicable).
83 | render: text
84 | validations:
85 | required: true
86 |
87 | - type: textarea
88 | attributes:
89 | label: Additional info
90 | description: |
91 | Please provide any additional information that seem useful.
92 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | ---
5 |
6 | ### Behaviour
7 |
8 | #### Steps to reproduce this issue
9 |
10 | 1.
11 | 2.
12 | 3.
13 |
14 | #### Expected behaviour
15 |
16 | > Tell me what should happen
17 |
18 | #### Actual behaviour
19 |
20 | > Tell me what happens instead
21 |
22 | ### Configuration
23 |
24 | * Docker version (type `docker --version`) :
25 | * Docker compose version if applicable (type `docker-compose --version`) :
26 | * Platform (Debian 9, Ubuntu 18.04, ...) :
27 | * System info (type `uname -a`) :
28 | * Include all necessary configuration files : `docker-compose.yml`, `.env`, ...
29 |
30 | ### Docker info
31 |
32 | ```
33 | > Output of command `docker info`
34 | ```
35 |
36 | ### Logs
37 |
38 | ```
39 | > Container logs (set LOG_LEVEL to debug if applicable)
40 | ```
41 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository#configuring-the-template-chooser
2 | blank_issues_enabled: true
3 | contact_links:
4 | - name: Questions and Discussions
5 | url: https://github.com/crazy-max/docker-msmtpd/discussions/new
6 | about: Use Github Discussions to ask questions and/or open discussion topics.
7 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature.yml:
--------------------------------------------------------------------------------
1 | # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema
2 | name: Feature request
3 | description: Missing functionality? Come tell us about it!
4 | labels:
5 | - kind/enhancement
6 | - status/triage
7 |
8 | body:
9 | - type: textarea
10 | id: description
11 | attributes:
12 | label: Description
13 | description: What is the feature you want to see?
14 | validations:
15 | required: true
16 |
--------------------------------------------------------------------------------
/.github/SUPPORT.md:
--------------------------------------------------------------------------------
1 | # Support [](https://isitmaintained.com/project/crazy-max/docker-msmtpd)
2 |
3 | ## Reporting an issue
4 |
5 | Please do a search in [open issues](https://github.com/crazy-max/docker-msmtpd/issues?utf8=%E2%9C%93&q=) to see if the issue or feature request has already been filed.
6 |
7 | If you find your issue already exists, make relevant comments and add your [reaction](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments). Use a reaction in place of a "+1" comment.
8 |
9 | :+1: - upvote
10 |
11 | :-1: - downvote
12 |
13 | If you cannot find an existing issue that describes your bug or feature, submit an issue using the guidelines below.
14 |
15 | ## Writing good bug reports and feature requests
16 |
17 | File a single issue per problem and feature request.
18 |
19 | * Do not enumerate multiple bugs or feature requests in the same issue.
20 | * Do not add your issue as a comment to an existing issue unless it's for the identical input. Many issues look similar, but have different causes.
21 |
22 | The more information you can provide, the more likely someone will be successful reproducing the issue and finding a fix.
23 |
24 | You are now ready to [create a new issue](https://github.com/crazy-max/docker-msmtpd/issues/new/choose)!
25 |
26 | ## Closure policy
27 |
28 | * Support directly related to msmtpd will not be provided if your problem is not related to the operation of this image.
29 | * Issues that don't have the information requested above (when applicable) will be closed immediately and the poster directed to the support guidelines.
30 | * Issues that go a week without a response from original poster are subject to closure at my discretion.
31 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "github-actions"
4 | directory: "/"
5 | schedule:
6 | interval: "daily"
7 | time: "08:00"
8 | timezone: "Europe/Paris"
9 | labels:
10 | - "kind/dependencies"
11 | - "bot"
12 |
--------------------------------------------------------------------------------
/.github/docker-msmtpd.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/crazy-max/docker-msmtpd/e1b38c5e7cc4ed59fb1118c00ef6adcb08bd7173/.github/docker-msmtpd.jpg
--------------------------------------------------------------------------------
/.github/labels.yml:
--------------------------------------------------------------------------------
1 | ## more info https://github.com/crazy-max/ghaction-github-labeler
2 | -
3 | name: "bot"
4 | color: "69cde9"
5 | description: ""
6 | -
7 | name: "good first issue"
8 | color: "7057ff"
9 | description: ""
10 | -
11 | name: "help wanted"
12 | color: "4caf50"
13 | description: ""
14 | -
15 | name: "area/ci"
16 | color: "ed9ca9"
17 | description: ""
18 | -
19 | name: "area/dockerfile"
20 | color: "03a9f4"
21 | description: ""
22 | -
23 | name: "kind/bug"
24 | color: "b60205"
25 | description: ""
26 | -
27 | name: "kind/dependencies"
28 | color: "0366d6"
29 | description: ""
30 | -
31 | name: "kind/docs"
32 | color: "c5def5"
33 | description: ""
34 | -
35 | name: "kind/duplicate"
36 | color: "cccccc"
37 | description: ""
38 | -
39 | name: "kind/enhancement"
40 | color: "0054ca"
41 | description: ""
42 | -
43 | name: "kind/invalid"
44 | color: "e6e6e6"
45 | description: ""
46 | -
47 | name: "kind/upstream"
48 | color: "fbca04"
49 | description: ""
50 | -
51 | name: "kind/wontfix"
52 | color: "ffffff"
53 | description: ""
54 | -
55 | name: "status/automerge"
56 | color: "8f4fbc"
57 | description: ""
58 | -
59 | name: "status/needs-investigation"
60 | color: "e6625b"
61 | description: ""
62 | -
63 | name: "status/needs-more-info"
64 | color: "795548"
65 | description: ""
66 | -
67 | name: "status/stale"
68 | color: "237da0"
69 | description: ""
70 | -
71 | name: "status/triage"
72 | color: "dde4b7"
73 | description: ""
74 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: build
2 |
3 | concurrency:
4 | group: ${{ github.workflow }}-${{ github.ref }}
5 | cancel-in-progress: true
6 |
7 | # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions
8 | permissions:
9 | contents: read
10 |
11 | on:
12 | push:
13 | branches:
14 | - 'master'
15 | tags:
16 | - '*'
17 | paths-ignore:
18 | - '**.md'
19 | pull_request:
20 | paths-ignore:
21 | - '**.md'
22 |
23 | env:
24 | DOCKERHUB_SLUG: crazymax/msmtpd
25 | GHCR_SLUG: ghcr.io/crazy-max/msmtpd
26 |
27 | jobs:
28 | build:
29 | runs-on: ubuntu-latest
30 | permissions:
31 | # same as global permissions
32 | contents: read
33 | # required to push to GHCR
34 | packages: write
35 | steps:
36 | -
37 | name: Docker meta
38 | id: meta
39 | uses: docker/metadata-action@v5
40 | with:
41 | images: |
42 | ${{ env.DOCKERHUB_SLUG }}
43 | ${{ env.GHCR_SLUG }}
44 | tags: |
45 | type=match,pattern=(.*)-r,group=1
46 | type=ref,event=pr
47 | type=edge
48 | labels: |
49 | org.opencontainers.image.title=msmtpd
50 | org.opencontainers.image.description=Lightweight SMTP relay using msmtpd
51 | org.opencontainers.image.vendor=CrazyMax
52 | -
53 | name: Set up QEMU
54 | uses: docker/setup-qemu-action@v3
55 | -
56 | name: Set up Docker Buildx
57 | uses: docker/setup-buildx-action@v3
58 | -
59 | name: Login to DockerHub
60 | if: github.event_name != 'pull_request'
61 | uses: docker/login-action@v3
62 | with:
63 | username: ${{ secrets.DOCKER_USERNAME }}
64 | password: ${{ secrets.DOCKER_PASSWORD }}
65 | -
66 | name: Login to GHCR
67 | if: github.event_name != 'pull_request'
68 | uses: docker/login-action@v3
69 | with:
70 | registry: ghcr.io
71 | username: ${{ github.repository_owner }}
72 | password: ${{ secrets.GITHUB_TOKEN }}
73 | -
74 | name: Build
75 | uses: docker/bake-action@v6
76 | with:
77 | files: |
78 | ./docker-bake.hcl
79 | cwd://${{ steps.meta.outputs.bake-file }}
80 | targets: image-all
81 | push: ${{ github.event_name != 'pull_request' }}
82 | -
83 | name: Check manifest
84 | if: github.event_name != 'pull_request'
85 | run: |
86 | docker buildx imagetools inspect ${{ env.DOCKERHUB_SLUG }}:${{ steps.meta.outputs.version }}
87 | docker buildx imagetools inspect ${{ env.GHCR_SLUG }}:${{ steps.meta.outputs.version }}
88 | -
89 | name: Inspect image
90 | if: github.event_name != 'pull_request'
91 | run: |
92 | docker pull ${{ env.DOCKERHUB_SLUG }}:${{ steps.meta.outputs.version }}
93 | docker image inspect ${{ env.DOCKERHUB_SLUG }}:${{ steps.meta.outputs.version }}
94 | docker pull ${{ env.GHCR_SLUG }}:${{ steps.meta.outputs.version }}
95 | docker image inspect ${{ env.GHCR_SLUG }}:${{ steps.meta.outputs.version }}
96 |
--------------------------------------------------------------------------------
/.github/workflows/labels.yml:
--------------------------------------------------------------------------------
1 | name: labels
2 |
3 | concurrency:
4 | group: ${{ github.workflow }}-${{ github.ref }}
5 | cancel-in-progress: true
6 |
7 | # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions
8 | permissions:
9 | contents: read
10 |
11 | on:
12 | push:
13 | branches:
14 | - 'master'
15 | paths:
16 | - '.github/labels.yml'
17 | - '.github/workflows/labels.yml'
18 | pull_request:
19 | paths:
20 | - '.github/labels.yml'
21 | - '.github/workflows/labels.yml'
22 |
23 | jobs:
24 | labeler:
25 | runs-on: ubuntu-latest
26 | permissions:
27 | # same as global permissions
28 | contents: read
29 | # required to update labels
30 | issues: write
31 | steps:
32 | -
33 | name: Checkout
34 | uses: actions/checkout@v4
35 | -
36 | name: Run Labeler
37 | uses: crazy-max/ghaction-github-labeler@v5
38 | with:
39 | dry-run: ${{ github.event_name == 'pull_request' }}
40 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: test
2 |
3 | concurrency:
4 | group: ${{ github.workflow }}-${{ github.ref }}
5 | cancel-in-progress: true
6 |
7 | # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions
8 | permissions:
9 | contents: read
10 |
11 | on:
12 | push:
13 | branches:
14 | - 'master'
15 | paths-ignore:
16 | - '**.md'
17 | pull_request:
18 | paths-ignore:
19 | - '**.md'
20 |
21 | env:
22 | BUILD_TAG: msmtpd:test
23 | CONTAINER_NAME: msmtpd
24 |
25 | jobs:
26 | test:
27 | runs-on: ubuntu-latest
28 | steps:
29 | -
30 | name: Checkout
31 | uses: actions/checkout@v4
32 | -
33 | name: Set up QEMU
34 | uses: docker/setup-qemu-action@v3
35 | -
36 | name: Set up Docker Buildx
37 | uses: docker/setup-buildx-action@v3
38 | -
39 | name: Build
40 | uses: docker/bake-action@v6
41 | with:
42 | source: .
43 | targets: image-local
44 | env:
45 | DEFAULT_TAG: ${{ env.BUILD_TAG }}
46 | -
47 | name: Start
48 | run: |
49 | docker compose up -d
50 | working-directory: test
51 | env:
52 | MSMTPD_IMAGE: ${{ env.BUILD_TAG }}
53 | MSMTPD_CONTAINER: ${{ env.CONTAINER_NAME }}
54 | -
55 | name: Check container logs
56 | uses: crazy-max/.github/.github/actions/container-logs-check@main
57 | with:
58 | container_name: ${{ env.CONTAINER_NAME }}
59 | log_check: "[services.d] done"
60 | timeout: 120
61 | -
62 | name: Logs
63 | if: always()
64 | run: |
65 | docker compose logs
66 | working-directory: test
67 | env:
68 | MSMTPD_IMAGE: ${{ env.BUILD_TAG }}
69 | MSMTPD_CONTAINER: ${{ env.CONTAINER_NAME }}
70 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # syntax=docker/dockerfile:1
2 |
3 | ARG MSMTP_VERSION=1.8.28
4 | ARG ALPINE_VERSION=3.21
5 | ARG XX_VERSION=1.6.1
6 |
7 | FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
8 | FROM --platform=$BUILDPLATFORM alpine:${ALPINE_VERSION} AS base
9 | COPY --from=xx / /
10 | RUN apk --update --no-cache add clang curl file lld make musl-dev pkgconfig tar xz
11 | ARG MSMTP_VERSION
12 | WORKDIR /src
13 | RUN curl -sSL "https://marlam.de/msmtp/releases/msmtp-$MSMTP_VERSION.tar.xz" | tar xJv --strip 1
14 |
15 | FROM base AS builder
16 | ARG TARGETPLATFORM
17 | RUN xx-apk --no-cache --no-scripts add g++ gettext-dev gnutls-dev libidn2-dev
18 | RUN <