#!/usr/bin/env bash set -o pipefail if [[ "$(uname -r)" =~ ^4\.15\.0-60 ]]; then echo "DO NOT RUN mailcow ON THIS UBUNTU KERNEL!"; echo "Please update to 5.x or use another distribution." exit 1 fi if [[ "$(uname -r)" =~ ^4\.4\. ]]; then if grep -q Ubuntu <<< $(uname -a); then echo "DO NOT RUN mailcow ON THIS UBUNTU KERNEL!"; echo "Please update to linux-generic-hwe-16.04 by running \"apt-get install --install-recommends linux-generic-hwe-16.04\"" exit 1 fi fi if grep --help 2>&1 | head -n 1 | grep -q -i "busybox"; then echo "BusyBox grep detected, please install gnu grep, \"apk add --no-cache --upgrade grep\""; exit 1; fi # This will also cover sort if cp --help 2>&1 | head -n 1 | grep -q -i "busybox"; then echo "BusyBox cp detected, please install coreutils, \"apk add --no-cache --upgrade coreutils\""; exit 1; fi if sed --help 2>&1 | head -n 1 | grep -q -i "busybox"; then echo "BusyBox sed detected, please install gnu sed, \"apk add --no-cache --upgrade sed\""; exit 1; fi # Check which container engine is available. # Check for podman first, because the 'podman-docker' package might be installed providing a dummy 'docker' command. if command -v podman > /dev/null 2>&1; then CONTAINER_ENGINE="podman" echo -e "\e[32mFound Podman container engine.\e[0m" echo -e "\e[31mNOTE: Support for Podman is experimental, consider this before deploying to production! \e[0m" if [[ -n "${DOCKER_HOST}" ]] && [[ "${DOCKER_HOST}" == "unix://"* ]]; then CONTAINER_SOCKET="${DOCKER_HOST/"unix://"/}" else CONTAINER_SOCKET="/run/user/${UID}/podman/podman.sock" fi # To patch the docker-compose file for use with podman EXTRA_REQUIRED_PACKAGES="patch" elif command -v docker > /dev/null 2>&1; then CONTAINER_ENGINE="docker" echo -e "\e[32mFound Docker container engine.\e[0m" CONTAINER_SOCKET="/var/run/docker.sock" EXTRA_REQUIRED_PACKAGES="" else echo "Cannot find container engine (Docker or Podman), exiting..." exit 1 fi for bin in openssl curl git awk sha1sum ${EXTRA_REQUIRED_PACKAGES}; do if [[ -z $(which ${bin}) ]]; then echo "Cannot find ${bin}, exiting..." exit 1 fi done MAILCOW_DOCKER_COMPOSE=${MAILCOW_DOCKER_COMPOSE:-"docker-compose"} if [[ "${CONTAINER_ENGINE}" == "docker" ]] && command -v docker compose > /dev/null 2>&1; then version=$(docker compose version --short) if [[ $version =~ ^2\.([0-9]+)\.([0-9]+) ]]; then COMPOSE_VERSION=native echo -e "\e[31mFound Docker Compose Plugin (native).\e[0m" echo -e "\e[31mSetting the DOCKER_COMPOSE_VERSION Variable to native\e[0m" sleep 2 echo -e "\e[33mNotice: You'll have to update this Compose Version via your Package Manager manually! \e[0m" else echo -e "\e[31mCannot find Docker Compose with a Version Higher than 2.X.X.\e[0m" echo -e "\e[31mPlease update/install manually regarding to this doc site: https://mailcow.github.io/mailcow-dockerized-docs/i_u_m/i_u_m_install/\e[0m" exit 1 fi elif command -v $MAILCOW_DOCKER_COMPOSE > /dev/null 2>&1; then version=$($MAILCOW_DOCKER_COMPOSE version --short) if [[ $version =~ ^2\.([0-9]+)\.([0-9]+) ]]; then COMPOSE_VERSION=standalone echo -e "\e[31mFound Docker Compose Standalone.\e[0m" echo -e "\e[31mSetting the DOCKER_COMPOSE_VERSION Variable to standalone\e[0m" sleep 2 echo -e "\e[33mNotice: For an automatic update of ${MAILCOW_DOCKER_COMPOSE} please use the update_compose.sh scripts located at the helper-scripts folder.\e[0m" else echo -e "\e[31mCannot find Docker Compose with a Version Higher than 2.X.X.\e[0m" echo -e "\e[31mPlease update/install manually regarding to this doc site: https://mailcow.github.io/mailcow-dockerized-docs/i_u_m/i_u_m_install/\e[0m" exit 1 fi else echo -e "\e[31mCannot find Docker Compose.\e[0m" echo -e "\e[31mPlease install it manually regarding to this doc site: https://mailcow.github.io/mailcow-dockerized-docs/i_u_m/i_u_m_install/\e[0m" exit 1 fi ### If generate_config.sh is started with --dev or -d it will not check out nightly or master branch and will keep on the current branch if [[ ${1} == "--dev" || ${1} == "-d" ]]; then SKIP_BRANCH=y else SKIP_BRANCH=n fi if [ -f mailcow.conf ]; then read -r -p "A config file exists and will be overwritten, are you sure you want to continue? [y/N] " response case $response in [yY][eE][sS]|[yY]) mv mailcow.conf mailcow.conf_backup chmod 600 mailcow.conf_backup ;; *) exit 1 ;; esac fi echo "Press enter to confirm the detected value '[value]' where applicable or enter a custom value." while [ -z "${MAILCOW_HOSTNAME}" ]; do read -p "Mail server hostname (FQDN) - this is not your mail domain, but your mail servers hostname: " -e MAILCOW_HOSTNAME DOTS=${MAILCOW_HOSTNAME//[^.]}; if [ ${#DOTS} -lt 2 ] && [ ! -z ${MAILCOW_HOSTNAME} ]; then echo "${MAILCOW_HOSTNAME} is not a FQDN" MAILCOW_HOSTNAME= fi done if [ -a /etc/timezone ]; then DETECTED_TZ=$(cat /etc/timezone) elif [ -a /etc/localtime ]; then DETECTED_TZ=$(readlink /etc/localtime|sed -n 's|^.*zoneinfo/||p') fi while [ -z "${MAILCOW_TZ}" ]; do if [ -z "${DETECTED_TZ}" ]; then read -p "Timezone: " -e MAILCOW_TZ else read -p "Timezone [${DETECTED_TZ}]: " -e MAILCOW_TZ [ -z "${MAILCOW_TZ}" ] && MAILCOW_TZ=${DETECTED_TZ} fi done MEM_TOTAL=$(awk '/MemTotal/ {print $2}' /proc/meminfo) if [ ${MEM_TOTAL} -le "2621440" ]; then echo "Installed memory is <= 2.5 GiB. It is recommended to disable ClamAV to prevent out-of-memory situations." echo "ClamAV can be re-enabled by setting SKIP_CLAMD=n in mailcow.conf." read -r -p "Do you want to disable ClamAV now? [Y/n] " response case $response in [nN][oO]|[nN]) SKIP_CLAMD=n ;; *) SKIP_CLAMD=y ;; esac else SKIP_CLAMD=n fi if [ ${MEM_TOTAL} -le "2097152" ]; then echo "Disabling Solr on low-memory system." SKIP_SOLR=y elif [ ${MEM_TOTAL} -le "3670016" ]; then echo "Installed memory is <= 3.5 GiB. It is recommended to disable Solr to prevent out-of-memory situations." echo "Solr is a prone to run OOM and should be monitored. The default Solr heap size is 1024 MiB and should be set in mailcow.conf according to your expected load." echo "Solr can be re-enabled by setting SKIP_SOLR=n in mailcow.conf but will refuse to start with less than 2 GB total memory." read -r -p "Do you want to disable Solr now? [Y/n] " response case $response in [nN][oO]|[nN]) SKIP_SOLR=n ;; *) SKIP_SOLR=y ;; esac else SKIP_SOLR=n fi if [[ ${SKIP_BRANCH} != y ]]; then echo "Which branch of mailcow do you want to use?" echo "" echo "Available Branches:" echo "- master branch (stable updates) | default, recommended [1]" echo "- nightly branch (unstable updates, testing) | not-production ready [2]" sleep 1 while [ -z "${MAILCOW_BRANCH}" ]; do read -r -p "Choose the Branch with it´s number [1/2] " branch case $branch in [2]) MAILCOW_BRANCH="nightly" ;; *) MAILCOW_BRANCH="master" ;; esac done git fetch --all git checkout -f $git_branch elif [[ ${SKIP_BRANCH} == y ]]; then echo -e "\033[33mEnabled Dev Mode.\033[0m" echo -e "\033[33mNot checking out a different branch!\033[0m" MAILCOW_BRANCH=$(git rev-parse --short $(git rev-parse @{upstream})) else echo -e "\033[31mCould not determine branch input..." echo -e "\033[31mExiting." exit 1 fi if [ ! -z "${MAILCOW_BRANCH}" ]; then git_branch=${MAILCOW_BRANCH} fi [ ! -f ./data/conf/rspamd/override.d/worker-controller-password.inc ] && echo '# Placeholder' > ./data/conf/rspamd/override.d/worker-controller-password.inc if [[ "${CONTAINER_ENGINE}" == "podman" ]]; then # Apply patches for usage with Podman bash ./patches-for-podman.sh fi cat << EOF > mailcow.conf # ------------------------------ # mailcow web ui configuration # ------------------------------ # example.org is _not_ a valid hostname, use a fqdn here. # Default admin user is "admin" # Default password is "moohoo" MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME} # Password hash algorithm # Only certain password hash algorithm are supported. For a fully list of supported schemes, # see https://mailcow.github.io/mailcow-dockerized-docs/models/model-passwd/ MAILCOW_PASS_SCHEME=BLF-CRYPT # The directory used to store the data of the used containers (used in case the CUSTOM_STORAGE_LOCATION override is included) MAILCOW_STORAGE_DIR= # ------------------------------ # SQL database configuration # ------------------------------ DBNAME=mailcow DBUSER=mailcow # Please use long, random alphanumeric strings (A-Za-z0-9) DBPASS=$(LC_ALL=C data/web/inc/app_info.inc.php echo ' $MAILCOW_GIT_VERSION="'$mailcow_git_version'";' >> data/web/inc/app_info.inc.php echo ' $MAILCOW_LAST_GIT_VERSION="";' >> data/web/inc/app_info.inc.php echo ' $MAILCOW_GIT_OWNER="mailcow";' >> data/web/inc/app_info.inc.php echo ' $MAILCOW_GIT_REPO="mailcow-dockerized";' >> data/web/inc/app_info.inc.php echo ' $MAILCOW_GIT_URL="https://github.com/mailcow/mailcow-dockerized";' >> data/web/inc/app_info.inc.php echo ' $MAILCOW_GIT_COMMIT="'$mailcow_git_commit'";' >> data/web/inc/app_info.inc.php echo ' $MAILCOW_GIT_COMMIT_DATE="'$mailcow_git_commit_date'";' >> data/web/inc/app_info.inc.php echo ' $MAILCOW_BRANCH="'$git_branch'";' >> data/web/inc/app_info.inc.php echo ' $MAILCOW_UPDATEDAT='$(date +%s)';' >> data/web/inc/app_info.inc.php echo '?>' >> data/web/inc/app_info.inc.php else echo ' data/web/inc/app_info.inc.php echo ' $MAILCOW_GIT_VERSION="'$mailcow_git_version'";' >> data/web/inc/app_info.inc.php echo ' $MAILCOW_LAST_GIT_VERSION="";' >> data/web/inc/app_info.inc.php echo ' $MAILCOW_GIT_OWNER="mailcow";' >> data/web/inc/app_info.inc.php echo ' $MAILCOW_GIT_REPO="mailcow-dockerized";' >> data/web/inc/app_info.inc.php echo ' $MAILCOW_GIT_URL="https://github.com/mailcow/mailcow-dockerized";' >> data/web/inc/app_info.inc.php echo ' $MAILCOW_GIT_COMMIT="";' >> data/web/inc/app_info.inc.php echo ' $MAILCOW_GIT_COMMIT_DATE="";' >> data/web/inc/app_info.inc.php echo ' $MAILCOW_BRANCH="'$git_branch'";' >> data/web/inc/app_info.inc.php echo ' $MAILCOW_UPDATEDAT='$(date +%s)';' >> data/web/inc/app_info.inc.php echo '?>' >> data/web/inc/app_info.inc.php echo -e "\e[33mCannot determine current git repository version...\e[0m" fi