initial commit

This commit is contained in:
2025-10-26 10:46:10 +00:00
commit 329c33afb1
4 changed files with 535 additions and 0 deletions

296
giteainstall Executable file
View File

@@ -0,0 +1,296 @@
#!/usr/bin/env bash
# Author : Allan Christensen
# First Created : 25082022 (DD-MM-YYYY)
# Description : Installs multiple isolated Gitea instances on Ubuntu 24.04
# License : MIT License (see LICENSE file for details)
#
# Are we root
#
if [[ $(id -u) -ne 0 ]]; then printf "\nMust be root or use sudo.\n\n" ; exit 1 ; fi
#
# Port 3000 must be temporarily free for the Gitea web installer
#
giteaport=3000
if ss -tuln | grep -q ":${giteaport}\b"; then
printf "\nPort %s appears to be in use.\n" "$giteaport"
listener=$(ss -tulpn 2>/dev/null | awk '/:3000\b/ && /LISTEN/ {print $7}' | sed 's/users:(("//; s/",.*//')
if [[ "$listener" == gitea* ]]; then
printf "Detected a running Gitea-related process: %s\n" "$listener"
printf "It looks like another Gitea multi-instance installation has not yet completed.\n"
printf "Please finish its web installer and run its postinstall script before continuing.\n\n"
elif [[ -n "$listener" ]]; then
printf "Process using port 3000 : %s\n" "$listener"
printf "This port is required temporarily by the Gitea web installer.\n"
printf "Please stop or reconfigure that application before running this installer.\n\n"
else
printf "Port 3000 is in use by an unknown process.\n"
printf "Please ensure it is free before running this installer.\n\n"
fi
exit 1
fi
#
# Define variables and functions
#
fallbackversion=$(<fallback)
giteadb="db"
gitealocation="/usr/local/bin/gitea"
usage () {
printf -- "\ngiteainstall-multi\n\n"
printf -- "%s\n\n" "$socket"
printf -- "Usage:\n"
printf -- "sudo ./giteainstall -n <gitea domain> -p <gitea database password> [options]\n\n"
printf -- "Options:\n"
printf -- " -a <mariadb admin user> Optional admin username $socketusage\n"
printf -- " -m <mariadb admin password> Optional admin password $socketusage\n"
printf -- " -h | -help | --help Show this help screen\n\n"
printf -- "Examples:\n"
printf -- " sudo ./giteainstall -n git1.example.com -p gitea1dbpwd\n"
printf -- " sudo ./giteainstall -n git2.example.com -p gitea2dbpwd -m rootpwd\n"
printf -- " sudo ./giteainstall -n git3.example.com -p gitea3dbpwd -a admin -m adminpwd\n\n"
}
serviceno () { printf "\n%s is not running cannot continue...\n\n" "$service"; }
servicedead () { status=$(systemctl is-active "$service"); if [[ "$status" != "active" ]]; then serviceno ; exit ; fi ; }
inputcheck () { [[ -z "$hostname" ]] && { usage ; printf "\nError! Hostname empty.\n\n" ; exit 1 ; } ; [[ -z "$dbpass" ]] && { usage ; printf "\nError! Database password empty.\n\n" ; exit 1 ; } ; }
#
# If Nginx and MariaDB are not running then die
#
service="mariadb" ; servicedead ; service="nginx" ; servicedead
#
# Check MariaDB authentication method (socket or not)
#
if mysql -u root -e ";" 2>/dev/null; then socket="SOCKET DETECTED — no need for -a or -m" ; socketusage="SOCKET DETECTED — these flags are not needed" ; socketauth="yes"
else socket="NO SOCKET DETECTED — you must use -a and -m" ; socketusage="NO SOCKET DETECTED — these flags are required" ; socketauth="no" ; fi
clear
#
# Check for the latest Gitea version
#
version=$(curl -s "https://dl.gitea.com/gitea/version.json" | grep -oP '"version"\s*:\s*"\K[^"]+')
if [[ -z "$version" ]]; then printf "Could not determine latest version. Falling back to version %s\n\n" "$fallbackversion" ; version="$fallbackversion" ; fi
printf "\nUsing Gitea version: %s\n" "$version"
#
# Configure command line options (safe for set -u)
#
firstarg="${1:-}"
if [[ "$firstarg" == "-help" || "$firstarg" == "--help" ]]; then usage ; exit 0 ; fi
if [[ $# -eq 0 || ! "$firstarg" =~ ^- ]]; then usage ; exit 1 ; fi
while getopts "n:p:m:a:h" option; do
case "$option" in
n) hostname=$(echo "$OPTARG" | tr '[:upper:]' '[:lower:]');;
p) dbpass="$OPTARG";;
m) mariadbpwd="$OPTARG";;
a) mariadbadmin="$OPTARG";;
h) usage ; exit 0 ;;
\?) printf "Type sudo %s -h for help\n" "$0" ; exit 1 ;;
esac
done
inputcheck "$hostname" "$dbpass"
#
# Check for existing Nginx host file with same domain
#
hostcheck=$(grep -r --exclude="giteainstall" --exclude="postinstall" --exclude="README.md" "$hostname" /etc/nginx/ 2>/dev/null || true)
if [[ -n "$hostcheck" ]]; then printf "\nFound existing configuration mentioning %s — aborting to avoid collision.\n\n" "$hostname" ; exit 1 ; fi
#
# Create Gitea counter logic
#
mkdir -p /var/lib/gitea
user_counter_file="/var/lib/gitea/giteausercount"
[ ! -f "$user_counter_file" ] && printf "0\n" > "$user_counter_file"
current_user=$(cat "$user_counter_file") ; next_user=$((current_user + 1))
giteauser="gitea$next_user" ; gitea_db="${giteauser}${giteadb}" ; giteaport=$((3000 + next_user))
printf "%s\n" "$next_user" > "$user_counter_file"
#
# Download gitea if not already present
#
if [[ ! -f $gitealocation ]]; then
wget --no-verbose "https://dl.gitea.com/gitea/${version}/gitea-${version}-linux-amd64" -O "$gitealocation" || { printf "\nDownload failed. Check your network connection or version string.\n\n" ; exit 1 ; }
chmod 755 "$gitealocation"
fi
#
# Clone nginx-snippets; if nginx-snippets exists then just pull latest changes
#
nginxsnippets="/etc/nginx/nginx-snippets" ; repo="https://git.x-files.dk/webserver/nginx-snippets.git"
if [[ -d "$nginxsnippets/.git" ]]; then git -C "$nginxsnippets" pull --quiet ; else git clone --quiet "$repo" "$nginxsnippets" ; fi
#
# Escape special characters in the password for MySQL
#
safe_dbpass=$(printf "%s" "$dbpass" | sed "s/'/''/g") ; mariadbadmin="${mariadbadmin:-root}"
printf "\nChecking MariaDB access method...\n"
if [[ "$socketauth" == "yes" ]]; then dbmethod="socket" ; printf "Socket authentication detected (root)\n"
elif [[ -n "${mariadbpwd:-}" && -n "${mariadbadmin:-}" ]]; then dbmethod="admin" ; printf "Using admin user authentication (%s)\n" "$mariadbadmin"
else printf "\nERROR: No valid MariaDB authentication method found.\n" ; exit 1 ; fi
#
# Create Gitea database
#
case "$dbmethod" in
socket)
mysql -u root <<EOF
CREATE DATABASE IF NOT EXISTS $gitea_db;
CREATE USER IF NOT EXISTS '$giteauser'@'localhost' IDENTIFIED BY '${safe_dbpass//\'/\'\\\'\'}';
GRANT ALL PRIVILEGES ON $gitea_db.* TO '$giteauser'@'localhost';
FLUSH PRIVILEGES;
EOF
;;
admin)
mysql -u "$mariadbadmin" -p"$mariadbpwd" <<EOF
CREATE DATABASE IF NOT EXISTS $gitea_db;
CREATE USER IF NOT EXISTS '$giteauser'@'localhost' IDENTIFIED BY '${safe_dbpass//\'/\'\\\'\'}';
GRANT ALL PRIVILEGES ON $gitea_db.* TO '$giteauser'@'localhost';
FLUSH PRIVILEGES;
EOF
;;
esac
#
# Create Gitea temporary Nginx configuration file using port 3000 for web installer
#
cp "$nginxsnippets/hostfiles/gitea-multi.80.conf" /etc/nginx/conf.d/"$hostname".conf
sed -i "s/DOMAIN/$hostname/g" /etc/nginx/conf.d/"$hostname".conf
sed -i "s/GITEAPORT/3000/g" /etc/nginx/conf.d/"$hostname".conf
systemctl restart nginx
#
# Create dedicated Gitea system user and home directory
#
adduser --system --group --disabled-password --shell /bin/bash --home /home/$giteauser --gecos 'Git Version Control' $giteauser
mkdir -p /home/$giteauser/.ssh ; chown -R $giteauser:$giteauser /home/$giteauser ; chmod 700 /home/$giteauser/.ssh
#
# Create Gitea data structure
#
mkdir -p /var/lib/$giteauser/{data,indexers,public,log}
chown "$giteauser":"$giteauser" /var/lib/$giteauser/{data,indexers,log}
chmod 750 /var/lib/$giteauser/{data,indexers,log}
mkdir -p /etc/$giteauser/custom/{templates,public/assets/img}
chown -R $giteauser:$giteauser /etc/$giteauser/custom
chmod -R 750 /etc/$giteauser/custom
mkdir -p /etc/$giteauser ; chown root:"$giteauser" /etc/$giteauser ; chmod 770 /etc/$giteauser
#
# Create systemd service
#
cat > /etc/systemd/system/$giteauser.service <<EOF
[Unit]
Description=Gitea Multi-Instance: $giteauser
After=syslog.target network.target
Requires=mariadb.service
[Service]
LimitMEMLOCK=infinity
LimitNOFILE=65535
RestartSec=2s
Type=simple
User=$giteauser
Group=$giteauser
WorkingDirectory=/var/lib/$giteauser/
ExecStart=/usr/local/bin/gitea web -c /etc/$giteauser/app.ini
Restart=always
Environment=USER=$giteauser HOME=/home/$giteauser GITEA_WORK_DIR=/var/lib/$giteauser GITEA_CUSTOM=/etc/$giteauser/custom
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload ; systemctl enable "$giteauser" ; systemctl start "$giteauser"
#
# Create postinstall script
#
postscript="/etc/$giteauser/gitea-postinstall"
cat > "$postscript" <<EOF
#!/usr/bin/env bash
if [[ \$(id -u) -ne 0 ]]; then printf "\\nMust be root or use sudo.\\n\\n" ; exit 1 ; fi
hostname="$hostname"
giteauser="$giteauser"
giteaport="$giteaport"
cp -Rp /etc/\$giteauser/app.ini /etc/\$giteauser/app.ini.orig
sed -i -E "s/^HTTP_PORT *= *3000/HTTP_PORT = \$giteaport/" /etc/\$giteauser/app.ini
sed -i '/gitea-repositories/a MAX_FILES = 500' /etc/\$giteauser/app.ini
sed -i '/gitea-repositories/a FILE_MAX_SIZE = 200' /etc/\$giteauser/app.ini
sed -i 's/LEVEL = info/LEVEL = warn/' /etc/\$giteauser/app.ini
sed -i 's/MODE = console/MODE = file/' /etc/\$giteauser/app.ini
sed -i 's/DISABLE_SSH = false/DISABLE_SSH = true/' /etc/\$giteauser/app.ini
cat >> /etc/\$giteauser/app.ini <<'INNER_EOF'
[ui.admin]
USER_PAGING_NUM = 50
REPO_PAGING_NUM = 50
NOTICE_PAGING_NUM = 25
ORG_PAGING_NUM = 25
[ui.user]
USER_PAGING_NUM = 50
REPO_PAGING_NUM = 50
NOTICE_PAGING_NUM = 25
ORG_PAGING_NUM = 25
[ui]
THEMES = gitea,arc-green
EXPLORE_PAGING_DEFAULT_SORT = alphabetically
[other]
SHOW_FOOTER_POWERED_BY = false
SHOW_FOOTER_VERSION = false
SHOW_FOOTER_TEMPLATE_LOAD_TIME = false
ENABLE_FEED = false
INNER_EOF
# Update Nginx proxy to final assigned port
sed -i "s/127\\.0\\.0\\.1:3000/127.0.0.1:\$giteaport/" /etc/nginx/conf.d/\$hostname.conf
printf "\\nUpdated Nginx proxy for %s to port %s\\n" "\$hostname" "\$giteaport"
systemctl reload nginx ; systemctl restart \$giteauser
EOF
chmod 755 "$postscript"
#
# Gitea postinstall notice
#
postnotice=$(cat <<EOF
--------------------------------------------------------------------------------------
NEXT STEP: Go to http://$hostname and complete the initial configuration.
--------------------------------------------------------------------------------------
Database Name : $gitea_db
Database User : $giteauser
Database Password: $dbpass
IMPORTANT: Leave the Gitea port unchanged. The postinstall script will take care this.
--------------------------------------------------------------------------------------
IMPORTANT: Once done from a terminal run the following command to finish up
sudo /etc/$giteauser/gitea-postinstall
The HTTP port and more will be automatically adjusted during the postinstall step.
--------------------------------------------------------------------------------------
EOF
)
printf '%s\n' "$postnotice"
printf "Postinstall script saved at: /etc/%s/gitea-postinstall\n" "$giteauser"
printf "\nAll Done...\n"
#
# End of script
#