Add Gitea installation script for Ubuntu 20.04
This commit is contained in:
parent
1d8a4d94ff
commit
56665cba03
|
@ -0,0 +1,500 @@
|
|||
#!/bin/bash
|
||||
|
||||
#############################################################
|
||||
# Author: Taryel Hlontsi, 2023
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
#############################################################
|
||||
|
||||
|
||||
#############################################################
|
||||
# SETUP SECTION, use "sudo" to run the script
|
||||
#############################################################
|
||||
# if set to true, ssh login only with ssh key which must(!) be configured upfront
|
||||
NO_PASSWORD_SSH=true
|
||||
|
||||
# user for gitea, and DB password that should be entered on the initialization web page
|
||||
HOST_USER='git' # better don't change it
|
||||
DB_PASSWORD='PasswordGoesHere'
|
||||
|
||||
GITEA_URL='https://dl.gitea.com/gitea/1.19.3/gitea-1.19.3-linux-arm64'
|
||||
|
||||
# change the IP. If domain is used then set it here as the server name
|
||||
OS_SERVER_NAME="gitea.local"
|
||||
OS_IP="192.168.0.10"
|
||||
OS_COUNTRY="PL"
|
||||
|
||||
# may be left as is
|
||||
LOG_DIR="/home/${SUDO_USER}"
|
||||
LOG="${LOG_DIR}/log.txt"
|
||||
|
||||
#############################################################
|
||||
# HELPER FUNCTIONS
|
||||
#############################################################
|
||||
warn() {
|
||||
PURPLE='\033[1;35m'
|
||||
NC='\033[0m'
|
||||
echo -e "${PURPLE}$1${NC}"
|
||||
echo -e "WARN:\t$1" >> $LOG
|
||||
}
|
||||
|
||||
info() {
|
||||
GREEN='\033[1;32m'
|
||||
NC='\033[0m'
|
||||
echo -e "${GREEN}$1${NC}"
|
||||
echo -e "INFO:\t$1" >> $LOG
|
||||
}
|
||||
|
||||
trace() {
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
echo -e "${YELLOW}$1${NC}"
|
||||
echo -e "TRACE:\t$1" >> $LOG
|
||||
}
|
||||
|
||||
error() {
|
||||
RED='\033[1;31m'
|
||||
NC='\033[0m'
|
||||
echo -e "${RED}$1${NC}"
|
||||
echo -e "ERROR:\t$1" >> $LOG
|
||||
}
|
||||
|
||||
not_set() {
|
||||
count=$(grep -Pcx "$1" "$2")
|
||||
code=$?
|
||||
|
||||
if [[ $code == 2 ]] && [[ -z "$count" ]]; then
|
||||
echo "not_set() func or its caller contains a bug that has to be fixed! param1=${1} param2=${2} code=${code} count=${count}. Exiting!"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
[[ $count == 0 ]] && [[ $code == 1 ]] && return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
not_exist() {
|
||||
if [[ ! -e "$2" ]]; then
|
||||
warn "file does not exist: $2"
|
||||
return 0
|
||||
else
|
||||
count=$(grep -Pc "$1" "$2")
|
||||
code=$?
|
||||
[[ $count == 0 ]] && [[ $code == 1 ]] && return 0
|
||||
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
configure() {
|
||||
if not_exist "$1" "$3"; then
|
||||
warn "setting \"$1\" is not in the file, thus won't be changed"
|
||||
return 1
|
||||
else
|
||||
if not_set "$2" "$3"; then
|
||||
sed -i "s~.*${1}.*~${2}~gi" "$3" &&
|
||||
trace "\"$1\" set to \"$2\"" &&
|
||||
return 0
|
||||
else
|
||||
warn "\"$2\" already set in \"$3\""
|
||||
return 2
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
#############################################################
|
||||
# 1 - ADD USER
|
||||
#############################################################
|
||||
add_user() {
|
||||
info "STEP 1 Adding a user for container"
|
||||
|
||||
sudo adduser \
|
||||
--system \
|
||||
--shell /bin/bash \
|
||||
--gecos 'Git Version Control' \
|
||||
--group \
|
||||
--disabled-password \
|
||||
--home /home/git \
|
||||
git
|
||||
|
||||
[[ $? -gt 0 ]] && { error 'Check git user setup, stopping now'; exit 1; }
|
||||
|
||||
info "STEP 1 done"
|
||||
warn "Press enter to proceed with the next step"; read
|
||||
}
|
||||
|
||||
#############################################################
|
||||
# 2 - CHANGE SERVER NAME
|
||||
#############################################################
|
||||
change_servername() {
|
||||
info "STEP 2 Changing server name to ${OS_SERVER_NAME}"
|
||||
|
||||
echo $OS_SERVER_NAME > /etc/hostname
|
||||
hostentry="127.0.1.1\t${OS_SERVER_NAME}"
|
||||
if not_set "$hostentry" "/etc/hosts"; then
|
||||
echo -e "$hostentry" >> /etc/hosts
|
||||
else
|
||||
warn "\"$hostentry\" already set in \"/etc/hosts\""
|
||||
fi
|
||||
|
||||
info "STEP 2 done"
|
||||
warn "Press enter to proceed with the next step"; read
|
||||
}
|
||||
|
||||
#############################################################
|
||||
# 3 - INSTALL MARIADB
|
||||
#############################################################
|
||||
install_mariadb() {
|
||||
info "STEP 3 Installing Maria DB"
|
||||
|
||||
apt-get -y install mariadb-server > /dev/null
|
||||
systemctl --quiet is-active mariadb || systemctl start mariadb
|
||||
systemctl --quiet is-enabled mariadb || systemctl enable mariadb
|
||||
|
||||
mysql -u root <<EOF
|
||||
CREATE DATABASE IF NOT EXISTS gitea;
|
||||
GRANT ALL PRIVILEGES ON gitea.* TO 'gitea'@'localhost' IDENTIFIED BY '${DB_PASSWORD}';
|
||||
DROP DATABASE IF EXISTS test;
|
||||
DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
|
||||
DELETE FROM mysql.user WHERE User='';
|
||||
DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');
|
||||
ALTER USER 'root'@'localhost' IDENTIFIED BY '${DB_PASSWORD}';
|
||||
FLUSH PRIVILEGES;
|
||||
EOF
|
||||
[[ $? -eq 0 ]] || { error 'Something went bananas while setting up a Maria DB, proceed?'; }
|
||||
|
||||
mysql -u root -p${DB_PASSWORD} -h localhost <<EOF
|
||||
SHOW DATABASES;
|
||||
SELECT User FROM mysql.user;
|
||||
EOF
|
||||
|
||||
info "STEP 3 done"
|
||||
warn "Press enter to proceed with the next step"; read
|
||||
}
|
||||
|
||||
#############################################################
|
||||
# 4 - INSTALL NGINX
|
||||
#############################################################
|
||||
install_nginx() {
|
||||
info "STEP 4 Installing Nginx"
|
||||
|
||||
which nginx && { warn 'Nginx already installed. Since there might be other sites configured on the server, advised to proceed with manual configuration of Nginx:
|
||||
- main config: /etc/nginx/nginx.conf
|
||||
- sites: /etc/nginx/sites-available
|
||||
- linked to: /etc/nginx/sites-enabled
|
||||
- logs: /var/log/nginx'; return 1; }
|
||||
|
||||
KEY="/etc/ssl/private/gitea-snakeoil.key"
|
||||
CRT="/etc/ssl/certs/gitea-snakeoil.crt"
|
||||
|
||||
trace "Generating a self signed sertificate (${KEY} and ${CRT})"
|
||||
|
||||
openssl req -x509 \
|
||||
-nodes \
|
||||
-days 2048 \
|
||||
-newkey rsa:2048 \
|
||||
-keyout $KEY \
|
||||
-out $CRT \
|
||||
-subj "/C=${OS_COUNTRY}/ST=${OS_COUNTRY}/L=${OS_COUNTRY}/O=E Corp/OU=IT/CN=${OS_SERVER_NAME}/emailAddress=info@example.com"
|
||||
|
||||
apt-get install -y nginx > /dev/null
|
||||
systemctl --quiet is-active nginx || systemctl start nginx
|
||||
ufw allow 'Nginx Full'
|
||||
|
||||
trace "Rewriting default /etc/nginx/nginx.conf"
|
||||
cat <<EOF | tee /etc/nginx/nginx.conf
|
||||
user www-data;
|
||||
worker_processes auto;
|
||||
pid /run/nginx.pid;
|
||||
include /etc/nginx/modules-enabled/*.conf;
|
||||
|
||||
events {
|
||||
worker_connections 768;
|
||||
}
|
||||
|
||||
http {
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 10m;
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
keepalive_timeout 70;
|
||||
types_hash_max_size 2048;
|
||||
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
ssl_protocols TLSv1.3;
|
||||
ssl_prefer_server_ciphers on;
|
||||
|
||||
access_log /var/log/nginx/access.log;
|
||||
error_log /var/log/nginx/error.log;
|
||||
|
||||
gzip on;
|
||||
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
include /etc/nginx/sites-enabled/*;
|
||||
}
|
||||
EOF
|
||||
|
||||
trace "Generating a new config /etc/nginx/sites-available/${OS_SERVER_NAME}.conf"
|
||||
|
||||
cat <<EOF | tee /etc/nginx/sites-available/${OS_SERVER_NAME}.conf
|
||||
server {
|
||||
listen 80;
|
||||
server_name ${OS_SERVER_NAME};
|
||||
return 301 https://${OS_SERVER_NAME}$request_uri;
|
||||
access_log /var/log/nginx/${OS_SERVER_NAME}-access.log;
|
||||
error_log /var/log/nginx/${OS_SERVER_NAME}-error.log;
|
||||
}
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
|
||||
server_name ${OS_SERVER_NAME};
|
||||
client_max_body_size 256m;
|
||||
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
|
||||
ssl_certificate ${CRT};
|
||||
ssl_certificate_key ${KEY};
|
||||
|
||||
location / {
|
||||
proxy_redirect off;
|
||||
proxy_pass http://localhost:3000/;
|
||||
}
|
||||
|
||||
access_log /var/log/nginx/${OS_SERVER_NAME}-access.log;
|
||||
error_log /var/log/nginx/${OS_SERVER_NAME}-error.log;
|
||||
}
|
||||
EOF
|
||||
|
||||
trace 'Making a link from sites-available to sites-enabled...'
|
||||
|
||||
ln -s /etc/nginx/sites-available/${OS_SERVER_NAME}.conf \
|
||||
/etc/nginx/sites-enabled
|
||||
nginx -t
|
||||
|
||||
info "STEP 4 done"
|
||||
warn "Press enter to proceed with the next step"; read
|
||||
}
|
||||
|
||||
#############################################################
|
||||
# 5 - INSTALL GITEA
|
||||
#############################################################
|
||||
install_gitea() {
|
||||
info "STEP 5 Installing Gitea as a binary"
|
||||
|
||||
trace "Downloading ${GITEA_URL}"
|
||||
|
||||
apt-get install -y git wget > /dev/null
|
||||
wget --continue $GITEA_URL --output-document gitea
|
||||
chmod +x gitea
|
||||
chown git:git gitea
|
||||
|
||||
trace 'Creating nessesary directories with git owner'
|
||||
|
||||
mkdir -p /var/lib/gitea/{custom,data,log}
|
||||
chown -Rv git:git /var/lib/gitea/
|
||||
chmod -Rv 750 /var/lib/gitea/
|
||||
mkdir /etc/gitea
|
||||
chown root:git /etc/gitea
|
||||
chmod 770 /etc/gitea
|
||||
cp --force gitea /usr/local/bin/gitea
|
||||
|
||||
cat <<EOF | tee /etc/systemd/system/gitea.service
|
||||
[Unit]
|
||||
Description=Gitea (Git with a cup of tea)
|
||||
DefaultDependencies=no
|
||||
After=syslog.target
|
||||
After=network.target
|
||||
Wants=mariadb.service
|
||||
After=mariadb.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=git
|
||||
Group=git
|
||||
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
|
||||
Environment=GITEA_WORK_DIR=/var/lib/gitea/
|
||||
Restart=always
|
||||
RestartSec=5s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
EOF
|
||||
trace 'Installing a systemd service'
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl --quiet is-enabled gitea || systemctl enable gitea
|
||||
systemctl restart gitea
|
||||
gitea --version
|
||||
|
||||
info "STEP 5 done"
|
||||
warn "Press enter to proceed with the next step"; read
|
||||
}
|
||||
|
||||
#############################################################
|
||||
# 6 - ADDITIONAL SECURITY FOR THE SERVER
|
||||
#############################################################
|
||||
secure_server() {
|
||||
info "STEP 6 Securing the server"
|
||||
|
||||
trace "Installing openssh server..."
|
||||
apt-get install -y openssh-server > /dev/null
|
||||
systemctl --quiet is-active sshd || systemctl start sshd
|
||||
systemctl --quiet is-enabled sshd || systemctl enable sshd
|
||||
|
||||
SSH_CFG="/etc/ssh/sshd_config"
|
||||
SSH_CFG_BACK="${LOG_DIR}/sshd_config.backup"
|
||||
|
||||
trace "Going to rewrite ${SSH_CFG}"
|
||||
trace "Backup will be here: ${SSH_CFG_BACK}"
|
||||
|
||||
if [[ -e "$SSH_CFG_BACK" ]]; then
|
||||
warn "SSH config backup is already there!"
|
||||
else
|
||||
cp $SSH_CFG $SSH_CFG_BACK
|
||||
cat <<EOF | tee ${SSH_CFG}
|
||||
Include /etc/ssh/sshd_config.d/*.conf
|
||||
PermitRootLogin no
|
||||
ChallengeResponseAuthentication no
|
||||
UsePAM yes
|
||||
X11Forwarding yes
|
||||
PrintMotd no
|
||||
AcceptEnv LANG LC_*
|
||||
Subsystem sftp /usr/lib/openssh/sftp-server
|
||||
EOF
|
||||
if $NO_PASSWORD_SSH; then
|
||||
info "Disabling SSH with password completely!"
|
||||
echo 'PasswordAuthentication no' >> $SSH_CFG
|
||||
fi
|
||||
fi
|
||||
|
||||
trace "Installing fail2ban..."
|
||||
apt-get install -y fail2ban > /dev/null
|
||||
systemctl --quiet is-active fail2ban || systemctl start fail2ban
|
||||
systemctl --quiet is-enabled fail2ban || systemctl enable fail2ban
|
||||
fail2ban-client status
|
||||
F2B_CFG_ORIG="/etc/fail2ban/jail.conf"
|
||||
F2B_CFG_COPY="/etc/fail2ban/jail.local"
|
||||
if [[ -e "$F2B_CFG_COPY" ]]; then
|
||||
warn "Fail2ban was already set up"
|
||||
else
|
||||
cp $F2B_CFG_ORIG $F2B_CFG_COPY
|
||||
trace "Setting up ${F2B_CFG_COPY}"
|
||||
configure 'bantime = 10m' 'bantime = 60m' $F2B_CFG_COPY
|
||||
configure 'maxretry = 5' 'maxretry = 20' $F2B_CFG_COPY
|
||||
fi
|
||||
|
||||
trace "Configuring ufw..."
|
||||
ufw --force enable
|
||||
ufw allow 'OpenSSH'
|
||||
ufw status
|
||||
|
||||
info "STEP 6 done"
|
||||
warn "Press enter to proceed with the next step"; read
|
||||
}
|
||||
|
||||
#############################################################
|
||||
# 7 - MAKE AN UPDATE HELPER (AS A SCRIPT)
|
||||
#############################################################
|
||||
create_updater() {
|
||||
info 'Step 7 Create an updater for gitea (small helper utility)'
|
||||
|
||||
MY_HOME="/home/${SUDO_USER}"
|
||||
SCRIPT='/usr/local/bin/gitea-update'
|
||||
|
||||
cat <<EOF | tee $SCRIPT
|
||||
#!/bin/bash
|
||||
|
||||
user=\$(whoami)
|
||||
if [[ \$user != root ]]; then
|
||||
echo 'You are using a non-privileged account'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ \$# -eq 0 ]]; then
|
||||
echo 'Provide a web link to the bin file as an argument!'
|
||||
echo "Example: gitea-update $GITEA_URL"
|
||||
exit 1
|
||||
else
|
||||
echo "Link: \$1"
|
||||
fi
|
||||
|
||||
mkdir -p "${MY_HOME}" > /dev/null
|
||||
cd "${MY_HOME}"
|
||||
|
||||
gitea --version
|
||||
wget --continue \$1 --output-document gitea
|
||||
systemctl stop gitea
|
||||
chmod +x gitea
|
||||
chown git:git gitea
|
||||
cp --force gitea /usr/local/bin/gitea
|
||||
systemctl restart gitea
|
||||
gitea --version
|
||||
|
||||
EOF
|
||||
|
||||
chmod +x $SCRIPT
|
||||
|
||||
trace "Updater has been created. call it 'sudo gitea-update url_to_new_version'"
|
||||
|
||||
info 'Step 7 done'
|
||||
}
|
||||
|
||||
#############################################################
|
||||
# RUN SECTION
|
||||
#############################################################
|
||||
user=$(whoami)
|
||||
if [ $user != root ]; then
|
||||
error "You are using a non-privileged account"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo $(date +'%Y-%m-%d %H:%M') > $LOG
|
||||
|
||||
info "Hiya!"
|
||||
|
||||
sudo apt update
|
||||
sudo apt upgrade -y
|
||||
|
||||
add_user
|
||||
change_servername
|
||||
install_mariadb
|
||||
install_nginx
|
||||
install_gitea
|
||||
secure_server
|
||||
create_updater
|
||||
|
||||
info "Don't forget to reboot"
|
||||
info "Bye!"
|
||||
info "PS. Log is here: ${LOG}"
|
||||
warn "REBOOT NOW!!!"
|
||||
|
||||
exit 0
|
||||
|
||||
# restart is mandatory!!!
|
||||
|
||||
# if a real domain is available - a certificate can be obtained, for examle:
|
||||
# sudo apt install certbot python3-certbot-nginx
|
||||
# sudo certbot --nginx -d gittar.crabdance.com
|
||||
# sudo certbot renew --dry-run
|
||||
|
||||
# gitea can be upgraded or downgraded by executing
|
||||
# sudo gitea-update 'https://dl.gitea.com/gitea/1.19.3/gitea-1.19.3-linux-arm64'
|
||||
# however before running it ensure there is no old gitea file in the home dir
|
||||
# otherwise it will install the same version again (such 'safety' measure;))
|
Loading…
Reference in New Issue