diff --git a/testing/maddy/APKBUILD b/testing/maddy/APKBUILD
new file mode 100644
index 0000000000000000000000000000000000000000..c2cfcba086729ce43f4d0c2d59fecafab85c101b
--- /dev/null
+++ b/testing/maddy/APKBUILD
@@ -0,0 +1,73 @@
+# Contributor: Michał Polański <michal@polanski.me>
+# Maintainer: Michał Polański <michal@polanski.me>
+pkgname=maddy
+pkgver=0.4.0
+pkgrel=0
+pkgdesc="Composable all-in-one mail server"
+url="https://foxcpp.dev/maddy/"
+license="GPL-3.0-or-later"
+arch="all !mips !mips64" # limited by go
+options="chmod-clean"
+makedepends="go linux-pam-dev libcap scdoc"
+subpackages="$pkgname-openrc $pkgname-doc $pkgname-vim::noarch"
+pkgusers="$pkgname"
+pkggroups="$pkgname"
+install="$pkgname.pre-install"
+source="$pkgname-$pkgver.tar.gz::https://github.com/foxcpp/maddy/archive/v$pkgver.tar.gz
+	$pkgname.initd
+	$pkgname.confd
+	use-syslog.patch
+	"
+
+export GOPATH="$srcdir"
+
+build() {
+	ldflags="-extldflags \"$LDFLAGS\" -s -w
+		-X github.com/foxcpp/maddy.DefaultLibexecDirectory=/usr/lib/maddy
+		-X github.com/foxcpp/maddy.DefaultStateDirectory=/var/lib/maddy
+		-X github.com/foxcpp/maddy.DefaultRuntimeDirectory=/run/maddy
+		-X github.com/foxcpp/maddy.ConfigDirectory=/etc/maddy
+		-X github.com/foxcpp/maddy.Version=$pkgver-$pkgrel
+		"
+
+	go build -trimpath -ldflags="$ldflags" -v -o bin/maddy ./cmd/maddy
+	go build -trimpath -ldflags="$ldflags" -v -o bin/maddyctl ./cmd/maddyctl
+
+	msg "Building man pages..."
+	for f in docs/man/*.scd; do
+		echo "$f -> ${f%.scd}.gz"
+		scdoc < "$f" | gzip > "${f%.scd}.gz"
+	done
+}
+
+check() {
+	go test ./...
+}
+
+package() {
+	install -Dm755 bin/maddy "$pkgdir"/usr/bin/maddy
+	setcap cap_net_bind_service=+ep "$pkgdir"/usr/bin/maddy
+	install -Dm755 bin/maddyctl "$pkgdir"/usr/bin/maddyctl
+
+	install -Dm644 maddy.conf "$pkgdir"/etc/maddy/maddy.conf
+
+	install -Dm755 "$srcdir"/$pkgname.initd "$pkgdir"/etc/init.d/$pkgname
+	install -Dm644 "$srcdir"/$pkgname.confd "$pkgdir"/etc/conf.d/$pkgname
+
+	install -Dm644 -t "$pkgdir"/usr/share/man/man1 docs/man/*.1.gz
+	install -Dm644 -t "$pkgdir"/usr/share/man/man5 docs/man/*.5.gz
+}
+
+vim() {
+	pkgdesc="$pkgdesc (vim syntax)"
+	depends=""
+	install_if="vim $pkgname=$pkgver-r$pkgrel"
+
+	mkdir -p "$subpkgdir"/usr/share/vim
+	cp -r "$builddir"/dist/vim "$subpkgdir"/usr/share/vim/vimfiles
+}
+
+sha512sums="8e459f96109939e7d375a00f2651699484c5e172566f95309c98c8ed3b0c876a40453f035e6cfc44a4640f03d76a202c5f12e665653dece7c10b0f3fcdd56558  maddy-0.4.0.tar.gz
+e6400f2e4b296d511d6b4a17e1411405ee8b7b642c892d7545d8d961b46899ff91cfc5ab254a79097634c33275d75b12d9ad7eb15e4dc4b650bc5cb07667bebd  maddy.initd
+0d7cc93c87b6b8ada3ee929513ae98f9393497371caaad85381f78f4a9ee7ec6523192fbea82ada013a7999521c0b88d6ca6a53a374b7b54f4a8e3d23cdda421  maddy.confd
+aab47869dd3b1e51fa0468fba8dcd24e2930127017b147165db280e28fb183f42b0401e8fcfa6dfb717c82fcecb4584934ddf3d73ad9f46034e0bd939bb96075  use-syslog.patch"
diff --git a/testing/maddy/maddy.confd b/testing/maddy/maddy.confd
new file mode 100644
index 0000000000000000000000000000000000000000..e92ee0cd17776a3e8488916f919386a5ef28ad51
--- /dev/null
+++ b/testing/maddy/maddy.confd
@@ -0,0 +1,3 @@
+# Configuration for /etc/init.d/maddy
+
+maddy_opts=""
diff --git a/testing/maddy/maddy.initd b/testing/maddy/maddy.initd
new file mode 100644
index 0000000000000000000000000000000000000000..1f3f9e6c6fdc04706708c8eccd60239db4dc3489
--- /dev/null
+++ b/testing/maddy/maddy.initd
@@ -0,0 +1,35 @@
+#!/sbin/openrc-run
+supervisor=supervise-daemon
+
+name="maddy"
+description="Composable all-in-one mail server"
+description_log_reopen="Reopen log files"
+description_reload="Reload some files from disk (but without main configuration)"
+
+command=/usr/bin/maddy
+command_args="$maddy_opts"
+command_user=maddy:maddy
+
+# make relative paths in config relative to the state directory
+directory="/var/lib/$RC_SVCNAME"
+extra_started_commands="log_reopen reload"
+
+depend() {
+	need net localmount
+	after firewall
+}
+
+log_reopen() {
+	ebegin "Reopening log files of $name"
+	supervise-daemon $RC_SVCNAME --signal USR1
+	eend $?
+}
+reload() {
+	ebegin "Reloading $name"
+	supervise-daemon $RC_SVCNAME --signal USR2
+	eend $?
+}
+
+start_pre() {
+	checkpath -d -o maddy:maddy /run/maddy
+}
diff --git a/testing/maddy/maddy.pre-install b/testing/maddy/maddy.pre-install
new file mode 100644
index 0000000000000000000000000000000000000000..936044c0d4542163ac2766d4bd5e372c164e5e30
--- /dev/null
+++ b/testing/maddy/maddy.pre-install
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+addgroup -S maddy 2>/dev/null
+adduser -S -D -h /var/lib/maddy -s /sbin/nologin -G maddy -g maddy maddy 2>/dev/null
+
+exit 0
diff --git a/testing/maddy/use-syslog.patch b/testing/maddy/use-syslog.patch
new file mode 100644
index 0000000000000000000000000000000000000000..b3ed70bdad9946053b17de361b5f51d084d2c9a0
--- /dev/null
+++ b/testing/maddy/use-syslog.patch
@@ -0,0 +1,14 @@
+Reason: Use syslog for logging
+Upstream: No
+
+--- a/maddy.conf
++++ b/maddy.conf
+@@ -169,3 +169,8 @@ imap tls://0.0.0.0:993 tcp://0.0.0.0:143 {
+     auth &local_authdb
+     storage &local_mailboxes
+ }
++
++# ----------------------------------------------------------------------------
++# Logging
++
++log syslog