From 4eb9af2ebdd7d1e690838e655f24943f1c1c5458 Mon Sep 17 00:00:00 2001 From: Joshua Tauberer Date: Fri, 30 Jan 2015 17:40:58 -0500 Subject: [PATCH] simplify dockerization --- Dockerfile | 10 +- containers/docker/apt_package_list.txt | 1 - containers/docker/init.sh | 98 +++++++++++-------- containers/docker/{run.sh => run} | 57 ++++++++--- .../docker/runit}/dovecot.sh | 0 .../docker/runit}/rsyslogd.sh | 0 services/bind9.sh | 11 --- services/fail2ban.sh | 9 -- services/mailinabox.sh | 12 --- services/memcached.sh | 10 -- services/nginx.sh | 10 -- services/nsd.sh | 10 -- services/opendkim.sh | 10 -- services/php5-fpm.sh | 10 -- services/postfix.sh | 10 -- services/postgrey.sh | 10 -- services/spampd.sh | 10 -- setup/functions.sh | 23 ++++- setup/start.sh | 11 ++- 19 files changed, 131 insertions(+), 181 deletions(-) rename containers/docker/{run.sh => run} (52%) rename {services => containers/docker/runit}/dovecot.sh (100%) rename {services => containers/docker/runit}/rsyslogd.sh (100%) delete mode 100755 services/bind9.sh delete mode 100755 services/fail2ban.sh delete mode 100755 services/mailinabox.sh delete mode 100755 services/memcached.sh delete mode 100755 services/nginx.sh delete mode 100755 services/nsd.sh delete mode 100755 services/opendkim.sh delete mode 100755 services/php5-fpm.sh delete mode 100755 services/postfix.sh delete mode 100755 services/postgrey.sh delete mode 100755 services/spampd.sh diff --git a/Dockerfile b/Dockerfile index 74ec64b4..3663649c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -35,18 +35,20 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get upgrade -y # Install packages needed by Mail-in-a-Box. ADD containers/docker/apt_package_list.txt /tmp/mailinabox_apt_package_list.txt RUN DEBIAN_FRONTEND=noninteractive apt-get install -y $(cat /tmp/mailinabox_apt_package_list.txt) +RUN DEBIAN_FRONTEND=noninteractive apt-get install -y rsyslog RUN rm -f /tmp/mailinabox_apt_package_list.txt +RUN apt-get clean + +# Create the user-data user, so the start script doesn't have to. RUN useradd -m user-data -RUN rm -rf /etc/service/syslog-ng # Now add Mail-in-a-Box to the system. ADD . /usr/local/mailinabox -#RUN /usr/local/mailinabox/containers/docker/setup.sh - # We can't know things like the IP address where the container will eventually # be deployed until the container is started. We also don't want to create any # private keys during the creation of the image --- that should wait until the # container is started too. So our whole setup process is deferred until the # container is started. -ENTRYPOINT /usr/local/mailinabox/containers/docker/init.sh +RUN mkdir -p /etc/my_init.d +RUN ln -s /usr/local/mailinabox/containers/docker/init.sh /etc/my_init.d/20-mailinabox.sh diff --git a/containers/docker/apt_package_list.txt b/containers/docker/apt_package_list.txt index 8ac6ebdf..de1cad43 100644 --- a/containers/docker/apt_package_list.txt +++ b/containers/docker/apt_package_list.txt @@ -76,7 +76,6 @@ python3-pip pyzor razor resolvconf -rsyslog spampd sqlite3 sudo diff --git a/containers/docker/init.sh b/containers/docker/init.sh index aea2ef3d..8f7e377e 100755 --- a/containers/docker/init.sh +++ b/containers/docker/init.sh @@ -17,51 +17,63 @@ if [ ! -t 0 ]; then export NONINTERACTIVE=1 fi -# Start configuration. +# The phusion/baseimage base image we use for a working Ubuntu +# replaces the normal Upstart system service management with +# a ligher-weight service management system called runit that +# requires a different configuration. We need to create service +# run files that do not daemonize. + +# For most of the services, there is a common pattern we can use: +# execute the init.d script that the Ubuntu package installs, and +# then poll for the termination of the daemon. +function make_runit_service { + INITD_NAME=$1 + WAIT_ON_PROCESS_NAME=$2 + mkdir -p /etc/service/$INITD_NAME + cat > /etc/service/$INITD_NAME/run < /dev/null; then - echo Starting user-data volume container... - $DOCKER run -d \ +tput setaf 2 +echo "Building/updating base image (mailinabox)..." +tput setaf 7 + +docker build -q -t mailinabox . + +if ! docker ps -a | grep mailinabox-userdata > /dev/null; then + tput setaf 2 + echo + echo "Creating a new container for your data (mailinabox-userdata)..." + tput setaf 7 + + docker run -d \ --name mailinabox-userdata \ -v /home/user-data \ - scratch /bin/bash + scratch /bin/does-not-exist-but-thats-ok +else + tput setaf 2 + echo + echo "Using existing container mailinabox-userdata for your data." + tput setaf 7 fi # End a running container. -if $DOCKER ps -a | grep mailinabox-services > /dev/null; then - echo Deleting container... - $DOCKER rm mailinabox-services + +if docker ps -a | grep mailinabox-services > /dev/null; then + tput setaf 2 + echo + echo "Destroying mailinabox-services container..." + tput setaf 7 + + docker rm -f mailinabox-services fi # Start container. -echo Starting new container... -$DOCKER run \ + +tput setaf 2 +echo +echo "Starting new container (mailinabox-services)..." +tput setaf 7 + +# Notes: +# * Passing through SKIP_NETWORK_CHECKS makes it easier to do testing +# on a residential network. + +docker run \ --privileged \ -v /dev/urandom:/dev/random \ -p 25 -p 53/udp -p 53/tcp -p 80 -p 443 -p 587 -p 993 \ --name mailinabox-services \ --volumes-from mailinabox-userdata \ - mailinabox \ No newline at end of file + -e "SKIP_NETWORK_CHECKS=$SKIP_NETWORK_CHECKS" \ + mailinabox diff --git a/services/dovecot.sh b/containers/docker/runit/dovecot.sh similarity index 100% rename from services/dovecot.sh rename to containers/docker/runit/dovecot.sh diff --git a/services/rsyslogd.sh b/containers/docker/runit/rsyslogd.sh similarity index 100% rename from services/rsyslogd.sh rename to containers/docker/runit/rsyslogd.sh diff --git a/services/bind9.sh b/services/bind9.sh deleted file mode 100755 index a962510b..00000000 --- a/services/bind9.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -EXEC=bind9 -PROCESS=named - -/etc/init.d/$EXEC start - -while [ `ps -C $PROCESS -o pid= | wc -l` -gt 0 ]; do - sleep 30 -done - diff --git a/services/fail2ban.sh b/services/fail2ban.sh deleted file mode 100755 index 3a5720e4..00000000 --- a/services/fail2ban.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -PROCESS=fail2ban - -/etc/init.d/$PROCESS start - -while [ `ps aux | grep fail2ban | grep -v grep | wc -l` -gt 0 ]; do - sleep 30 -done diff --git a/services/mailinabox.sh b/services/mailinabox.sh deleted file mode 100755 index 2ed281c9..00000000 --- a/services/mailinabox.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -EXEC=mailinabox -PROCESS=mailinabox-daemon - -if [ `ps aux | grep $PROCESS | grep -v grep | wc -l` -eq 0 ]; then - /etc/init.d/$EXEC start -fi - -while [ `ps aux | grep $PROCESS | grep -v grep | wc -l` -gt 0 ]; do - sleep 30 -done diff --git a/services/memcached.sh b/services/memcached.sh deleted file mode 100755 index 823997f1..00000000 --- a/services/memcached.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -PROCESS=memcached - -/etc/init.d/$PROCESS start - -while [ `ps -C $PROCESS -o pid= | wc -l` -gt 0 ]; do - sleep 60 -done - diff --git a/services/nginx.sh b/services/nginx.sh deleted file mode 100755 index ea73ae92..00000000 --- a/services/nginx.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -PROCESS=nginx - -/etc/init.d/$PROCESS start - -while [ `ps -C $PROCESS -o pid= | wc -l` -gt 0 ]; do - sleep 30 -done - diff --git a/services/nsd.sh b/services/nsd.sh deleted file mode 100755 index 392215d4..00000000 --- a/services/nsd.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -PROCESS=nsd - -/etc/init.d/$PROCESS start - -while [ `ps -C $PROCESS -o pid= | wc -l` -gt 0 ]; do - sleep 30 -done - diff --git a/services/opendkim.sh b/services/opendkim.sh deleted file mode 100755 index a3a76eb2..00000000 --- a/services/opendkim.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -PROCESS=opendkim - -/etc/init.d/$PROCESS start - -while [ `ps -C $PROCESS -o pid= | wc -l` -gt 0 ]; do - sleep 30 -done - diff --git a/services/php5-fpm.sh b/services/php5-fpm.sh deleted file mode 100755 index e00987a8..00000000 --- a/services/php5-fpm.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -PROCESS=php5-fpm - -/etc/init.d/$PROCESS start - -while [ `ps -C $PROCESS -o pid= | wc -l` -gt 0 ]; do - sleep 30 -done - diff --git a/services/postfix.sh b/services/postfix.sh deleted file mode 100755 index 18755980..00000000 --- a/services/postfix.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -PROCESS=postfix - -/etc/init.d/$PROCESS start - -while [ `ps aux | grep $PROCESS | grep -v grep | wc -l` -gt 0 ]; do - sleep 30 -done - diff --git a/services/postgrey.sh b/services/postgrey.sh deleted file mode 100755 index 7a052f0d..00000000 --- a/services/postgrey.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -PROCESS=postgrey - -/etc/init.d/$PROCESS start - -while [ `ps aux | grep $PROCESS | grep -v grep | wc -l` -gt 0 ]; do - sleep 30 -done - diff --git a/services/spampd.sh b/services/spampd.sh deleted file mode 100755 index a9fd4393..00000000 --- a/services/spampd.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -PROCESS=spampd - -/etc/init.d/$PROCESS start - -while [ `ps -C $PROCESS -o pid= | wc -l` -gt 0 ]; do - sleep 30 -done - diff --git a/setup/functions.sh b/setup/functions.sh index 4ae8e090..07a3af8f 100644 --- a/setup/functions.sh +++ b/setup/functions.sh @@ -39,9 +39,14 @@ function apt_get_quiet { } function apt_install { - if [ ! "$IS_DOCKER" ];then - # Report any packages already installed. PACKAGES=$@ + + if [ ! -z "$IS_DOCKER" ]; then + # Speed things up because packages are already installed by the image. + PACKAGES="" + fi + + # Report any packages already installed. TO_INSTALL="" ALREADY_INSTALLED="" for pkg in $PACKAGES; do @@ -163,10 +168,18 @@ function ufw_allow { function restart_service { # Restart a service quietly. - if [ ! "$IS_DOCKER" ]; then - # The normal way to restart a service. - hide_output service $1 restart + + if [[ ! -z "$IS_DOCKER" && "$1" == "dovecot" ]]; then + # In Docker, sysvinit takes care of any services with an init.d + # script. The dovecot package provides an Upstart config only, + # and so it won't work this way. We make a new script for it + # elsewhere. We also cant do `sv restart dovecot` because runit + # is not running until after the setup scripts are run. So we + # will have to skip starting dovecot for now. + return 0 fi + + hide_output service $1 restart } ## Dialog Functions ## diff --git a/setup/start.sh b/setup/start.sh index df753d0c..57049b3f 100755 --- a/setup/start.sh +++ b/setup/start.sh @@ -102,6 +102,14 @@ source setup/zpush.sh source setup/management.sh source setup/munin.sh +# In Docker, sysvinit services are started automatically. Runit services +# aren't started until after this setup script finishes. But we need +# Dovecot (which is Upstart-only) running in order to create the first +# mail user. So start dovecot now. +if [ ! -z "$IS_DOCKER" ]; then + /usr/sbin/dovecot -c /etc/dovecot/dovecot.conf +fi + # Ping the management daemon to write the DNS and nginx configuration files. until nc -z -w 4 localhost 10222 do @@ -139,5 +147,4 @@ openssl x509 -in $STORAGE_ROOT/ssl/ssl_certificate.pem -noout -fingerprint \ | sed "s/SHA1 Fingerprint=//" echo echo Then you can confirm the security exception and continue. -echo - +echo \ No newline at end of file