From 5ceec760b9b4fa97d883cd79cf46dc32cfac5070 Mon Sep 17 00:00:00 2001 From: Paul Jimenez Date: Fri, 2 May 2014 09:35:21 -0400 Subject: [PATCH 1/4] Better Dockerfile support --- containers/docker/Dockerfile | 29 +++++++++------ containers/docker/setup_services.sh | 58 +++++++++++++++++++++++++++++ containers/docker/start_services.sh | 12 ------ 3 files changed, 75 insertions(+), 24 deletions(-) create mode 100644 containers/docker/setup_services.sh delete mode 100644 containers/docker/start_services.sh diff --git a/containers/docker/Dockerfile b/containers/docker/Dockerfile index 80cb2a4c..8c04c4f9 100644 --- a/containers/docker/Dockerfile +++ b/containers/docker/Dockerfile @@ -6,7 +6,11 @@ # sudo docker.io build -t box . # sudo docker.io run -i -t box -FROM ubuntu:14.04 +# Revert to phusion's baseimage once they upgrade to Ubuntu 14.04 +#FROM phusion/baseimage: +# For now use an upgraded image provided by pjz, based on his +# a PR: https://github.com/phusion/baseimage-docker/pull/64 +FROM pjzz/phusion-baseimage:0.9.10 MAINTAINER Joshua Tauberer (http://razor.occams.info) ENV PUBLIC_HOSTNAME box.local @@ -16,19 +20,20 @@ ENV PUBLIC_HOSTNAME box.local # host forward its port 53 (TCP/UDP) traffic to the docker container. # Since we can't get the host's IP address here, we'll set this to # a dummy value. -ENV PUBLIC_IP 127.0.123.123 +ENV PUBLIC_IP 127.0.122.123 -# Our install will fail if SSH is installed and allows password-based authentication. -RUN apt-get install -q -y openssh-server -RUN sed -i /etc/ssh/sshd_config -e "s/^#PasswordAuthentication yes/PasswordAuthentication no/g" -RUN service ssh restart +# Turn off password-based authentication; for ssh access see the phusion-baseimage docs +RUN sed -i 's/^#\s*\(PasswordAuthentication no\)/\1/' /etc/ssh/sshd_config -# Start our setup. -RUN apt-get install -q -y git +# install some tools to install mailinabox +RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -q -y git ca-certificates wget && apt-get clean + +# actually install mailinabox RUN git clone https://github.com/joshdata/mailinabox -RUN cd mailinabox; scripts/start.sh +RUN cd mailinabox && scripts/start.sh + +# configure mailinabox services +ADD setup_services.sh /usr/local/bin/setup_services.sh +RUN bash /usr/local/bin/setup_services.sh -# Launch configuration. -ADD start_services.sh /usr/local/bin/start_services.sh -CMD bash /usr/local/bin/start_services.sh EXPOSE 22 25 53 443 587 993 diff --git a/containers/docker/setup_services.sh b/containers/docker/setup_services.sh new file mode 100644 index 00000000..eb8a6ec5 --- /dev/null +++ b/containers/docker/setup_services.sh @@ -0,0 +1,58 @@ +#!/bin/bash +echo "Setting up Mail-in-a-Box services..." + +SERVICES="nsd postfix dovecot opendkim nginx php-fastcgi" + +for service in $SERVICES; do + mkdir -p /etc/service/$service +done + +cat </etc/service/nsd/run +#!/bin/sh +exec /usr/bin/nsd -d +EORUN + +cat </etc/service/postfix/run +#!/bin/sh +# from http://smarden.org/runit/runscripts.html#postfix +exec 1>&2 + +daemon_directory=/usr/lib/postfix \ + command_directory=/usr/sbin \ + config_directory=/etc/postfix \ + queue_directory=/var/spool/postfix \ + mail_owner=postfix \ + setgid_group=postdrop \ + /etc/postfix/postfix-script check || exit 1 + +exec /usr/lib/postfix/master +EORUN + +cat </etc/service/dovecot/run +#!/bin/sh +exec dovecot +EORUN + +cat </etc/service/opendkim/run +#!/bin/sh +exec opendkim -f -x /etc/opendkim.conf -u opendkim -P /var/run/opendkim/opendkim.pid +EORUN + +echo "daemon off;" >> /etc/nginx/nginx.conf +cat </etc/service/nginx/run +#!/bin/sh +exec nginx +EORUN + +cat </etc/service/php-fastcgi/run +#!/bin/bash +export PHP_FCGI_CHILDREN=4 PHP_FCGI_MAX_REQUESTS=1000 +exec /usr/bin/php-cgi -q -b /tmp/php-fastcgi.www-data.sock -c /etc/php5/cgi/php.ini +EORUN + +for service in $SERVICES; do + chmod a+x /etc/service/$service/run +done + +echo "Your Mail-in-a-Box services are configured." + diff --git a/containers/docker/start_services.sh b/containers/docker/start_services.sh deleted file mode 100644 index 137b9c8e..00000000 --- a/containers/docker/start_services.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -echo "Starting Mail-in-a-Box services..." - -service nsd start -service postfix start -dovecot # it's integration with Upstart doesn't work in docker -service opendkim start -service nginx start -service php-fastcgi start - -echo "Your Mail-in-a-Box is running." -bash From fbd7d731e88c3edf50604dc23b5c40551d8d580b Mon Sep 17 00:00:00 2001 From: Joshua Tauberer Date: Tue, 6 May 2014 09:56:20 -0400 Subject: [PATCH 2/4] docker: fix startup scripts for nsd and dovecot to run them in the foreground --- containers/docker/setup_services.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/containers/docker/setup_services.sh b/containers/docker/setup_services.sh index eb8a6ec5..650b54c0 100755 --- a/containers/docker/setup_services.sh +++ b/containers/docker/setup_services.sh @@ -9,7 +9,7 @@ done cat </etc/service/nsd/run #!/bin/sh -exec /usr/bin/nsd -d +exec /usr/sbin/nsd -d EORUN cat </etc/service/postfix/run @@ -30,7 +30,7 @@ EORUN cat </etc/service/dovecot/run #!/bin/sh -exec dovecot +exec dovecot -F EORUN cat </etc/service/opendkim/run From 1db0dd3092aaa642d05b1d0c3dd8b0c389a63168 Mon Sep 17 00:00:00 2001 From: Joshua Tauberer Date: Tue, 6 May 2014 09:57:11 -0400 Subject: [PATCH 3/4] system.sh: make apt-get upgrade quieter --- scripts/system.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system.sh b/scripts/system.sh index 76e33d2d..68826e5e 100755 --- a/scripts/system.sh +++ b/scripts/system.sh @@ -2,8 +2,8 @@ source scripts/functions.sh # load our functions # Base system configuration. -apt-get -q -q update -apt-get -q -y upgrade +apt-get -qq update +apt-get -qq -y upgrade # Install openssh-server to ensure that the end result is consistent across all Mail-in-a-Boxes. apt_install openssh-server From e247929386b057860da551e1c134a281178e20a7 Mon Sep 17 00:00:00 2001 From: Joshua Tauberer Date: Tue, 6 May 2014 09:59:53 -0400 Subject: [PATCH 4/4] docker: don't start services ourself * let the base image's system services manager handle it * move our container start script to occur before system services are started --- Dockerfile | 18 ++++++++---------- containers/docker/container_start.sh | 25 ++++--------------------- scripts/start.sh | 11 +++++++++++ 3 files changed, 23 insertions(+), 31 deletions(-) diff --git a/Dockerfile b/Dockerfile index 45f14daf..8f315389 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,14 +5,10 @@ # To build the image: # sudo docker.io build -t box . -# Run your container the first time with an interactive console so you can -# create your first mail account. -# sudo docker.io run -i -t box - -# Then run it in the background and expose all of the ports so that the *host* acts as a Mail-in-a-Box: -# (the SSH port is only available locally, but other ports are exposed publicly and must be available -# otherwise the container won't start) -# sudo docker.io run -d -p 22 -p 25:25 -p 53:53/udp -p 443:443 -p 587:587 -p 993:993 box +# Run your container. +# -i -t: creates an interactive console so you can poke around (CTRL+D will terminate the container) +# -p ...: Maps container ports to host ports so that the host begins acting as a Mail-in-a-Box. +# sudo docker.io run -i -t -p 22 -p 25:25 -p 53:53/udp -p 443:443 -p 587:587 -p 993:993 box ########################################### @@ -43,6 +39,7 @@ ENV PUBLIC_IP 192.168.200.1 # Docker-specific Mail-in-a-Box configuration. ENV DISABLE_FIREWALL 1 +ENV NO_RESTART_SERVICES 1 # Our install will fail if SSH is installed and allows password-based authentication. # The base image already installs openssh-server. Just edit its configuration. @@ -59,6 +56,7 @@ RUN cd /usr/local/mailinabox && scripts/start.sh # Configure services for docker. ADD containers/docker /usr/local/mailinabox/containers/docker RUN /usr/local/mailinabox/containers/docker/setup_services.sh +RUN ln -s /usr/local/mailinabox/containers/docker/container_start.sh /etc/my_init.d/99-mailinabox.sh -# How the container is launched. -CMD bash /usr/local/mailinabox/containers/docker/container_start.sh +# Start bash so we can poke around. +CMD ["/sbin/my_init", "--", "bash"] diff --git a/containers/docker/container_start.sh b/containers/docker/container_start.sh index cb13d0ff..ce46e0a3 100755 --- a/containers/docker/container_start.sh +++ b/containers/docker/container_start.sh @@ -15,27 +15,10 @@ if grep "^PUBLIC_IP=192.168.200.1" /etc/mailinabox.conf > /dev/null; then export PUBLIC_HOSTNAME=`host $PUBLIC_IP | sed -e "s/.* //" | sed -e "s/\.$//"` echo Your hostname is $PUBLIC_HOSTNAME. - # Start configuration again. + # Start configuration again. Hide the terminal. The system services + # have not been started yet, so we can't ask the user to create an + # account yet. cd /usr/local/mailinabox - scripts/start.sh + scripts/start.sh < /dev/null fi -if [ -t 0 ] -then - # This is an interactive shell. You get a command prompt within - # the container. - # - # You get here by running 'docker run -i -t'. - - echo "Welcome to your Mail-in-a-Box." - bash - -else - # This is a non-interactive shell. Just display status. Because - # other services are running, the container remains running after - # this script exits. - # - # You get here by omitting '-t' from the docker run arguments. - - echo "Your Mail-in-a-Box is running..." -fi diff --git a/scripts/start.sh b/scripts/start.sh index e963b071..71267c92 100755 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -52,6 +52,17 @@ PUBLIC_HOSTNAME=$PUBLIC_HOSTNAME PUBLIC_IP=$PUBLIC_IP EOF +# For docker, we don't want any of our scripts to start daemons. +# Mask the 'service' program by defining a function of the same name +# so that whenever we try to restart a service we just silently do +# nothing. +if [ "$NO_RESTART_SERVICES" == "1" ]; then + function service { + # we could output some status, but it's not important + echo skipping service $@ > /dev/null; + } +fi + # Start service configuration. . scripts/system.sh . scripts/dns.sh