mirror of
https://github.com/foxcpp/maddy.git
synced 2025-04-01 20:27:36 +03:00
Improve Docker image
* Use TLS filenames same as certbot (see #350). * Put the Docker-specific maddy.conf in the repo (see #350). * Set OCI labels for the image in CI * Move Docker-specific documentation from Docker Hub into docs/ * Add .dockerignore
This commit is contained in:
parent
9dd34b85ef
commit
2037b05dae
7 changed files with 297 additions and 30 deletions
4
.dockerignore
Normal file
4
.dockerignore
Normal file
|
@ -0,0 +1,4 @@
|
|||
testdata/
|
||||
cmd/maddy/maddy
|
||||
maddy
|
||||
tests/maddy.cover
|
29
.github/workflows/cicd.yml
vendored
29
.github/workflows/cicd.yml
vendored
|
@ -85,16 +85,16 @@ jobs:
|
|||
path: '~/maddy-x86_64-linux-musl.tar.zst'
|
||||
if-no-files-found: error
|
||||
docker-builder:
|
||||
name: "Build Docker image"
|
||||
needs: build-and-test
|
||||
name: "Build & push Docker image"
|
||||
needs: build-and-test # Upload
|
||||
if: github.ref_type == 'tag'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up QEMU
|
||||
- name: "Set up QEMU"
|
||||
uses: docker/setup-qemu-action@v1
|
||||
with:
|
||||
platforms: arm64
|
||||
- name: Set up Docker Buildx
|
||||
- name: "Set up Docker Buildx"
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
- name: "Login to Docker Hub"
|
||||
|
@ -108,13 +108,24 @@ jobs:
|
|||
registry: "ghcr.io"
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: "Generate container metadata"
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
foxcpp/maddy
|
||||
ghcr.io/foxcpp/maddy
|
||||
tags: |
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
labels: |
|
||||
org.opencontainers.image.title=Maddy Mail Server
|
||||
org.opencontainers.image.documentation=https://maddy.email/docker/
|
||||
org.opencontainers.image.url=https://maddy.email
|
||||
- name: "Build and push"
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64/v8
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: |
|
||||
foxcpp/maddy:${{ github.ref_name }}
|
||||
ghcr.io/foxcpp/maddy:${{ github.ref_name }}
|
||||
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
|
|
@ -19,6 +19,7 @@ nav:
|
|||
- multiple-domains.md
|
||||
- upgrading.md
|
||||
- seclevels.md
|
||||
- docker.md
|
||||
- Reference manual:
|
||||
- reference/modules.md
|
||||
- reference/global-config.md
|
||||
|
|
31
Dockerfile
31
Dockerfile
|
@ -1,33 +1,30 @@
|
|||
FROM golang:1.17-alpine AS build-env
|
||||
|
||||
RUN set -ex ;\
|
||||
apk upgrade --no-cache --available ;\
|
||||
apk add --no-cache bash git build-base
|
||||
RUN set -ex && \
|
||||
apk upgrade --no-cache --available && \
|
||||
apk add --no-cache build-base
|
||||
|
||||
WORKDIR /maddy
|
||||
ADD go.mod go.sum ./
|
||||
ENV LDFLAGS -static
|
||||
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
ADD . ./
|
||||
RUN mkdir -p /pkg/data
|
||||
COPY maddy.conf /pkg/data/maddy.conf
|
||||
# Monkey-patch config to use environment.
|
||||
RUN sed -Ei 's!\$\(hostname\) = .+!$(hostname) = {env:MADDY_HOSTNAME}!' /pkg/data/maddy.conf
|
||||
RUN sed -Ei 's!\$\(primary_domain\) = .+!$(primary_domain) = {env:MADDY_DOMAIN}!' /pkg/data/maddy.conf
|
||||
RUN sed -Ei 's!^tls .+!tls file /data/tls_cert.pem /data/tls_key.pem!' /pkg/data/maddy.conf
|
||||
|
||||
RUN ./build.sh --builddir /tmp --destdir /pkg/ --tags docker build install
|
||||
COPY . ./
|
||||
RUN mkdir -p /pkg/data && \
|
||||
cp maddy.conf.docker /pkg/data/maddy.conf && \
|
||||
./build.sh --builddir /tmp --destdir /pkg/ --tags docker build install
|
||||
|
||||
FROM alpine:3.15.0
|
||||
FROM alpine:3.16.0
|
||||
LABEL maintainer="fox.cpp@disroot.org"
|
||||
LABEL org.opencontainers.image.source=https://github.com/foxcpp/maddy
|
||||
|
||||
RUN set -ex ;\
|
||||
apk upgrade --no-cache --available ;\
|
||||
RUN set -ex && \
|
||||
apk upgrade --no-cache --available && \
|
||||
apk --no-cache add ca-certificates
|
||||
COPY --from=build-env /pkg/data/maddy.conf /data/maddy.conf
|
||||
COPY --from=build-env /pkg/usr/local/bin/maddy /pkg/usr/local/bin/maddyctl /bin/
|
||||
|
||||
EXPOSE 25 143 993 587 465
|
||||
VOLUME ["/data"]
|
||||
ENTRYPOINT ["/bin/maddy", "-config", "/data/maddy.conf", "run"]
|
||||
ENTRYPOINT ["/bin/maddy", "-config", "/data/maddy.conf"]
|
||||
CMD ["run"]
|
||||
|
|
75
docs/docker.md
Normal file
75
docs/docker.md
Normal file
|
@ -0,0 +1,75 @@
|
|||
# Docker
|
||||
|
||||
Official Docker image is available from Docker Hub.
|
||||
|
||||
It expects configuration file to be available at /data/maddy.conf.
|
||||
|
||||
If /data is a Docker volume, then default configuration will be placed there
|
||||
automatically. If it is used, then MADDY_HOSTNAME, MADDY_DOMAIN environment
|
||||
variables control the host name and primary domain for the server. TLS
|
||||
certificate should be placed in /data/tls/fullchain.pem, private key in
|
||||
/data/tls/privkey.pem
|
||||
|
||||
DKIM keys are generated in /data/dkim_keys directory.
|
||||
|
||||
## Image tags
|
||||
|
||||
- `latest` - A latest stable release. May contain breaking changes.
|
||||
- `X.Y` - A specific feature branch, it is recommended to use these tags to
|
||||
receive bugfixes without the risk of feature-related regressions or breaking
|
||||
changes.
|
||||
- `X.Y.Z` - A specific stable release
|
||||
|
||||
## Ports
|
||||
|
||||
All standard ports, as described in maddy docs.
|
||||
|
||||
- `25` - SMTP inbound port.
|
||||
- `465`, `587` - SMTP Submission ports
|
||||
- `993`, `143` - IMAP4 ports
|
||||
|
||||
## Volumes
|
||||
|
||||
`/data` - maddy state directory. Databases, queues, etc are stored here. You
|
||||
might want to mount a named volume there. The main configuration file is stored
|
||||
here too (`/data/maddy.conf`).
|
||||
|
||||
## Management utility
|
||||
|
||||
To run management commands, create a temporary container with the same
|
||||
/data directory and put the command after the image name, like this:
|
||||
|
||||
```
|
||||
docker run --rm -it -v maddydata:/data foxcpp/maddy:0.6.0 creds create foxcpp@maddy.test
|
||||
docker run --rm -it -v maddydata:/data foxcpp/maddy:0.6.0 imap-acct create foxcpp@maddy.test
|
||||
```
|
||||
|
||||
Use the same image version as the running server. Things may break badly
|
||||
otherwise.
|
||||
|
||||
Note that, if you modify messages using maddyctl while the server is running -
|
||||
you must ensure that /tmp from the server is accessible for the management
|
||||
command. One way to it is to run it using `docker exec` instead of `docker run`:
|
||||
```
|
||||
docker exec -it container_name_here maddy creds create foxcpp@maddy.test
|
||||
```
|
||||
|
||||
## TL;DR
|
||||
|
||||
```
|
||||
docker volume create maddydata
|
||||
docker run \
|
||||
--name maddy \
|
||||
-e MADDY_HOSTNAME=mx.maddy.test \
|
||||
-e MADDY_DOMAIN=maddy.test \
|
||||
-v maddydata:/data \
|
||||
-p 25:25 \
|
||||
-p 143:143 \
|
||||
-p 587:587 \
|
||||
-p 993:993 \
|
||||
foxcpp/maddy:0.6
|
||||
```
|
||||
|
||||
It will fail on first startup. Copy TLS certificate to /data/tls/fullchain.pem
|
||||
and key to /data/tls/privkey.pem. Run the server again. Finish DNS configuration
|
||||
(DKIM keys, etc) as described in [tutorials/setting-up/](tutorials/setting-up/).
|
|
@ -1,12 +1,9 @@
|
|||
## Maddy Mail Server - default configuration file (2021-08-16)
|
||||
## Maddy Mail Server - default configuration file (2022-06-18)
|
||||
# Suitable for small-scale deployments. Uses its own format for local users DB,
|
||||
# should be managed via maddyctl utility.
|
||||
#
|
||||
# See tutorials at https://maddy.email for guidance on typical
|
||||
# configuration changes.
|
||||
#
|
||||
# See manual pages (also available at https://maddy.email) for reference
|
||||
# documentation.
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Base variables
|
||||
|
|
182
maddy.conf.docker
Normal file
182
maddy.conf.docker
Normal file
|
@ -0,0 +1,182 @@
|
|||
## Maddy Mail Server - default configuration file (2022-06-18)
|
||||
## This is the copy of maddy.conf with changes necessary to run it in Docker.
|
||||
# Suitable for small-scale deployments. Uses its own format for local users DB,
|
||||
# should be managed via maddyctl utility.
|
||||
#
|
||||
# See tutorials at https://maddy.email for guidance on typical
|
||||
# configuration changes.
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Base variables
|
||||
|
||||
$(hostname) = {env:MADDY_HOSTNAME}
|
||||
$(primary_domain) = {env:MADDY_DOMAIN}
|
||||
$(local_domains) = $(primary_domain)
|
||||
|
||||
tls file /data/tls/fullchain.pem /data/tls/privkey.pem
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Local storage & authentication
|
||||
|
||||
# pass_table provides local hashed passwords storage for authentication of
|
||||
# users. It can be configured to use any "table" module, in default
|
||||
# configuration a table in SQLite DB is used.
|
||||
# Table can be replaced to use e.g. a file for passwords. Or pass_table module
|
||||
# can be replaced altogether to use some external source of credentials (e.g.
|
||||
# PAM, /etc/shadow file).
|
||||
#
|
||||
# If table module supports it (sql_table does) - credentials can be managed
|
||||
# using 'maddyctl creds' command.
|
||||
|
||||
auth.pass_table local_authdb {
|
||||
table sql_table {
|
||||
driver sqlite3
|
||||
dsn credentials.db
|
||||
table_name passwords
|
||||
}
|
||||
}
|
||||
|
||||
# imapsql module stores all indexes and metadata necessary for IMAP using a
|
||||
# relational database. It is used by IMAP endpoint for mailbox access and
|
||||
# also by SMTP & Submission endpoints for delivery of local messages.
|
||||
#
|
||||
# IMAP accounts, mailboxes and all message metadata can be inspected using
|
||||
# imap-* subcommands of maddyctl utility.
|
||||
|
||||
storage.imapsql local_mailboxes {
|
||||
driver sqlite3
|
||||
dsn imapsql.db
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# SMTP endpoints + message routing
|
||||
|
||||
hostname $(hostname)
|
||||
|
||||
table.chain local_rewrites {
|
||||
optional_step regexp "(.+)\+(.+)@(.+)" "$1@$3"
|
||||
optional_step static {
|
||||
entry postmaster postmaster@$(primary_domain)
|
||||
}
|
||||
optional_step file /etc/maddy/aliases
|
||||
}
|
||||
|
||||
msgpipeline local_routing {
|
||||
# Insert handling for special-purpose local domains here.
|
||||
# e.g.
|
||||
# destination lists.example.org {
|
||||
# deliver_to lmtp tcp://127.0.0.1:8024
|
||||
# }
|
||||
|
||||
destination postmaster $(local_domains) {
|
||||
modify {
|
||||
replace_rcpt &local_rewrites
|
||||
}
|
||||
|
||||
deliver_to &local_mailboxes
|
||||
}
|
||||
|
||||
default_destination {
|
||||
reject 550 5.1.1 "User doesn't exist"
|
||||
}
|
||||
}
|
||||
|
||||
smtp tcp://0.0.0.0:25 {
|
||||
limits {
|
||||
# Up to 20 msgs/sec across max. 10 SMTP connections.
|
||||
all rate 20 1s
|
||||
all concurrency 10
|
||||
}
|
||||
|
||||
dmarc yes
|
||||
check {
|
||||
require_mx_record
|
||||
dkim
|
||||
spf
|
||||
}
|
||||
|
||||
source $(local_domains) {
|
||||
reject 501 5.1.8 "Use Submission for outgoing SMTP"
|
||||
}
|
||||
default_source {
|
||||
destination postmaster $(local_domains) {
|
||||
deliver_to &local_routing
|
||||
}
|
||||
default_destination {
|
||||
reject 550 5.1.1 "User doesn't exist"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
submission tls://0.0.0.0:465 tcp://0.0.0.0:587 {
|
||||
limits {
|
||||
# Up to 50 msgs/sec across any amount of SMTP connections.
|
||||
all rate 50 1s
|
||||
}
|
||||
|
||||
auth &local_authdb
|
||||
|
||||
source $(local_domains) {
|
||||
check {
|
||||
authorize_sender {
|
||||
prepare_email &local_rewrites
|
||||
user_to_email identity
|
||||
}
|
||||
}
|
||||
|
||||
destination postmaster $(local_domains) {
|
||||
deliver_to &local_routing
|
||||
}
|
||||
default_destination {
|
||||
modify {
|
||||
dkim $(primary_domain) $(local_domains) default
|
||||
}
|
||||
deliver_to &remote_queue
|
||||
}
|
||||
}
|
||||
default_source {
|
||||
reject 501 5.1.8 "Non-local sender domain"
|
||||
}
|
||||
}
|
||||
|
||||
target.remote outbound_delivery {
|
||||
limits {
|
||||
# Up to 20 msgs/sec across max. 10 SMTP connections
|
||||
# for each recipient domain.
|
||||
destination rate 20 1s
|
||||
destination concurrency 10
|
||||
}
|
||||
mx_auth {
|
||||
dane
|
||||
mtasts {
|
||||
cache fs
|
||||
fs_dir mtasts_cache/
|
||||
}
|
||||
local_policy {
|
||||
min_tls_level encrypted
|
||||
min_mx_level none
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
target.queue remote_queue {
|
||||
target &outbound_delivery
|
||||
|
||||
autogenerated_msg_domain $(primary_domain)
|
||||
bounce {
|
||||
destination postmaster $(local_domains) {
|
||||
deliver_to &local_routing
|
||||
}
|
||||
default_destination {
|
||||
reject 550 5.0.0 "Refusing to send DSNs to non-local addresses"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# IMAP endpoints
|
||||
|
||||
imap tls://0.0.0.0:993 tcp://0.0.0.0:143 {
|
||||
auth &local_authdb
|
||||
storage &local_mailboxes
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue