fix(setup-script): ZMS-252 Install script updates (#847)

* Switches to latest tagged release for repo checkouts

Replaces hardcoded commit hashes with a function that checks out
the latest tagged release for each repository. Improves deployment flow
by automatically tracking stable upstream releases.

* Enforces supported architectures in install scripts

Adds explicit architecture detection and validation to setup scripts,
restricting them to amd64, arm64, and armhf. Updates repository
configuration to use detected architecture for package sources,
improving compatibility and preventing installation on unsupported systems.

* Updates npm install flags for improved dependency handling

Replaces deprecated and less explicit npm install flags with
--omit=dev and --omit=optional to better control installed
dependencies and align with modern npm practices. Reduces
potential for installing unnecessary packages and improves
script reliability.

* Reformats SSL certificate issuance command by placing each argument
on a separate line, enhancing readability and simplifying future
modifications.

* Updates Node.js and MongoDB to latest major versions

Ensures compatibility and access to new features by moving to Node.js 22 and MongoDB 8.0. Prepares environment for current ecosystem dependencies and future-proofing.

* add ending line

* fix typos, improve consistency, fix npm install script, make it more modern

* improve consistency

---------

Co-authored-by: Joosep Jõeleht <joosep@zone.ee>
Co-authored-by: Nikolai Ovtsinnikov <nikolai@zone.ee>
This commit is contained in:
Joosep Jõeleht 2025-08-01 10:31:16 +03:00 committed by GitHub
parent 4adfce07c3
commit c209b3af26
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 51 additions and 38 deletions

View file

@ -198,8 +198,8 @@ There is a slight difference between domainname and hostname.
${ORANGE}Simplest case${NC}:
One server serves everything: company website, emails, webmails.
One ip address, and domainname is the same az hostname.
Eg. amazme.com
One ip address, and domainname is the same as hostname.
Eg. amazeme.com
${GREEN}More general case${NC}:
The domainname is part of the email address:
@ -210,11 +210,11 @@ name is: `hostname`
On larger organizations, the company homepage is independent from
the mail servers. Or the webmail servers.
Eg. the company homepage is amazme.com [11.22.33.44],
the mail server is mail.amazme.com [11.22.33.43]
Eg. the company homepage is amazeme.com [11.22.33.44],
the mail server is mail.amazeme.com [11.22.33.43]
So domainname = amazme.com
hostname = mail.amazme.com
So domainname = amazeme.com
hostname = mail.amazeme.com
${RED}IP address${NC} case:
You can call this script with ip address instead of domain name:
@ -236,7 +236,7 @@ function hook_script {
git --git-dir=/var/opt/$1.git --work-tree=\"/opt/$1\" checkout "\$3" -f
cd \"/opt/$1\"
rm -rf package-lock.json
npm install --production --no-optional --no-package-lock --no-audit --ignore-scripts --no-shrinkwrap --progress=false
npm install --omit=dev --omit=optional --no-package-lock --no-audit --ignore-scripts --no-shrinkwrap --progress=false
sudo $SYSTEMCTL_PATH restart $1 || echo \"Failed restarting service\"" > "/var/opt/$1.git/hooks/update"
chmod +x "/var/opt/$1.git/hooks/update"
}
@ -284,4 +284,14 @@ echo "/var/log/${SERVICE_NAME}/${SERVICE_NAME}.log {
}
export -f log_script
export -f log_script
function get_latest_release_commit {
REPO_NAME="$1"
GIT_DIR="/var/opt/${REPO_NAME}.git"
git --git-dir="$GIT_DIR" fetch --tags
LATEST_TAG=$(git --git-dir="$GIT_DIR" describe --tags $(git --git-dir="$GIT_DIR" rev-list --tags --max-count=1))
LATEST_COMMIT=$(git --git-dir="$GIT_DIR" rev-list -n 1 "$LATEST_TAG")
echo "$LATEST_COMMIT"
}
export -f get_latest_release_commit

View file

@ -5,15 +5,15 @@ OURNAME=01_install_commits.sh
apt-get update
apt-get install -y lsb-release ca-certificates curl gnupg
NODE_MAJOR="20"
MONGODB="7.0"
NODE_MAJOR="22"
MONGODB="8.0"
CODENAME=`lsb_release -c -s`
WILDDUCK_COMMIT="9a204f5751ad2bd80baaa3abca95f334fbdf0757"
ZONEMTA_COMMIT="0df73a3946eae0964a166b3015d3ed558d9d024f" # zone-mta-template
WEBMAIL_COMMIT="093cc641782c1a9ca4f498b24ebded23873cb390"
WILDDUCK_ZONEMTA_COMMIT="1f4fad5ba771ce381ef0543e8c9c49ee25e4a6f2"
WILDDUCK_HARAKA_COMMIT="91745b5af70e1d3dfd0fac22d9550f893662ad70"
HARAKA_VERSION="3.0.5"
ARCHITECTURE=$(dpkg --print-architecture)
if [ "$ARCHITECTURE" != "amd64" ] && [ "$ARCHITECTURE" != "arm64" ] && [ "$ARCHITECTURE" != "armhf" ]; then
handle_error "1" "Unsupported architecture: $ARCHITECTURE. Only amd64, arm64, and armhf are supported."
fi
echo -e "\n-- Executing ${ORANGE}${OURNAME}${NC} subscript --"

View file

@ -2,12 +2,12 @@
OURNAME=02_install_prerequisites.sh
# No $AUT_SAFETY variable present, so we have not sourced install_variables.sh yet
# No $AUT_SAFETY variable present, so we have not sourced 00_install_global_functions_variables.sh yet
if [ -z ${AUT_SAFETY+x} ]
then
echo "this script ${RED}called directly${NC}, and not from the main ./install.sh script"
echo "initializing common variables ('install_variables.sh')"
source "$INSTALLDIR/install_variables.sh"
echo "initializing common variables ('00_install_global_functions_variables.sh')"
source "$INSTALLDIR/00_install_global_functions_variables.sh"
fi
echo -e "\n-- Executing ${ORANGE}${OURNAME}${NC} subscript --"

View file

@ -2,13 +2,13 @@
OURNAME=03_install_check_running_services.sh
# No $AUT_SAFETY variable present, so we have not sourced install_variables.sh yet
# No $AUT_SAFETY variable present, so we have not sourced 00_install_global_functions_variables.sh yet
# check if $AUT_SAFETY is unset (as opposed to empty "" string)
if [ -z ${AUT_SAFETY+x} ]
then
echo "this script ${RED}called directly${NC}, and not from the main ./install.sh script"
echo "initializing common variables ('install_variables.sh')"
source "$INSTALLDIR/install_variables.sh"
echo "initializing common variables ('00_install_global_functions_variables.sh')"
source "$INSTALLDIR/00_install_global_functions_variables.sh"
fi
echo -e "\n\n-- Executing ${ORANGE}${OURNAME}${NC} subscript --"

View file

@ -27,14 +27,14 @@ node_key_url="https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key"
local_node_key="${keyring}/nodesource.gpg"
curl -fsSL $node_key_url | gpg --dearmor | tee $local_node_key >/dev/null
echo "deb [signed-by=${local_node_key}] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" > /etc/apt/sources.list.d/nodesource.list
echo "deb-src [signed-by=${local_node_key}] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" >> /etc/apt/sources.list.d/nodesource.list
echo "deb [arch=${ARCHITECTURE} signed-by=${local_node_key}] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" > /etc/apt/sources.list.d/nodesource.list
echo "deb-src [arch=${ARCHITECTURE} signed-by=${local_node_key}] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" >> /etc/apt/sources.list.d/nodesource.list
# mongodb
mongo_key_url="https://pgp.mongodb.com/server-${MONGODB}.asc"
local_mongo_key="${keyring}/mongodb-server-${MONGODB}.gpg"
curl -fsSL $mongo_key_url | gpg --dearmor | tee ${local_mongo_key} >/dev/null
echo "deb [ arch=amd64,arm64 signed-by=${local_mongo_key} ] https://repo.mongodb.org/apt/ubuntu ${CODENAME}/mongodb-org/${MONGODB} multiverse" > /etc/apt/sources.list.d/mongodb-org-${MONGODB}.list
echo "deb [ arch=${ARCHITECTURE} signed-by=${local_mongo_key} ] https://repo.mongodb.org/apt/ubuntu ${CODENAME}/mongodb-org/${MONGODB} multiverse" > /etc/apt/sources.list.d/mongodb-org-${MONGODB}.list
# rspamd
rspamd_key_url="https://rspamd.com/apt-stable/gpg.key"

View file

@ -29,7 +29,7 @@ echo "deploy ALL = (root) NOPASSWD: $SYSTEMCTL_PATH restart wildduck" >> /etc/su
# checkout files from git to working directory
mkdir -p /opt/wildduck
git --git-dir=/var/opt/wildduck.git --work-tree=/opt/wildduck checkout "$WILDDUCK_COMMIT"
git --git-dir=/var/opt/wildduck.git --work-tree=/opt/wildduck checkout $(get_latest_release_commit "wildduck")
cp -r /opt/wildduck/config /etc/wildduck
mv /etc/wildduck/default.toml /etc/wildduck/wildduck.toml
@ -55,7 +55,7 @@ sed -i -e "s/localhost:3000/$HOSTNAME/g;s/localhost/$HOSTNAME/g;s/2587/587/g" /e
sed -i -e "s/secret value/$SRS_SECRET/g;s/#loopSecret/loopSecret/g" /etc/wildduck/sender.toml
cd /opt/wildduck
npm install --production --unsafe-perm --no-optional --no-package-lock --no-audit --ignore-scripts --no-shrinkwrap
npm install --omit=dev --omit=optional --no-package-lock --no-audit --ignore-scripts --no-shrinkwrap
chown -R deploy:deploy /var/opt/wildduck.git
chown -R deploy:deploy /opt/wildduck

View file

@ -25,7 +25,7 @@ echo "#!/bin/bash
git --git-dir=/var/opt/haraka-plugin-wildduck.git --work-tree=/opt/haraka/plugins/wildduck checkout "\$3" -f
cd /opt/haraka/plugins/wildduck
rm -rf package-lock.json
npm install --production --no-optional --no-package-lock --no-audit --ignore-scripts --no-shrinkwrap --progress=false
npm install --omit=dev --omit=optional --no-package-lock --no-audit --ignore-scripts --no-shrinkwrap --progress=false
sudo $SYSTEMCTL_PATH restart haraka || echo \"Failed restarting service\"" > "/var/opt/haraka-plugin-wildduck.git/hooks/update"
chmod +x "/var/opt/haraka-plugin-wildduck.git/hooks/update"
@ -33,17 +33,17 @@ chmod +x "/var/opt/haraka-plugin-wildduck.git/hooks/update"
echo "deploy ALL = (root) NOPASSWD: $SYSTEMCTL_PATH restart haraka" >> /etc/sudoers.d/wildduck
cd
npm install --production --no-optional --no-package-lock --no-audit --no-shrinkwrap --unsafe-perm -g Haraka@$HARAKA_VERSION
npm install --omit=dev --omit=optional --no-package-lock --no-audit --no-shrinkwrap -g Haraka@$HARAKA_VERSION
haraka -i /opt/haraka
cd /opt/haraka
npm install --production --no-optional --no-package-lock --no-audit --no-shrinkwrap --unsafe-perm --save haraka-plugin-rspamd haraka-plugin-redis Haraka@$HARAKA_VERSION
npm install --omit=dev --omit=optional --no-package-lock --no-audit --no-shrinkwrap --save haraka-plugin-rspamd haraka-plugin-redis Haraka@$HARAKA_VERSION
# Haraka WildDuck plugin. Install as separate repo as it can be edited more easily later
mkdir -p plugins/wildduck
git --git-dir=/var/opt/haraka-plugin-wildduck.git --work-tree=/opt/haraka/plugins/wildduck checkout "$WILDDUCK_HARAKA_COMMIT"
git --git-dir=/var/opt/haraka-plugin-wildduck.git --work-tree=/opt/haraka/plugins/wildduck checkout $(get_latest_release_commit "haraka-plugin-wildduck")
cd plugins/wildduck
npm install --production --no-optional --no-package-lock --no-audit --ignore-scripts --no-shrinkwrap --unsafe-perm --progress=false
npm install --omit=dev --omit=optional --no-package-lock --no-audit --ignore-scripts --no-shrinkwrap --progress=false
cd /opt/haraka
mv config/plugins config/plugins.bak

View file

@ -30,7 +30,7 @@ echo "#!/bin/bash
git --git-dir=/var/opt/zonemta-wildduck.git --work-tree=/opt/zone-mta/plugins/wildduck checkout "\$3" -f
cd /opt/zone-mta/plugins/wildduck
rm -rf package-lock.json
npm install --production --no-optional --no-package-lock --no-audit --ignore-scripts --no-shrinkwrap --progress=false
npm install --omit=dev --omit=optional --no-package-lock --no-audit --ignore-scripts --no-shrinkwrap --progress=false
sudo $SYSTEMCTL_PATH restart zone-mta || echo \"Failed restarting service\"" > "/var/opt/zonemta-wildduck.git/hooks/update"
chmod +x "/var/opt/zonemta-wildduck.git/hooks/update"
@ -39,10 +39,10 @@ echo "deploy ALL = (root) NOPASSWD: $SYSTEMCTL_PATH restart zone-mta" >> /etc/su
# checkout files from git to working directory
mkdir -p /opt/zone-mta
git --git-dir=/var/opt/zone-mta.git --work-tree=/opt/zone-mta checkout "$ZONEMTA_COMMIT"
git --git-dir=/var/opt/zone-mta.git --work-tree=/opt/zone-mta checkout $(get_latest_release_commit "zone-mta")
mkdir -p /opt/zone-mta/plugins/wildduck
git --git-dir=/var/opt/zonemta-wildduck.git --work-tree=/opt/zone-mta/plugins/wildduck checkout "$WILDDUCK_ZONEMTA_COMMIT"
git --git-dir=/var/opt/zonemta-wildduck.git --work-tree=/opt/zone-mta/plugins/wildduck checkout $(get_latest_release_commit "zonemta-wildduck")
cp -r /opt/zone-mta/config /etc/zone-mta
sed -i -e 's/port=2525/port=587/g;s/host="127.0.0.1"/host="0.0.0.0"/g;s/authentication=false/authentication=true/g' /etc/zone-mta/interfaces/feeder.toml
@ -100,10 +100,10 @@ DKIM_JSON=`DOMAIN="$MAILDOMAIN" SELECTOR="$DKIM_SELECTOR" node -e 'console.log(J
}))'`
cd /opt/zone-mta
npm install --production --no-optional --no-package-lock --no-audit --ignore-scripts --no-shrinkwrap --unsafe-perm
npm install --omit=dev --omit=optional --no-package-lock --no-audit --ignore-scripts --no-shrinkwrap
cd /opt/zone-mta/plugins/wildduck
npm install --production --no-optional --no-package-lock --no-audit --ignore-scripts --no-shrinkwrap --unsafe-perm
npm install --omit=dev --omit=optional --no-package-lock --no-audit --ignore-scripts --no-shrinkwrap
chown -R deploy:deploy /var/opt/zone-mta.git
chown -R deploy:deploy /var/opt/zonemta-wildduck.git

View file

@ -29,7 +29,7 @@ echo "deploy ALL = (root) NOPASSWD: $SYSTEMCTL_PATH restart wildduck-webmail" >>
# checkout files from git to working directory
mkdir -p /opt/wildduck-webmail
git --git-dir=/var/opt/wildduck-webmail.git --work-tree=/opt/wildduck-webmail checkout "$WEBMAIL_COMMIT"
git --git-dir=/var/opt/wildduck-webmail.git --work-tree=/opt/wildduck-webmail checkout $(get_latest_release_commit "wildduck-webmail")
cp /opt/wildduck-webmail/config/default.toml /etc/wildduck/wildduck-webmail.toml
sed -i -e "s/localhost/$HOSTNAME/g;s/999/99/g;s/2587/587/g;s/proxy=false/proxy=true/g;s/domains=.*/domains=[\"$MAILDOMAIN\"]/g" /etc/wildduck/wildduck-webmail.toml

View file

@ -25,7 +25,10 @@ echo '#!/bin/bash
echo "OK"' > /usr/local/bin/reload-services.sh
chmod +x /usr/local/bin/reload-services.sh
~/.acme.sh/acme.sh --issue --nginx --server letsencrypt \
~/.acme.sh/acme.sh \
--issue \
--nginx \
--server letsencrypt \
-d "$HOSTNAME" \
--key-file /etc/wildduck/certs/privkey.pem \
--fullchain-file /etc/wildduck/certs/fullchain.pem \