diff --git a/Dockerfile b/Dockerfile index 17f625040fb08f5aa5cda4c209a4e5aed580769f..be53c31902b6acbee7f0ea3b2fe2c232bb00ac8f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,8 +9,10 @@ RUN go build -o smtpd smtpd.go FROM registry.git.autistici.org/ai3/docker/apache2-base:master COPY start.sh /start.sh COPY build.sh /tmp/build.sh +COPY ai-lurker-ui.patch /tmp/ai-lurker-ui.patch COPY conf/ /etc/ COPY --from=build /go/src/smtpd /usr/bin/smtpd -RUN /tmp/build.sh && rm /tmp/build.sh +RUN /tmp/build.sh && rm /tmp/build.sh /tmp/ai-lurker-ui.patch +COPY logo.png /var/lib/lurker-www-orig/logo.png ENTRYPOINT ["/usr/local/bin/chaperone"] diff --git a/README.md b/README.md index 0db655fe63552624b3ab6ec10afff290d5ec987c..0607386ebf37995a84d612d7f988df6a4d82f923 100644 --- a/README.md +++ b/README.md @@ -8,3 +8,26 @@ instead of using two separate container images. Configuration and data storage must be mounted respectively in */etc/lurker* and */var/lib/lurker*. +Instead of running a full-blown Postfix instance, this container runs +a very simple [SMTP server](smtpd.go) that is only suitable for internal +traffic. + +The image expects /var/lib/lurker to be mounted externally with the +right permissions, and to contain the *www* and *data* subdirectories. + +## Environment variables + +* `DOMAIN`: domain for the HTTP website, minus the *lists* prefix +* `APACHE_PORT`: port for the HTTP service +* `SMTP_PORT`: port for the SMTP service +* `SMTP_EHLO_HOSTNAME`: hostname to use for SMTP EHLO +* `LURKER_ADDR_RX`: regular expression to match SMTP recipients and + extract the list name from it. It should include a single regexp + group (the list name). The default handles plus-extension addresses + using the *lurker* username (`lurker\\+([^@]+)@.*`), but it is + recommended to extend it to match the expected domain name as well. +* `LURKER_DATA_DIR`: data directory for Lurker (default */var/lib/lurker/data*). + +When Lurker is performing maintenance on its database, incoming +SMTP reception is temporarily suspended. + diff --git a/ai-lurker-ui.patch b/ai-lurker-ui.patch new file mode 100644 index 0000000000000000000000000000000000000000..e5345420c1c6fc3d6f73f3edb2afc262422ebc33 --- /dev/null +++ b/ai-lurker-ui.patch @@ -0,0 +1,169 @@ +diff -urN ui_/common.xsl ui/common.xsl +--- ui_/common.xsl 2016-12-20 12:02:51.000000000 +0000 ++++ ui/common.xsl 2017-09-16 13:59:48.788481408 +0000 +@@ -313,7 +313,7 @@ + <xsl:template name="navbar"> + <table> + <tr> +- <td><xsl:call-template name="link-to-top"/></td> ++ <td></td> + <td nowrap="NOWRAP"><xsl:call-template name="language-dropdown"/></td> + </tr> + </table> +diff -urN ui_/default.css ui/default.css +--- ui_/default.css 2016-12-20 12:02:51.000000000 +0000 ++++ ui/default.css 2017-09-16 13:59:48.428473648 +0000 +@@ -1,9 +1,9 @@ + body { + padding: 0px; +- margin: 0px; +- background-color: #BBF; ++ margin: 5px; ++ background-color: #FFF; + color: black; +- font-family: serif; ++ font-family: Arial, Helvetica, sans-serif; + } + + form { +@@ -11,13 +11,13 @@ + } + + div.header { +- background-color: #BBF; ++ background-color: #FFF; + padding: 4px 0.25em 0.25em 0.25em; +- border-bottom: 1px solid #434399; + } + + div.footer { +- background-color: #BBF; ++display: none; ++ background-color: #FFF; + padding: 0.25em 0.25em 1px 0.25em; + border-top: 1px solid #434399; + } +@@ -57,8 +57,8 @@ + font-size: 100%; + } + +-a:link { color:#11F } +-a:visited { color:#00B } ++a:link { color:#000 } ++a:visited { color:#000 } + a:hover { color:#F00 } + a:active { color:#A00 } + h1 a:visited { color:#11F } +@@ -113,7 +113,7 @@ + tr.lit { background-color:#77F } /* even rows in mindex/thread/search tables */ + tr.row1 { background-color:#DDD } /* even rows in mindex/thread/search tables */ + tr.row2 { background-color:#EEE } /* odd rows in mindex/thread/search tables */ +-tr.rowover { background-color:#CAC } /* active (= mouseOver) rows in mindex/thread/search tables */ ++tr.rowover { background-color:#FFF } /* active (= mouseOver) rows in mindex/thread/search tables */ + + div.body { + padding: 1em; +@@ -171,7 +171,7 @@ + table.navigation { + width: 100%; + font-size: 80%; +- background-color: #e8e8e8; ++ background-color: #FFF; + + /* disabled until mozilla fixes the progressive render bug with images + border-top: 1px solid #969696; +@@ -183,7 +183,7 @@ + + table.navigation th { + font-size: 100%; +- background-color: #969696; ++ background-color: #FFF; + padding: 3px; + } + +@@ -214,10 +214,13 @@ + } + + ul { ++ list-style-type: none; + margin-bottom: 0em; + margin-top: 0em; + } + ++li { padding: 1px; } ++ + h1.group { + margin: 0px; + } +@@ -309,3 +312,7 @@ + .url { } /* "url" elements used inside of message's mime contents */ + .quote { } /* "quote" elements used inside of message's mime contents */ + .art { margin: 0em; } /* "art" elements used inside of message's mime contents */ ++ ++ ++input { padding: 3px; font-size: 12px; margin: 1px; border: 1px solid #CCC; } ++select { padding: 3px; font-size: 10px; margin: 1px; border: 1px solid #CCC; } +diff -urN ui_/list.xsl ui/list.xsl +--- ui_/list.xsl 2016-12-20 12:02:51.000000000 +0000 ++++ ui/list.xsl 2017-09-16 13:59:48.476474682 +0000 +@@ -107,7 +107,7 @@ + </table> + + <table class="navigation"> +- <tr><th align="left" colspan="2"><xsl:value-of select="$jump-to-date"/></th></tr> ++ <tr><th align="left" colspan="2"></th></tr> + <tr> + <td> + <!-- make this the same height as mindex --> +diff -urN ui_/message.xsl ui/message.xsl +--- ui_/message.xsl 2016-12-20 12:02:51.000000000 +0000 ++++ ui/message.xsl 2017-09-16 13:59:48.280470457 +0000 +@@ -274,7 +274,7 @@ + <img src="../imgs/trash.png" alt="{$delete-message}" title="{$delete-message}"/> + </a> + <xsl:if test="mbox/list/email/@address"> +- <br/><xsl:call-template name="reply-link"/> ++ <br/><br/><xsl:call-template name="reply-link"/> + </xsl:if> + </td> + </tr></table> +diff -urN ui_/mindex.xsl ui/mindex.xsl +--- ui_/mindex.xsl 2016-12-20 12:02:51.000000000 +0000 ++++ ui/mindex.xsl 2017-09-16 13:59:48.692479338 +0000 +@@ -62,7 +62,7 @@ + </table> + + <table class="navigation"> +- <tr><th align="left" colspan="3"><xsl:value-of select="$jump-to-date"/></th></tr> ++ <tr><th align="left" colspan="3"></th></tr> + <tr> + <td> + <xsl:choose> +diff -urN ui_/splash.xsl ui/splash.xsl +--- ui_/splash.xsl 2016-12-20 12:02:51.000000000 +0000 ++++ ui/splash.xsl 2017-09-16 13:59:48.548476235 +0000 +@@ -39,7 +39,7 @@ + </xsl:otherwise> + </xsl:choose> + <xsl:text> — </xsl:text> +- <i><xsl:value-of select="description"/></i> ++ <xsl:value-of select="description"/> + </li> + <xsl:text> </xsl:text> + </xsl:template> +@@ -75,13 +75,13 @@ + <div class="header"> + <table class="external"> + <tr> +- <td align="left"><h1><xsl:value-of select="server/archive"/></h1></td> ++ <td align="left"><img src="/logo.png"/></td> + <td align="right"><xsl:call-template name="navbar"/></td> + </tr> + </table> + + <table class="navigation"> +- <tr><th align="left"><xsl:value-of select="$search-menu"/></th></tr> ++ <tr><th align="left"></th></tr> + <tr><td nowrap="NOWRAP" align="center"> + <form action="{server/cgi-url}/keyword.cgi" accept-charset="UTF-8" onsubmit="form_timezone(this)"> + <input type="hidden" name="doc-url" value="{server/doc-url}"/> diff --git a/build.sh b/build.sh index 6b12278a2dca2c83e04840d0cbece64efd00729f..7269705581611d3941910ad68cbd68360b1b87d4 100755 --- a/build.sh +++ b/build.sh @@ -3,9 +3,12 @@ # Install script for Lurker inside a Docker container. # +BUILD_PACKAGES=" + patch +" + PACKAGES=" lurker - python3-aiosmtpd " install_packages() { @@ -20,10 +23,8 @@ die() { set -x # Install packages (aiosmtpd comes from backports in stretch). -echo "deb http://deb.debian.org/debian stretch-backports main" \ - > /etc/apt/sources.list.d/backports.list apt-get -q update -install_packages ${PACKAGES} \ +install_packages ${BUILD_PACKAGES} ${PACKAGES} \ || die "could not install packages" # Enable the apache modules we need. @@ -39,15 +40,19 @@ mkdir -p /var/lib/lurker # so the original files would disappear "below" the mount. To # prevent this, we copy the files to a well-known location # beforehand, and set up links at run-time. -mkdir -p /var/lib/lurker-www -mv /etc/lurker/ui /var/lib/lurker-www/ui -mv /var/lib/lurker/www/index.html /var/lib/lurker-www/index.html +mkdir -p /var/lib/lurker-www-orig +mv /etc/lurker/ui /var/lib/lurker-www-orig/ui +mv /var/lib/lurker/www/index.html /var/lib/lurker-www-orig/index.html + +# Apply our UI patch. +(cd /var/lib/lurker-www-orig/ui && patch -p1 </tmp/ai-lurker-ui.patch) # Clear the existing default config # (this will be mounted externally). rm -fr /etc/lurker/* # Clean up. +apt-get --purge remove ${BUILD_PACKAGES} apt-get autoremove -y apt-get clean rm -fr /var/lib/apt/lists/* diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..064cb4f6ecccedb6608ac5e830118f0af7235d2b Binary files /dev/null and b/logo.png differ diff --git a/start.sh b/start.sh index 8a01ede77d05697c01116022077a6ac8801371ff..c4f2f3831a44101ed77069676774b1550060a5a2 100755 --- a/start.sh +++ b/start.sh @@ -1,7 +1,27 @@ #!/bin/sh +# +# Setup script for the Lurker Docker container. +# +# Since /var/lib/lurker is mounted externally, ensure that it +# has the required structure, and that all the contents that +# were originally installed by the lurker package in those +# directories are correctly symlinked to $static_dir. +# +data_dir=/var/lib/lurker/data www_dir=/var/lib/lurker/www -static_dir=/var/lib/lurker-www +static_dir=/var/lib/lurker-www-orig + +umask 077 +set -e + +echo "Checking dirs..." >&2 + +mkdir -p ${data_dir} +mkdir -p ${www_dir} +for sub in attach list mbox message mindex search splash thread zap; do + mkdir -p ${www_dir}/${sub} +done echo "Fixing symlinks..." >&2 @@ -18,4 +38,11 @@ if [ ! -e ${www_dir}/lurker.docroot ]; then touch ${www_dir}/lurker.docroot fi +# The logo.png symlink switches between custom / builtin. +logo_src=${static_dir}/logo.png +if [ -e /etc/lurker/logo.png ]; then + logo_src=/etc/lurker/logo.png +fi +ln -sf ${logo_src} ${www_dir}/logo.png + exit 0