Files
2026-03-09 22:30:41 +00:00

251 lines
6.4 KiB
Bash

#!/bin/bash
# Dovecot Docker Entrypoint Script
# Phase 8: Email Client Implementation
# Handles container initialization and configuration
set -e
# Color output for logging
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
log_info() {
echo -e "${GREEN}[DOVECOT]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[DOVECOT]${NC} $1"
}
log_error() {
echo -e "${RED}[DOVECOT]${NC} $1"
}
##
## Configuration Initialization
##
log_info "Initializing Dovecot container..."
# Ensure directories exist
log_info "Creating required directories..."
mkdir -p /var/mail/vmail
mkdir -p /var/run/dovecot
mkdir -p /var/log/dovecot
mkdir -p /etc/dovecot/private
mkdir -p /etc/dovecot/certs
mkdir -p /var/spool/postfix/private 2>/dev/null || true
# Set proper permissions
chown -R vmail:mail /var/mail
chmod 700 /var/mail/vmail
chown -R dovecot:dovecot /var/run/dovecot
chmod 750 /var/run/dovecot
chown -R dovecot:dovecot /var/log/dovecot
# Remove stale auth-token-secret.dat from previous runs to prevent
# "Compromised token secret file" errors on container restart
rm -f /var/run/dovecot/auth-token-secret.dat
rm -f /run/dovecot/auth-token-secret.dat
log_info "Directory initialization complete"
##
## User Database Configuration
##
# If DOVECOT_USERS environment variable is set, write it to the users file
if [ -n "$DOVECOT_USERS" ]; then
log_info "Setting up virtual users from environment..."
echo "$DOVECOT_USERS" > /etc/dovecot/dovecot-users
# dovecot auth process runs as dovecot:dovecot (uid=90, gid=101)
# File must be readable by the dovecot group for auth lookups
chown root:dovecot /etc/dovecot/dovecot-users
chmod 640 /etc/dovecot/dovecot-users
log_info "Virtual users configured"
else
# Ensure the COPY'd dovecot-users file has correct permissions
# in case a volume mount replaced it
chown root:dovecot /etc/dovecot/dovecot-users
chmod 640 /etc/dovecot/dovecot-users
fi
##
## LDAP Configuration (Optional)
##
if [ "$DOVECOT_AUTH_BACKEND" = "ldap" ]; then
log_info "Configuring LDAP authentication..."
if [ -z "$LDAP_URI" ] || [ -z "$LDAP_BASE_DN" ]; then
log_error "LDAP enabled but LDAP_URI or LDAP_BASE_DN not set"
exit 1
fi
# Create LDAP configuration
cat > /etc/dovecot/dovecot-ldap.conf <<EOF
# LDAP Configuration for Dovecot
# Generated by docker-entrypoint.sh
hosts = $LDAP_URI
base = $LDAP_BASE_DN
scope = subtree
# User search filter
user_filter = (&(objectClass=inetOrgPerson)(uid=%u))
# Group search filter (optional)
user_attrs = mail=user@*,homeDirectory=home
pass_filter = (&(objectClass=inetOrgPerson)(uid=%u))
# TLS settings
tls = ${LDAP_TLS:-start_tls}
tls_ca_cert_file = /etc/ssl/certs/ca-certificates.crt
tls_require_cert = ${LDAP_TLS_VERIFY:-demand}
# Bind credentials (if required)
${LDAP_BIND_DN:+dn = $LDAP_BIND_DN}
${LDAP_BIND_PASSWORD:+dnpass = $LDAP_BIND_PASSWORD}
# Debug
debug = ${DOVECOT_LDAP_DEBUG:-no}
EOF
chmod 600 /etc/dovecot/dovecot-ldap.conf
log_info "LDAP configuration created"
fi
##
## TLS Certificate Handling
##
log_info "Checking TLS certificates..."
# Allow custom certificates via volumes
if [ -f "/etc/dovecot/certs/custom.crt" ] && [ -f "/etc/dovecot/private/custom.key" ]; then
log_info "Using custom certificates from volumes"
else
log_info "Using default self-signed certificates"
# Certificates are already generated in Dockerfile
if [ ! -f "/etc/dovecot/certs/dovecot.crt" ]; then
log_warn "Generating new self-signed certificate..."
mkdir -p /etc/dovecot/private /etc/dovecot/certs
openssl req -x509 -newkey rsa:2048 -keyout /etc/dovecot/private/dovecot.key \
-out /etc/dovecot/certs/dovecot.crt -days 365 -nodes \
-subj "/C=US/ST=State/L=City/O=Organization/CN=${DOVECOT_HOSTNAME:-emailclient.local}"
fi
fi
# Ensure certificate permissions
chmod 600 /etc/dovecot/private/*.key
chmod 644 /etc/dovecot/certs/*.crt
log_info "TLS certificates ready"
##
## Postfix Integration
##
log_info "Setting up Postfix integration..."
# Ensure Postfix directories exist (may be mounted)
mkdir -p /var/spool/postfix/private 2>/dev/null || true
mkdir -p /var/mail/postfix 2>/dev/null || true
# Create LMTP socket directory with proper permissions
if [ -d "/var/spool/postfix" ]; then
chown postfix:postfix /var/spool/postfix 2>/dev/null || true
chmod 710 /var/spool/postfix 2>/dev/null || true
# Create private directory with correct permissions for Dovecot LMTP
mkdir -p /var/spool/postfix/private
chmod 710 /var/spool/postfix/private
fi
log_info "Postfix integration configured"
##
## Dovecot Configuration Validation
##
log_info "Validating Dovecot configuration..."
if ! doveconf -c /etc/dovecot/dovecot.conf > /dev/null 2>&1; then
log_error "Dovecot configuration validation failed!"
doveconf -c /etc/dovecot/dovecot.conf
exit 1
fi
log_info "Configuration validation successful"
##
## Environment-Based Customizations
##
# Enable debug logging if DOVECOT_DEBUG is set
if [ "${DOVECOT_DEBUG}" = "true" ] || [ "${DOVECOT_DEBUG}" = "1" ]; then
log_warn "DEBUG MODE ENABLED - verbose logging will be active"
cat >> /etc/dovecot/conf.d/99-local.conf <<EOF
# Debug logging (container startup)
auth_debug = yes
mail_debug = yes
verbose_ssl = yes
EOF
fi
# Set max message size from environment (if provided)
if [ -n "$DOVECOT_MAX_MESSAGE_SIZE" ]; then
log_info "Setting max message size to $DOVECOT_MAX_MESSAGE_SIZE"
cat >> /etc/dovecot/conf.d/99-local.conf <<EOF
# Message size limit (from environment)
mail_max_userip_connections = ${DOVECOT_MAX_MESSAGE_SIZE}
EOF
fi
# Configure hostname
if [ -n "$DOVECOT_HOSTNAME" ]; then
log_info "Setting hostname to $DOVECOT_HOSTNAME"
cat >> /etc/dovecot/conf.d/99-local.conf <<EOF
# Hostname (from environment)
mail_server_admin = postmaster@${DOVECOT_HOSTNAME}
EOF
fi
##
## Pre-startup Health Checks
##
log_info "Performing pre-startup health checks..."
# Check if mail storage is writable
if ! touch /var/mail/vmail/.write_test 2>/dev/null; then
log_error "Mail storage directory is not writable!"
exit 1
fi
rm -f /var/mail/vmail/.write_test
log_info "Health checks passed"
##
## Final Log Output
##
log_info "Configuration complete. Starting Dovecot..."
log_info "IMAP: port 143 (STARTTLS)"
log_info "IMAPS: port 993 (TLS)"
log_info "POP3: port 110 (STARTTLS)"
log_info "POP3S: port 995 (TLS)"
log_info "LMTP: unix socket at /var/spool/postfix/private/dovecot-lmtp"
##
## Start Dovecot
##
# Execute main command (typically "dovecot -F" for foreground mode)
exec "$@"