mirror of
				https://github.com/mail-in-a-box/mailinabox.git
				synced 2025-11-03 19:30:54 +00:00 
			
		
		
		
	more dockerization work
[From @joshdata: This is part of @toilal's work in #377 and 1eb77c332b. The changes are:
* Separates out the runit configuration from starting Mail-in-a-Box setup so that Mail-in-a-Box setup does not block the starting of runit services and we can assume that runit is running during setup (i.e. we can restart services).
* Adds a SKIP_INSTALL flag so that the container can be restarted without re-running the whole Mail-in-a-Box setup.
* Made containers/docker/run more flexible.
* I'm also adding some "|| exit 0"s to the run script to stop if there are any docker errors.
* I'm also adding the prereqs installs from questions.sh into Dockerfile so we don't have to reinstall each time.
]
			
			
This commit is contained in:
		
							parent
							
								
									4eb9af2ebd
								
							
						
					
					
						commit
						e004041de2
					
				
							
								
								
									
										31
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								Dockerfile
									
									
									
									
									
								
							@ -19,8 +19,15 @@ FROM phusion/baseimage:0.9.16
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Dockerfile metadata.
 | 
					# Dockerfile metadata.
 | 
				
			||||||
MAINTAINER Joshua Tauberer (http://razor.occams.info)
 | 
					MAINTAINER Joshua Tauberer (http://razor.occams.info)
 | 
				
			||||||
EXPOSE 25 53/udp 53/tcp 80 443 587 993
 | 
					EXPOSE 25 53/udp 53/tcp 80 443 587 993 4190
 | 
				
			||||||
VOLUME /data
 | 
					VOLUME /home/user-data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Use baseimage's init system. A correct init process is required for
 | 
				
			||||||
 | 
					# process #1 in order to have a functioning Linux system.
 | 
				
			||||||
 | 
					CMD ["/sbin/my_init"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Create the user-data user, so the start script doesn't have to.
 | 
				
			||||||
 | 
					RUN useradd -m user-data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Docker has a beautiful way to cache images after each step. The next few
 | 
					# Docker has a beautiful way to cache images after each step. The next few
 | 
				
			||||||
# steps of installing system packages are very intensive, so we take care
 | 
					# steps of installing system packages are very intensive, so we take care
 | 
				
			||||||
@ -35,20 +42,16 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get upgrade -y
 | 
				
			|||||||
# Install packages needed by Mail-in-a-Box.
 | 
					# Install packages needed by Mail-in-a-Box.
 | 
				
			||||||
ADD containers/docker/apt_package_list.txt /tmp/mailinabox_apt_package_list.txt
 | 
					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 $(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.
 | 
					# from questions.sh -- needs merging into the above line
 | 
				
			||||||
RUN useradd -m user-data
 | 
					RUN DEBIAN_FRONTEND=noninteractive apt-get install -y dialog python3 python3-pip
 | 
				
			||||||
 | 
					RUN pip3 install "email_validator==0.1.0-rc4"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Now add Mail-in-a-Box to the system.
 | 
					# Now add Mail-in-a-Box to the system.
 | 
				
			||||||
ADD . /usr/local/mailinabox
 | 
					ADD . /usr/local/mailinabox
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# We can't know things like the IP address where the container will eventually
 | 
					# Configure runit services.
 | 
				
			||||||
# be deployed until the container is started. We also don't want to create any
 | 
					RUN /usr/local/mailinabox/containers/docker/tools/configure_services.sh
 | 
				
			||||||
# 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
 | 
					# Add my_init scripts
 | 
				
			||||||
# container is started.
 | 
					ADD containers/docker/my_init.d/* /etc/my_init.d/
 | 
				
			||||||
RUN mkdir -p /etc/my_init.d
 | 
					 | 
				
			||||||
RUN ln -s /usr/local/mailinabox/containers/docker/init.sh /etc/my_init.d/20-mailinabox.sh
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -1,79 +0,0 @@
 | 
				
			|||||||
#!/bin/bash
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# This script is used within containers to turn it into a Mail-in-a-Box.
 | 
					 | 
				
			||||||
# It is referenced by the Dockerfile. You should not run it directly.
 | 
					 | 
				
			||||||
########################################################################
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Local configuration details were not known at the time the Docker
 | 
					 | 
				
			||||||
# image was created, so all setup is defered until the container
 | 
					 | 
				
			||||||
# is started. That's when this script runs.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# If we're not in an interactive shell, set defaults.
 | 
					 | 
				
			||||||
if [ ! -t 0 ]; then
 | 
					 | 
				
			||||||
	export PUBLIC_IP=auto
 | 
					 | 
				
			||||||
	export PUBLIC_IPV6=auto
 | 
					 | 
				
			||||||
	export PRIMARY_HOSTNAME=auto
 | 
					 | 
				
			||||||
	export CSR_COUNTRY=US
 | 
					 | 
				
			||||||
	export NONINTERACTIVE=1
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# 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 <<EOF;
 | 
					 | 
				
			||||||
#!/bin/bash
 | 
					 | 
				
			||||||
source /usr/local/mailinabox/setup/functions.sh
 | 
					 | 
				
			||||||
hide_output /etc/init.d/$INITD_NAME restart
 | 
					 | 
				
			||||||
while [ \`ps a -C $WAIT_ON_PROCESS_NAME -o pid= | wc -l\` -gt 0 ]; do
 | 
					 | 
				
			||||||
	sleep 30
 | 
					 | 
				
			||||||
done
 | 
					 | 
				
			||||||
echo $WAIT_ON_PROCESS_NAME died.
 | 
					 | 
				
			||||||
sleep 20
 | 
					 | 
				
			||||||
EOF
 | 
					 | 
				
			||||||
	chmod +x /etc/service/$INITD_NAME/run
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#make_runit_service bind9 named
 | 
					 | 
				
			||||||
#make_runit_service fail2ban fail2ban
 | 
					 | 
				
			||||||
#make_runit_service mailinabox mailinabox-daemon
 | 
					 | 
				
			||||||
#make_runit_service memcached memcached
 | 
					 | 
				
			||||||
#make_runit_service nginx nginx
 | 
					 | 
				
			||||||
#make_runit_service nsd nsd
 | 
					 | 
				
			||||||
#make_runit_service opendkim opendkim
 | 
					 | 
				
			||||||
#make_runit_service php5-fpm php5-fpm
 | 
					 | 
				
			||||||
#make_runit_service postfix postfix
 | 
					 | 
				
			||||||
#make_runit_service postgrey postgrey
 | 
					 | 
				
			||||||
#make_runit_service spampd spampd
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Dovecot doesn't provide an init.d script, but it does provide
 | 
					 | 
				
			||||||
# a way to launch without daemonization. We wrote a script for
 | 
					 | 
				
			||||||
# that specifically.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# We also want to use Ubuntu's stock rsyslog rather than syslog-ng
 | 
					 | 
				
			||||||
# that the base image provides. Our Dockerfile installs rsyslog.
 | 
					 | 
				
			||||||
rm -rf /etc/service/syslog-ng
 | 
					 | 
				
			||||||
for service in dovecot; do
 | 
					 | 
				
			||||||
	mkdir -p /etc/service/$service
 | 
					 | 
				
			||||||
	cp /usr/local/mailinabox/containers/docker/runit/$service.sh /etc/service/$service/run
 | 
					 | 
				
			||||||
	chmod +x /etc/service/$service/run
 | 
					 | 
				
			||||||
done
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Rsyslog isn't starting automatically but we need it during setup.
 | 
					 | 
				
			||||||
service rsyslog start
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Start configuration. Using 'source' means an exit from inside
 | 
					 | 
				
			||||||
# also exits this script and terminates the container.
 | 
					 | 
				
			||||||
cd /usr/local/mailinabox
 | 
					 | 
				
			||||||
export IS_DOCKER=1
 | 
					 | 
				
			||||||
export DISABLE_FIREWALL=1
 | 
					 | 
				
			||||||
source setup/start.sh
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										58
									
								
								containers/docker/my_init.d/10-mailinabox.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										58
									
								
								containers/docker/my_init.d/10-mailinabox.sh
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,58 @@
 | 
				
			|||||||
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This script is used within containers to turn it into a Mail-in-a-Box.
 | 
				
			||||||
 | 
					# It is referenced by the Dockerfile. You should not run it directly.
 | 
				
			||||||
 | 
					########################################################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Local configuration details were not known at the time the Docker
 | 
				
			||||||
 | 
					# image was created, so all setup is defered until the container
 | 
				
			||||||
 | 
					# is started. That's when this script runs.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# If we're not in an interactive shell, set defaults.
 | 
				
			||||||
 | 
					if [ ! -t 0 ]; then
 | 
				
			||||||
 | 
						echo '*** Non interactive shell detected...'
 | 
				
			||||||
 | 
						export PUBLIC_IP=auto
 | 
				
			||||||
 | 
						export PUBLIC_IPV6=auto
 | 
				
			||||||
 | 
						export PRIMARY_HOSTNAME=auto
 | 
				
			||||||
 | 
						export CSR_COUNTRY=US
 | 
				
			||||||
 | 
						export NONINTERACTIVE=1
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if ([ -z "$FORCE_INSTALL" ] && [ -f /var/lib/mailinabox/api.key ]); then
 | 
				
			||||||
 | 
						# Mailinabox is already installed and we don't want to reinstall
 | 
				
			||||||
 | 
						export SKIP_INSTALL=1
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# If we are skipping install, reload from /etc/mailinabox.conf if exists
 | 
				
			||||||
 | 
					if ([ -f /var/lib/mailinabox/api.key ] && [ ! -z "$SKIP_INSTALL" ]); then
 | 
				
			||||||
 | 
						echo '*** Loading variables from "/etc/mailinabox.conf"...'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						source /etc/mailinabox.conf
 | 
				
			||||||
 | 
						unset PRIVATE_IP
 | 
				
			||||||
 | 
						unset PRIVATE_IPV6
 | 
				
			||||||
 | 
						export SKIP_NETWORK_CHECKS=1
 | 
				
			||||||
 | 
						export NONINTERACTIVE=1
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export DISABLE_FIREWALL=1
 | 
				
			||||||
 | 
					cd /usr/local/mailinabox
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ -z "$SKIP_INSTALL" ]; then
 | 
				
			||||||
 | 
						echo "*** Starting mailinabox installation..."
 | 
				
			||||||
 | 
						# Run in background to avoid blocking runit initialization while installing.
 | 
				
			||||||
 | 
						source setup/start.sh &
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
						echo "*** Configuring mailinabox..."
 | 
				
			||||||
 | 
						# Run in foreground for services to be started after configuration is re-written.
 | 
				
			||||||
 | 
						source setup/questions.sh
 | 
				
			||||||
 | 
						cat > /etc/mailinabox.conf << EOF;
 | 
				
			||||||
 | 
					STORAGE_USER=$STORAGE_USER
 | 
				
			||||||
 | 
					STORAGE_ROOT=$STORAGE_ROOT
 | 
				
			||||||
 | 
					PRIMARY_HOSTNAME=$PRIMARY_HOSTNAME
 | 
				
			||||||
 | 
					PUBLIC_IP=$PUBLIC_IP
 | 
				
			||||||
 | 
					PUBLIC_IPV6=$PUBLIC_IPV6
 | 
				
			||||||
 | 
					PRIVATE_IP=$PRIVATE_IP
 | 
				
			||||||
 | 
					PRIVATE_IPV6=$PRIVATE_IPV6
 | 
				
			||||||
 | 
					CSR_COUNTRY=$CSR_COUNTRY
 | 
				
			||||||
 | 
					EOF
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
@ -3,75 +3,112 @@
 | 
				
			|||||||
# ==================================================================
 | 
					# ==================================================================
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Run this script from the base directory of the Mail-in-a-Box
 | 
					# Run this script from the base directory of the Mail-in-a-Box
 | 
				
			||||||
# repository (i.e. run as 'containers/docker/run').
 | 
					# repository (i.e. run as './containers/docker/run').
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Set these optional environment variables as needed:
 | 
				
			||||||
 | 
					# * HOST_HTTP_PORT: Host http: port to bind (default: 80).
 | 
				
			||||||
 | 
					# * HOST_HTTPS_PORT: Host https: port to bind (default: 443).
 | 
				
			||||||
 | 
					# * SKIP_BUILD: Skip the build of docker image (default: unset).
 | 
				
			||||||
 | 
					# * NODNS: Skip mapping of DNS ports (53 tcp/upd). They are not always available on host, as another DNS server can be running (default: unset).
 | 
				
			||||||
 | 
					# * CONTAINER_NAME: Name of the main container (default: mailinabox).
 | 
				
			||||||
 | 
					# * CONTAINER_DATA_NAME: Name of the data container (default: mailinabox-data).
 | 
				
			||||||
 | 
					# * NONINTERACTIVE: Use this when mailinabox is already installed on the volume container. Else, it's not recommanded (default: unset).
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# A base image is created first. The base image installs Ubuntu
 | 
					# A base image is created first. The base image installs Ubuntu
 | 
				
			||||||
# packages and pulls in the Mail-in-a-Box source code. This is
 | 
					# packages and pulls in the Mail-in-a-Box source code. This is
 | 
				
			||||||
# defined in Dockerfile at the root of this repository.
 | 
					# defined in Dockerfile at the root of this repository.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# A mailinabox-userdata container is started next. This container
 | 
					# A mailinabox-data container is created next. This container
 | 
				
			||||||
# contains nothing but a shared volume for storing user data.
 | 
					# contains nothing but a shared volume for storing user data.
 | 
				
			||||||
# It is segregated from the rest of the live system to make backups
 | 
					# It is segregated from the rest of the live system to make backups
 | 
				
			||||||
# easier.
 | 
					# easier.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# The mailinabox-services container is started last. It is the
 | 
					# The mailinabox container is started last. It is the
 | 
				
			||||||
# real thing: it runs the mailinabox image. This container will
 | 
					# real thing: it runs the mailinabox image. This container will
 | 
				
			||||||
# initialize itself and will initialize the mailinabox-userdata
 | 
					# initialize itself and will initialize the mailinabox-data
 | 
				
			||||||
# volume if the volume is new.
 | 
					# volume if the volume is new.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Build or rebuild the image.
 | 
					# Build or rebuild the image.
 | 
				
			||||||
# Rebuilds are very fast.
 | 
					# Rebuilds are very fast.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
tput setaf 2
 | 
					HOST_HTTP_PORT=${HOST_HTTP_PORT:-80}
 | 
				
			||||||
echo "Building/updating base image (mailinabox)..."
 | 
					HOST_HTTPS_PORT=${HOST_HTTPS_PORT:-443}
 | 
				
			||||||
tput setaf 7
 | 
					CONTAINER_NAME=${CONTAINER_NAME:-mailinabox}
 | 
				
			||||||
 | 
					CONTAINER_DATA_NAME=${CONTAINER_DATA_NAME:-${CONTAINER_NAME}-data}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
docker build -q -t mailinabox .
 | 
					if [ -z "$SKIP_BUILD" ]; then
 | 
				
			||||||
 | 
					 | 
				
			||||||
if ! docker ps -a | grep mailinabox-userdata > /dev/null; then
 | 
					 | 
				
			||||||
	tput setaf 2
 | 
						tput setaf 2
 | 
				
			||||||
	echo
 | 
						echo "Building/updating base image (mailinabox)..."
 | 
				
			||||||
	echo "Creating a new container for your data (mailinabox-userdata)..."
 | 
					 | 
				
			||||||
	tput setaf 7
 | 
						tput setaf 7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	docker run -d \
 | 
						docker build -q -t mailinabox . || exit 1
 | 
				
			||||||
		--name mailinabox-userdata \
 | 
					fi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if ! docker inspect ${CONTAINER_DATA_NAME} > /dev/null; then
 | 
				
			||||||
 | 
						tput setaf 2
 | 
				
			||||||
 | 
						echo
 | 
				
			||||||
 | 
						echo "Creating a new container for your data (${CONTAINER_DATA_NAME})..."
 | 
				
			||||||
 | 
						tput setaf 7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						docker create \
 | 
				
			||||||
 | 
							--name ${CONTAINER_DATA_NAME} \
 | 
				
			||||||
		-v /home/user-data \
 | 
							-v /home/user-data \
 | 
				
			||||||
		scratch /bin/does-not-exist-but-thats-ok
 | 
							phusion/baseimage:0.9.16 || exit 1
 | 
				
			||||||
else
 | 
					else
 | 
				
			||||||
	tput setaf 2
 | 
						tput setaf 2
 | 
				
			||||||
	echo
 | 
						echo
 | 
				
			||||||
	echo "Using existing container mailinabox-userdata for your data."
 | 
						echo "Using existing container ${CONTAINER_DATA_NAME} for your data."
 | 
				
			||||||
	tput setaf 7
 | 
						tput setaf 7
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# End a running container.
 | 
					# End a running container.
 | 
				
			||||||
 | 
					if docker inspect ${CONTAINER_NAME} > /dev/null; then
 | 
				
			||||||
if docker ps -a | grep mailinabox-services > /dev/null; then
 | 
					 | 
				
			||||||
	tput setaf 2
 | 
						tput setaf 2
 | 
				
			||||||
	echo
 | 
						echo
 | 
				
			||||||
	echo "Destroying mailinabox-services container..."
 | 
						echo "Destroying ${CONTAINER_NAME} container..."
 | 
				
			||||||
	tput setaf 7
 | 
						tput setaf 7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	docker rm -f mailinabox-services
 | 
						docker rm -f ${CONTAINER_NAME}
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Start container.
 | 
					# Start container.
 | 
				
			||||||
 | 
					 | 
				
			||||||
tput setaf 2
 | 
					tput setaf 2
 | 
				
			||||||
echo
 | 
					echo
 | 
				
			||||||
echo "Starting new container (mailinabox-services)..."
 | 
					echo "Starting new container (${CONTAINER_NAME})..."
 | 
				
			||||||
tput setaf 7
 | 
					tput setaf 7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Run the services container
 | 
				
			||||||
 | 
					# detached if NONINTERACTIVE is set,
 | 
				
			||||||
 | 
					# interactively if NONINTERACTIVE is not set,
 | 
				
			||||||
# Notes:
 | 
					# Notes:
 | 
				
			||||||
# * Passing through SKIP_NETWORK_CHECKS makes it easier to do testing
 | 
					# * Passing through SKIP_NETWORK_CHECKS makes it easier to do testing
 | 
				
			||||||
#   on a residential network.
 | 
					#   on a residential network.
 | 
				
			||||||
 | 
					# * --privileged flag cause an issue with bind9/named failing to start in this case
 | 
				
			||||||
 | 
					#   see docker/docker#7318
 | 
				
			||||||
docker run \
 | 
					docker run \
 | 
				
			||||||
	--privileged \
 | 
					 | 
				
			||||||
	-v /dev/urandom:/dev/random \
 | 
						-v /dev/urandom:/dev/random \
 | 
				
			||||||
	-p 25 -p 53/udp -p 53/tcp -p 80 -p 443 -p 587 -p 993 \
 | 
						-p 25:25 \
 | 
				
			||||||
	--name mailinabox-services \
 | 
						$([ -z "$NODNS" ] && echo "-p 53:53/udp -p 53:53/tcp") \
 | 
				
			||||||
	--volumes-from mailinabox-userdata \
 | 
						-p $HOST_HTTP_PORT:80 \
 | 
				
			||||||
 | 
						-p $HOST_HTTPS_PORT:443 \
 | 
				
			||||||
 | 
						-p 587:587 \
 | 
				
			||||||
 | 
						-p 993:993 \
 | 
				
			||||||
 | 
						-p 4190:4190 \
 | 
				
			||||||
 | 
						--name ${CONTAINER_NAME} \
 | 
				
			||||||
 | 
						--volumes-from ${CONTAINER_DATA_NAME} \
 | 
				
			||||||
 | 
						--restart always \
 | 
				
			||||||
 | 
						$([ ! -z "$NONINTERACTIVE" ] && echo "-d") \
 | 
				
			||||||
 | 
						-it \
 | 
				
			||||||
 | 
						-e "IS_DOCKER=1" \
 | 
				
			||||||
	-e "SKIP_NETWORK_CHECKS=$SKIP_NETWORK_CHECKS" \
 | 
						-e "SKIP_NETWORK_CHECKS=$SKIP_NETWORK_CHECKS" \
 | 
				
			||||||
	mailinabox
 | 
						mailinabox \
 | 
				
			||||||
 | 
						|| exit 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ -z "$NONINTERACTIVE" ]; then
 | 
				
			||||||
 | 
						tput setaf 2
 | 
				
			||||||
 | 
						echo
 | 
				
			||||||
 | 
						echo "Restarting container ${CONTAINER_NAME}..."
 | 
				
			||||||
 | 
						tput setaf 7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						docker restart ${CONTAINER_NAME} || exit 1
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
@ -1,3 +0,0 @@
 | 
				
			|||||||
#!/bin/bash
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
rsyslogd -n
 | 
					 | 
				
			||||||
							
								
								
									
										103
									
								
								containers/docker/tools/configure_services.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										103
									
								
								containers/docker/tools/configure_services.sh
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,103 @@
 | 
				
			|||||||
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# 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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This removes /etc/init.d service if service exists in runit.
 | 
				
			||||||
 | 
					# It also creates a symlink from /usr/bin/sv to /etc/init.d/$service
 | 
				
			||||||
 | 
					# to support SysV syntax: service $service <command> or /etc/init.d/$service <command>
 | 
				
			||||||
 | 
					SERVICES=/etc/service/*
 | 
				
			||||||
 | 
					for f in $SERVICES
 | 
				
			||||||
 | 
					do
 | 
				
			||||||
 | 
						service=$(basename "$f")
 | 
				
			||||||
 | 
						if [ -d /etc/service/$service ]; then
 | 
				
			||||||
 | 
							if [ -f /etc/init.d/$service ]; then
 | 
				
			||||||
 | 
								mv /etc/init.d/$service /etc/init.d/$service.lsb
 | 
				
			||||||
 | 
								chmod -x /etc/init.d/$service.lsb
 | 
				
			||||||
 | 
							fi
 | 
				
			||||||
 | 
							ln -s /usr/bin/sv /etc/init.d/$service
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Create runit services from sysv services. 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 <<EOF;
 | 
				
			||||||
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					source /usr/local/mailinabox/setup/functions.sh
 | 
				
			||||||
 | 
					hide_output /etc/init.d/$INITD_NAME restart
 | 
				
			||||||
 | 
					while [ \`ps a -C $WAIT_ON_PROCESS_NAME -o pid= | wc -l\` -gt 0 ]; do
 | 
				
			||||||
 | 
					       sleep 30
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
 | 
					echo $WAIT_ON_PROCESS_NAME died.
 | 
				
			||||||
 | 
					sleep 20
 | 
				
			||||||
 | 
					EOF
 | 
				
			||||||
 | 
						chmod +x /etc/service/$INITD_NAME/run
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					make_runit_service bind9 named
 | 
				
			||||||
 | 
					make_runit_service resolvconf resolvconf
 | 
				
			||||||
 | 
					make_runit_service fail2ban fail2ban
 | 
				
			||||||
 | 
					make_runit_service mailinabox mailinabox-daemon
 | 
				
			||||||
 | 
					make_runit_service memcached memcached
 | 
				
			||||||
 | 
					make_runit_service nginx nginx
 | 
				
			||||||
 | 
					make_runit_service nsd nsd
 | 
				
			||||||
 | 
					make_runit_service opendkim opendkim
 | 
				
			||||||
 | 
					make_runit_service opendmarc opendmarc
 | 
				
			||||||
 | 
					make_runit_service php5-fpm php5-fpm
 | 
				
			||||||
 | 
					make_runit_service postfix postfix
 | 
				
			||||||
 | 
					make_runit_service postgrey postgrey
 | 
				
			||||||
 | 
					make_runit_service spampd spampd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Dovecot doesn't provide an init.d script, but it does provide
 | 
				
			||||||
 | 
					# a way to launch without daemonization. We wrote a script for
 | 
				
			||||||
 | 
					# that specifically.
 | 
				
			||||||
 | 
					for service in dovecot; do
 | 
				
			||||||
 | 
						mkdir -p /etc/service/$service
 | 
				
			||||||
 | 
						cp /usr/local/mailinabox/containers/docker/runit/$service.sh /etc/service/$service/run
 | 
				
			||||||
 | 
						chmod +x /etc/service/$service/run
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This adds a log/run file on each runit service directory.
 | 
				
			||||||
 | 
					# This file make services stdout/stderr output to svlogd log
 | 
				
			||||||
 | 
					# directory located in /var/log/runit/$service.
 | 
				
			||||||
 | 
					SERVICES=/etc/service/*
 | 
				
			||||||
 | 
					for f in $SERVICES
 | 
				
			||||||
 | 
					do
 | 
				
			||||||
 | 
						service=$(basename "$f")
 | 
				
			||||||
 | 
						if [ -d /etc/service/$service ]; then
 | 
				
			||||||
 | 
							mkdir -p /etc/service/$service/log
 | 
				
			||||||
 | 
							cat > /etc/service/$service/log/run <<EOF;
 | 
				
			||||||
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					mkdir -p /var/log/runit
 | 
				
			||||||
 | 
					chmod o-wrx /var/log/runit
 | 
				
			||||||
 | 
					mkdir -p /var/log/runit/$service
 | 
				
			||||||
 | 
					chmod o-wrx /var/log/runit/$service
 | 
				
			||||||
 | 
					exec svlogd -tt /var/log/runit/$service/
 | 
				
			||||||
 | 
					EOF
 | 
				
			||||||
 | 
							chmod +x /etc/service/$service/log/run
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Disable services for now. Until Mail-in-a-Box is installed the
 | 
				
			||||||
 | 
					# services won't be configured right and there would be errors if
 | 
				
			||||||
 | 
					# they got run prematurely.
 | 
				
			||||||
 | 
					SERVICES=/etc/service/*
 | 
				
			||||||
 | 
					for f in $SERVICES
 | 
				
			||||||
 | 
					do
 | 
				
			||||||
 | 
						service=$(basename "$f")
 | 
				
			||||||
 | 
						if [ "$service" = "syslog-ng" ]; then continue; fi;
 | 
				
			||||||
 | 
						if [ "$service" = "syslog-forwarder" ]; then continue; fi;
 | 
				
			||||||
 | 
						if [ "$service" = "ssh" ]; then continue; fi;
 | 
				
			||||||
 | 
						if [ "$service" = "cron" ]; then continue; fi;
 | 
				
			||||||
 | 
						if ([ -d /etc/service/$service ] && [ ! -f /etc/service/$service/down ]); then
 | 
				
			||||||
 | 
							touch /etc/service/$service/down
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
@ -127,6 +127,8 @@ EOF
 | 
				
			|||||||
chmod +x /etc/cron.daily/mailinabox-dnssec
 | 
					chmod +x /etc/cron.daily/mailinabox-dnssec
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Permit DNS queries on TCP/UDP in the firewall.
 | 
					# Permit DNS queries on TCP/UDP in the firewall.
 | 
				
			||||||
 | 
					 | 
				
			||||||
ufw_allow domain
 | 
					ufw_allow domain
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Start nsd. None of the zones are configured until the management daemon is
 | 
				
			||||||
 | 
					# run later, though.
 | 
				
			||||||
 | 
					restart_service nsd
 | 
				
			||||||
 | 
				
			|||||||
@ -167,19 +167,17 @@ function ufw_allow {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function restart_service {
 | 
					function restart_service {
 | 
				
			||||||
	# Restart a service quietly.
 | 
						if [ -z "$IS_DOCKER" ]; then
 | 
				
			||||||
 | 
							# Restart the service.
 | 
				
			||||||
	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
 | 
							hide_output service $1 restart
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							# In Docker, make sure the service is not disabled by a down file.
 | 
				
			||||||
 | 
							if [ -f /etc/service/$1/down ]; then
 | 
				
			||||||
 | 
								rm /etc/service/$1/down
 | 
				
			||||||
 | 
							fi
 | 
				
			||||||
 | 
							sv restart $1
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Dialog Functions ##
 | 
					## Dialog Functions ##
 | 
				
			||||||
 | 
				
			|||||||
@ -184,4 +184,5 @@ chmod +x /etc/cron.hourly/mailinabox-owncloud
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Enable PHP modules and restart PHP.
 | 
					# Enable PHP modules and restart PHP.
 | 
				
			||||||
php5enmod imap
 | 
					php5enmod imap
 | 
				
			||||||
 | 
					restart_service memcached
 | 
				
			||||||
restart_service php5-fpm
 | 
					restart_service php5-fpm
 | 
				
			||||||
 | 
				
			|||||||
@ -12,8 +12,10 @@ if [ -z "$NONINTERACTIVE" ]; then
 | 
				
			|||||||
		apt_get_quiet install dialog python3 python3-pip  || exit 1
 | 
							apt_get_quiet install dialog python3 python3-pip  || exit 1
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if [ -z "$IS_DOCKER" ]; then
 | 
				
			||||||
	# email_validator is repeated in setup/management.sh
 | 
						# email_validator is repeated in setup/management.sh
 | 
				
			||||||
	hide_output pip3 install "email_validator==0.1.0-rc5" || exit 1
 | 
						hide_output pip3 install "email_validator==0.1.0-rc5" || exit 1
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	message_box "Mail-in-a-Box Installation" \
 | 
						message_box "Mail-in-a-Box Installation" \
 | 
				
			||||||
		"Hello and thanks for deploying a Mail-in-a-Box!
 | 
							"Hello and thanks for deploying a Mail-in-a-Box!
 | 
				
			||||||
 | 
				
			|||||||
@ -102,14 +102,6 @@ source setup/zpush.sh
 | 
				
			|||||||
source setup/management.sh
 | 
					source setup/management.sh
 | 
				
			||||||
source setup/munin.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.
 | 
					# Ping the management daemon to write the DNS and nginx configuration files.
 | 
				
			||||||
until nc -z -w 4 localhost 10222
 | 
					until nc -z -w 4 localhost 10222
 | 
				
			||||||
do
 | 
					do
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user