lasthourcloud/scripts/install.sh

284 lines
11 KiB
Bash
Raw Normal View History

2023-04-27 09:29:02 +00:00
#!/bin/bash
2023-04-28 12:39:14 +00:00
set -e # Exit immediately if a command exits with a non-zero status
2023-12-11 20:07:40 +00:00
## $1 could be empty, so we need to disable this check
#set -u # Treat unset variables as an error and exit
set -o pipefail # Cause a pipeline to return the status of the last command that exited with a non-zero status
VERSION="1.2.2"
2023-09-05 13:43:56 +00:00
DOCKER_VERSION="24.0"
2023-05-03 07:57:06 +00:00
2024-03-02 03:42:21 +00:00
CDN="https://cdn.lasthourhosting.org/lasthourcloud"
OS_TYPE=$(grep -w "ID" /etc/os-release | cut -d "=" -f 2 | tr -d '"')
if [ "$OS_TYPE" = "arch" ]; then
OS_VERSION="rolling"
else
OS_VERSION=$(grep -w "VERSION_ID" /etc/os-release | cut -d "=" -f 2 | tr -d '"')
fi
LATEST_VERSION=$(wget -q -O - $CDN/versions.json | grep -i version | sed -n '2p' | xargs | awk '{print $2}' | tr -d ',')
DATE=$(date +"%Y%m%d-%H%M%S")
2023-04-27 12:45:45 +00:00
2023-05-03 07:01:58 +00:00
if [ $EUID != 0 ]; then
2023-04-27 09:29:02 +00:00
echo "Please run as root"
exit
fi
2023-11-28 09:46:00 +00:00
case "$OS_TYPE" in
arch | ubuntu | debian | raspbian | centos | fedora | rhel | ol | rocky | sles | opensuse-leap | opensuse-tumbleweed | almalinux) ;;
*)
echo "This script only supports Debian, Redhat, Arch Linux, or SLES based operating systems for now."
exit
;;
esac
2023-06-16 19:42:11 +00:00
2024-01-07 22:32:54 +00:00
# Overwrite LATEST_VERSION if user pass a version number
2023-06-23 11:22:29 +00:00
if [ "$1" != "" ]; then
LATEST_VERSION=$1
LATEST_VERSION="${LATEST_VERSION,,}"
LATEST_VERSION="${LATEST_VERSION#v}"
2023-06-23 11:22:29 +00:00
fi
2023-06-16 19:42:11 +00:00
echo -e "-------------"
2024-03-06 19:55:06 +00:00
echo -e "Welcome to Last Hour Cloud v4 installer!"
2023-06-16 19:42:11 +00:00
echo -e "This script will install everything for you."
2024-03-02 03:17:11 +00:00
echo -e "(Source code: https://githaven.org/Shiloh/lasthourcloud/src/branch/main/scripts/install.sh)\n"
2023-06-16 19:42:11 +00:00
echo -e "-------------"
echo "OS: $OS_TYPE $OS_VERSION"
2024-03-02 02:37:31 +00:00
echo "Last Hour Cloud version: $LATEST_VERSION"
2023-06-16 19:42:11 +00:00
echo -e "-------------"
echo "Installing required packages..."
case "$OS_TYPE" in
arch)
pacman -Sy >/dev/null 2>&1 || true
if ! pacman -Q curl wget git jq >/dev/null 2>&1; then
pacman -S --noconfirm curl wget git jq >/dev/null 2>&1 || true
fi
;;
ubuntu | debian | raspbian)
apt update -y >/dev/null 2>&1
apt install -y curl wget git jq >/dev/null 2>&1
;;
centos | fedora | rhel | ol | rocky | almalinux)
dnf install -y curl wget git jq >/dev/null 2>&1
;;
sles | opensuse-leap | opensuse-tumbleweed)
zypper refresh >/dev/null 2>&1
zypper install -y curl wget git jq >/dev/null 2>&1
;;
*)
echo "This script only supports Debian, Redhat, Arch Linux, or SLES based operating systems for now."
exit
;;
esac
2023-04-27 09:29:02 +00:00
# Detect OpenSSH server
SSH_DETECTED=false
if [ -x "$(command -v systemctl)" ]; then
if systemctl status sshd >/dev/null 2>&1; then
2024-02-16 08:04:32 +00:00
echo "OpenSSH server is installed."
SSH_DETECTED=true
fi
if systemctl status ssh >/dev/null 2>&1; then
echo "OpenSSH server is installed."
SSH_DETECTED=true
fi
elif [ -x "$(command -v service)" ]; then
if service sshd status >/dev/null 2>&1; then
2024-02-16 08:04:32 +00:00
echo "OpenSSH server is installed."
SSH_DETECTED=true
fi
if service ssh status >/dev/null 2>&1; then
echo "OpenSSH server is installed."
SSH_DETECTED=true
fi
fi
if [ "$SSH_DETECTED" = "false" ]; then
echo "###############################################################################"
echo "WARNING: Could not detect if OpenSSH server is installed and running - this does not mean that it is not installed, just that we could not detect it."
2024-03-02 02:37:31 +00:00
echo -e "Please make sure it is set, otherwise Last Hour Cloud cannot connect to the host system. \n"
echo "###############################################################################"
fi
# Detect SSH PermitRootLogin
SSH_PERMIT_ROOT_LOGIN=false
SSH_PERMIT_ROOT_LOGIN_CONFIG=$(grep "^PermitRootLogin" /etc/ssh/sshd_config | awk '{print $2}') || SSH_PERMIT_ROOT_LOGIN_CONFIG="N/A (commented out or not found at all)"
if [ "$SSH_PERMIT_ROOT_LOGIN_CONFIG" = "prohibit-password" ] || [ "$SSH_PERMIT_ROOT_LOGIN_CONFIG" = "yes" ] || [ "$SSH_PERMIT_ROOT_LOGIN_CONFIG" = "without-password" ]; then
echo "PermitRootLogin is enabled."
SSH_PERMIT_ROOT_LOGIN=true
fi
if [ "$SSH_PERMIT_ROOT_LOGIN" != "true" ]; then
echo "###############################################################################"
echo "WARNING: PermitRootLogin is not enabled in /etc/ssh/sshd_config."
echo -e "It is set to $SSH_PERMIT_ROOT_LOGIN_CONFIG. Should be prohibit-password, yes or without-password.\n"
2024-03-02 02:37:31 +00:00
echo -e "Please make sure it is set, otherwise Last Hour Cloud cannot connect to the host system. \n"
echo "(Currently we only support root user to login via SSH, this will be changed in the future.)"
echo "###############################################################################"
fi
2023-04-27 09:29:02 +00:00
if ! [ -x "$(command -v docker)" ]; then
if [ "$OS_TYPE" == 'almalinux' ]; then
dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
if ! [ -x "$(command -v docker)" ]; then
echo "Docker could not be installed automatically. Please visit https://docs.docker.com/engine/install/ and install Docker manually to continue."
exit 1
fi
systemctl start docker
systemctl enable docker
else
set +e
if ! [ -x "$(command -v docker)" ]; then
echo "Docker is not installed. Installing Docker."
if [ "$OS_TYPE" = "arch" ]; then
pacman -Sy docker docker-compose --noconfirm
systemctl enable docker.service
if [ -x "$(command -v docker)" ]; then
echo "Docker installed successfully."
else
echo "Failed to install Docker with pacman. Try to install it manually."
echo "Please visit https://wiki.archlinux.org/title/docker for more information."
exit
fi
else
curl https://releases.rancher.com/install-docker/${DOCKER_VERSION}.sh | sh
if [ -x "$(command -v docker)" ]; then
echo "Docker installed successfully."
else
echo "Docker installation failed with Rancher script. Trying with official script."
curl https://get.docker.com | sh -s -- --version ${DOCKER_VERSION}
if [ -x "$(command -v docker)" ]; then
echo "Docker installed successfully."
else
echo "Docker installation failed with official script."
echo "Maybe your OS is not supported?"
echo "Please visit https://docs.docker.com/engine/install/ and install Docker manually to continue."
exit 1
fi
fi
fi
fi
set -e
2023-11-28 09:46:00 +00:00
fi
2023-04-27 09:29:02 +00:00
fi
2023-06-16 19:42:11 +00:00
echo -e "-------------"
2023-06-19 11:08:34 +00:00
echo -e "Check Docker Configuration..."
2023-06-16 19:42:11 +00:00
mkdir -p /etc/docker
# shellcheck disable=SC2015
test -s /etc/docker/daemon.json && cp /etc/docker/daemon.json /etc/docker/daemon.json.original-"$DATE" || cat >/etc/docker/daemon.json <<EOL
2023-06-16 19:42:11 +00:00
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
EOL
cat >/etc/docker/daemon.json.coolify <<EOL
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
EOL
TEMP_FILE=$(mktemp)
if ! jq -s '.[0] * .[1]' /etc/docker/daemon.json /etc/docker/daemon.json.coolify >"$TEMP_FILE"; then
echo "Error merging JSON files"
exit 1
fi
mv "$TEMP_FILE" /etc/docker/daemon.json
2023-09-28 11:05:17 +00:00
if [ -s /etc/docker/daemon.json.original-"$DATE" ]; then
DIFF=$(diff <(jq --sort-keys . /etc/docker/daemon.json) <(jq --sort-keys . /etc/docker/daemon.json.original-"$DATE"))
2023-09-28 11:05:17 +00:00
if [ "$DIFF" != "" ]; then
echo "Docker configuration updated, restart docker daemon..."
systemctl restart docker
else
echo "Docker configuration is up to date."
fi
else
2023-06-19 11:08:34 +00:00
echo "Docker configuration updated, restart docker daemon..."
systemctl restart docker
fi
2023-06-16 19:42:11 +00:00
echo -e "-------------"
2023-04-27 09:29:02 +00:00
mkdir -p /data/coolify/{source,ssh,applications,databases,backups,services,proxy,webhooks-during-maintenance}
mkdir -p /data/coolify/ssh/{keys,mux}
2023-05-26 07:53:30 +00:00
mkdir -p /data/coolify/proxy/dynamic
2023-04-27 09:29:02 +00:00
2023-04-28 13:30:42 +00:00
echo "Downloading required files from CDN..."
curl -fsSL $CDN/docker-compose.yml -o /data/coolify/source/docker-compose.yml
curl -fsSL $CDN/docker-compose.prod.yml -o /data/coolify/source/docker-compose.prod.yml
curl -fsSL $CDN/.env.production -o /data/coolify/source/.env.production
curl -fsSL $CDN/scripts/upgrade.sh -o /data/coolify/source/upgrade.sh
2023-04-27 09:29:02 +00:00
2024-03-02 02:37:31 +00:00
# echo "Copying required files from Last Hour Cloud git repo..."
# cp /home/lasthour/lasthourcloud/docker-compose.yml /data/coolify/source/docker-compose.yml
# cp /home/lasthour/lasthourcloud/docker-compose.prod.yml /data/coolify/source/docker-compose.prod.yml
# cp /home/lasthour/lasthourcloud/.env.production /data/coolify/source/.env.production
# cp /home/lasthour/lasthourcloud/scripts/upgrade.sh /data/coolify/source/upgrade.sh
chown -R 9999:root /data/coolify
chmod -R 700 /data/coolify
2023-04-27 09:29:02 +00:00
# Copy .env.example if .env does not exist
if [ ! -f /data/coolify/source/.env ]; then
2023-04-27 12:50:42 +00:00
cp /data/coolify/source/.env.production /data/coolify/source/.env
2023-06-16 19:42:11 +00:00
sed -i "s|APP_ID=.*|APP_ID=$(openssl rand -hex 16)|g" /data/coolify/source/.env
2023-04-27 09:29:02 +00:00
sed -i "s|APP_KEY=.*|APP_KEY=base64:$(openssl rand -base64 32)|g" /data/coolify/source/.env
sed -i "s|DB_PASSWORD=.*|DB_PASSWORD=$(openssl rand -base64 32)|g" /data/coolify/source/.env
2023-05-10 07:26:25 +00:00
sed -i "s|REDIS_PASSWORD=.*|REDIS_PASSWORD=$(openssl rand -base64 32)|g" /data/coolify/source/.env
2023-12-05 13:52:19 +00:00
sed -i "s|PUSHER_APP_ID=.*|PUSHER_APP_ID=$(openssl rand -hex 32)|g" /data/coolify/source/.env
sed -i "s|PUSHER_APP_KEY=.*|PUSHER_APP_KEY=$(openssl rand -hex 32)|g" /data/coolify/source/.env
sed -i "s|PUSHER_APP_SECRET=.*|PUSHER_APP_SECRET=$(openssl rand -hex 32)|g" /data/coolify/source/.env
2023-04-27 09:29:02 +00:00
fi
2023-06-12 12:47:42 +00:00
# Merge .env and .env.production. New values will be added to .env
2023-06-16 19:42:11 +00:00
sort -u -t '=' -k 1,1 /data/coolify/source/.env /data/coolify/source/.env.production | sed '/^$/d' >/data/coolify/source/.env.temp && mv /data/coolify/source/.env.temp /data/coolify/source/.env
2023-06-12 12:47:42 +00:00
2023-12-11 20:07:40 +00:00
if [ "$AUTOUPDATE" = "false" ]; then
if ! grep -q "AUTOUPDATE=" /data/coolify/source/.env; then
echo "AUTOUPDATE=false" >>/data/coolify/source/.env
else
sed -i "s|AUTOUPDATE=.*|AUTOUPDATE=false|g" /data/coolify/source/.env
fi
2023-12-11 20:07:40 +00:00
fi
2023-06-23 07:47:36 +00:00
# Generate an ssh key (ed25519) at /data/coolify/ssh/keys/id.root@host.docker.internal
2023-05-25 11:29:15 +00:00
if [ ! -f /data/coolify/ssh/keys/id.root@host.docker.internal ]; then
2023-06-23 07:47:36 +00:00
ssh-keygen -t ed25519 -a 100 -f /data/coolify/ssh/keys/id.root@host.docker.internal -q -N "" -C root@coolify
2023-05-25 11:29:15 +00:00
chown 9999 /data/coolify/ssh/keys/id.root@host.docker.internal
2023-04-27 09:29:02 +00:00
fi
addSshKey() {
2023-06-16 19:42:11 +00:00
cat /data/coolify/ssh/keys/id.root@host.docker.internal.pub >>~/.ssh/authorized_keys
2023-04-27 09:29:02 +00:00
chmod 600 ~/.ssh/authorized_keys
}
2023-04-27 12:45:45 +00:00
if [ ! -f ~/.ssh/authorized_keys ]; then
2023-04-27 09:29:02 +00:00
mkdir -p ~/.ssh
chmod 700 ~/.ssh
touch ~/.ssh/authorized_keys
addSshKey
fi
2023-04-27 12:45:45 +00:00
if ! grep -qw "root@coolify" ~/.ssh/authorized_keys; then
2023-04-27 09:29:02 +00:00
addSshKey
fi
2024-03-02 02:37:31 +00:00
echo "Generated SSH access"
2023-04-27 09:29:02 +00:00
2024-03-02 02:37:31 +00:00
echo "Begin upgrade.sh"
bash /data/coolify/source/upgrade.sh "${LATEST_VERSION:-latest}"
2023-06-16 19:42:11 +00:00
2024-03-02 02:37:31 +00:00
echo -e "\nCongratulations! Your Last Hour Cloud instance is ready to use.\n"
echo "Please visit http://$(curl -4s https://ifconfig.io):8000 to get started."