From 4b592b93e8757bd73e3b94316274a9de93001489 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 29 Aug 2025 15:22:30 +0200 Subject: [PATCH 01/80] chore: remove unused files --- scripts/install-1.6.sh | 571 ----------------------------- scripts/install-1.7.sh | 789 ----------------------------------------- 2 files changed, 1360 deletions(-) delete mode 100644 scripts/install-1.6.sh delete mode 100755 scripts/install-1.7.sh diff --git a/scripts/install-1.6.sh b/scripts/install-1.6.sh deleted file mode 100644 index 50bce4e55..000000000 --- a/scripts/install-1.6.sh +++ /dev/null @@ -1,571 +0,0 @@ -#!/bin/bash -## Do not modify this file. You will lose the ability to install and auto-update! - -set -e # Exit immediately if a command exits with a non-zero status -## $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 -CDN="https://cdn.coollabs.io/coolify" -DATE=$(date +"%Y%m%d-%H%M%S") - -VERSION="1.6" -DOCKER_VERSION="27.0" -# TODO: Ask for a user -CURRENT_USER=$USER - -if [ $EUID != 0 ]; then - echo "Please run this script as root or with sudo" - exit -fi - -echo -e "Welcome to Coolify Installer!" -echo -e "This script will install everything for you. Sit back and relax." -echo -e "Source code: https://github.com/coollabsio/coolify/blob/main/scripts/install.sh\n" - -# Predefined root user -ROOT_USERNAME=${ROOT_USERNAME:-} -ROOT_USER_EMAIL=${ROOT_USER_EMAIL:-} -ROOT_USER_PASSWORD=${ROOT_USER_PASSWORD:-} - -TOTAL_SPACE=$(df -BG / | awk 'NR==2 {print $2}' | sed 's/G//') -AVAILABLE_SPACE=$(df -BG / | awk 'NR==2 {print $4}' | sed 's/G//') -REQUIRED_TOTAL_SPACE=30 -REQUIRED_AVAILABLE_SPACE=20 -WARNING_SPACE=false - -if [ "$TOTAL_SPACE" -lt "$REQUIRED_TOTAL_SPACE" ]; then - WARNING_SPACE=true - cat < >(tee -a $INSTALLATION_LOG_WITH_DATE) 2>&1 - -getAJoke() { - JOKES=$(curl -s --max-time 2 "https://v2.jokeapi.dev/joke/Programming?blacklistFlags=nsfw,religious,political,racist,sexist,explicit&format=txt&type=single" || true) - if [ "$JOKES" != "" ]; then - echo -e " - Until then, here's a joke for you:\n" - echo -e "$JOKES\n" - fi -} -OS_TYPE=$(grep -w "ID" /etc/os-release | cut -d "=" -f 2 | tr -d '"') -ENV_FILE="/data/coolify/source/.env" - -# Check if the OS is manjaro, if so, change it to arch -if [ "$OS_TYPE" = "manjaro" ] || [ "$OS_TYPE" = "manjaro-arm" ]; then - OS_TYPE="arch" -fi - -# Check if the OS is Endeavour OS, if so, change it to arch -if [ "$OS_TYPE" = "endeavouros" ]; then - OS_TYPE="arch" -fi - -# Check if the OS is Asahi Linux, if so, change it to fedora -if [ "$OS_TYPE" = "fedora-asahi-remix" ]; then - OS_TYPE="fedora" -fi - -# Check if the OS is popOS, if so, change it to ubuntu -if [ "$OS_TYPE" = "pop" ]; then - OS_TYPE="ubuntu" -fi - -# Check if the OS is linuxmint, if so, change it to ubuntu -if [ "$OS_TYPE" = "linuxmint" ]; then - OS_TYPE="ubuntu" -fi - -#Check if the OS is zorin, if so, change it to ubuntu -if [ "$OS_TYPE" = "zorin" ]; then - OS_TYPE="ubuntu" -fi - -if [ "$OS_TYPE" = "arch" ] || [ "$OS_TYPE" = "archarm" ]; then - OS_VERSION="rolling" -else - OS_VERSION=$(grep -w "VERSION_ID" /etc/os-release | cut -d "=" -f 2 | tr -d '"') -fi - -# Install xargs on Amazon Linux 2023 - lol -if [ "$OS_TYPE" = 'amzn' ]; then - dnf install -y findutils >/dev/null -fi - -LATEST_VERSION=$(curl --silent $CDN/versions.json | grep -i version | xargs | awk '{print $2}' | tr -d ',') -LATEST_HELPER_VERSION=$(curl --silent $CDN/versions.json | grep -i version | xargs | awk '{print $6}' | tr -d ',') -LATEST_REALTIME_VERSION=$(curl --silent $CDN/versions.json | grep -i version | xargs | awk '{print $8}' | tr -d ',') - -if [ -z "$LATEST_HELPER_VERSION" ]; then - LATEST_HELPER_VERSION=latest -fi - -if [ -z "$LATEST_REALTIME_VERSION" ]; then - LATEST_REALTIME_VERSION=latest -fi - -case "$OS_TYPE" in -arch | ubuntu | debian | raspbian | centos | fedora | rhel | ol | rocky | sles | opensuse-leap | opensuse-tumbleweed | almalinux | amzn | alpine) ;; -*) - echo "This script only supports Debian, Redhat, Arch Linux, Alpine Linux, or SLES based operating systems for now." - exit - ;; -esac - -# Overwrite LATEST_VERSION if user pass a version number -if [ "$1" != "" ]; then - LATEST_VERSION=$1 - LATEST_VERSION="${LATEST_VERSION,,}" - LATEST_VERSION="${LATEST_VERSION#v}" -fi - -echo -e "---------------------------------------------" -echo "| Operating System | $OS_TYPE $OS_VERSION" -echo "| Docker | $DOCKER_VERSION" -echo "| Coolify | $LATEST_VERSION" -echo "| Helper | $LATEST_HELPER_VERSION" -echo "| Realtime | $LATEST_REALTIME_VERSION" -echo -e "---------------------------------------------\n" -echo -e "1. Installing required packages (curl, wget, git, jq, openssl). " - -case "$OS_TYPE" in -arch) - pacman -Sy --noconfirm --needed curl wget git jq openssl >/dev/null || true - ;; -alpine) - sed -i '/^#.*\/community/s/^#//' /etc/apk/repositories - apk update >/dev/null - apk add curl wget git jq openssl >/dev/null - ;; -ubuntu | debian | raspbian) - apt-get update -y >/dev/null - apt-get install -y curl wget git jq openssl >/dev/null - ;; -centos | fedora | rhel | ol | rocky | almalinux | amzn) - if [ "$OS_TYPE" = "amzn" ]; then - dnf install -y wget git jq openssl >/dev/null - else - if ! command -v dnf >/dev/null; then - yum install -y dnf >/dev/null - fi - if ! command -v curl >/dev/null; then - dnf install -y curl >/dev/null - fi - dnf install -y wget git jq openssl >/dev/null - fi - ;; -sles | opensuse-leap | opensuse-tumbleweed) - zypper refresh >/dev/null - zypper install -y curl wget git jq openssl >/dev/null - ;; -*) - echo "This script only supports Debian, Redhat, Arch Linux, or SLES based operating systems for now." - exit - ;; -esac - -echo -e "2. Check OpenSSH server configuration. " - -# Detect OpenSSH server -SSH_DETECTED=false -if [ -x "$(command -v systemctl)" ]; then - if systemctl status sshd >/dev/null 2>&1; then - echo " - OpenSSH server is installed." - SSH_DETECTED=true - elif 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 - echo " - OpenSSH server is installed." - SSH_DETECTED=true - elif service ssh status >/dev/null 2>&1; then - echo " - OpenSSH server is installed." - SSH_DETECTED=true - fi -fi - -if [ "$SSH_DETECTED" = "false" ]; then - echo " - OpenSSH server not detected. Installing OpenSSH server." - case "$OS_TYPE" in - arch) - pacman -Sy --noconfirm openssh >/dev/null - systemctl enable sshd >/dev/null 2>&1 - systemctl start sshd >/dev/null 2>&1 - ;; - alpine) - apk add openssh >/dev/null - rc-update add sshd default >/dev/null 2>&1 - service sshd start >/dev/null 2>&1 - ;; - ubuntu | debian | raspbian) - apt-get update -y >/dev/null - apt-get install -y openssh-server >/dev/null - systemctl enable ssh >/dev/null 2>&1 - systemctl start ssh >/dev/null 2>&1 - ;; - centos | fedora | rhel | ol | rocky | almalinux | amzn) - if [ "$OS_TYPE" = "amzn" ]; then - dnf install -y openssh-server >/dev/null - else - dnf install -y openssh-server >/dev/null - fi - systemctl enable sshd >/dev/null 2>&1 - systemctl start sshd >/dev/null 2>&1 - ;; - sles | opensuse-leap | opensuse-tumbleweed) - zypper install -y openssh >/dev/null - systemctl enable sshd >/dev/null 2>&1 - systemctl start sshd >/dev/null 2>&1 - ;; - *) - echo "###############################################################################" - echo "WARNING: Could not detect and install OpenSSH server - this does not mean that it is not installed or not running, just that we could not detect it." - echo -e "Please make sure it is installed and running, otherwise Coolify cannot connect to the host system. \n" - echo "###############################################################################" - exit 1 - ;; - esac - echo " - OpenSSH server installed successfully." - SSH_DETECTED=true -fi - -# Detect SSH PermitRootLogin -SSH_PERMIT_ROOT_LOGIN=$(sshd -T | grep -i "permitrootlogin" | awk '{print $2}') || true -if [ "$SSH_PERMIT_ROOT_LOGIN" = "yes" ] || [ "$SSH_PERMIT_ROOT_LOGIN" = "without-password" ] || [ "$SSH_PERMIT_ROOT_LOGIN" = "prohibit-password" ]; then - echo " - SSH PermitRootLogin is enabled." -else - echo " - SSH PermitRootLogin is disabled." - echo " If you have problems with SSH, please read this: https://coolify.io/docs/knowledge-base/server/openssh" -fi - -# Detect if docker is installed via snap -if [ -x "$(command -v snap)" ]; then - SNAP_DOCKER_INSTALLED=$(snap list docker >/dev/null 2>&1 && echo "true" || echo "false") - if [ "$SNAP_DOCKER_INSTALLED" = "true" ]; then - echo " - Docker is installed via snap." - echo " Please note that Coolify does not support Docker installed via snap." - echo " Please remove Docker with snap (snap remove docker) and reexecute this script." - exit 1 - fi -fi - -echo -e "3. Check Docker Installation. " -if ! [ -x "$(command -v docker)" ]; then - echo " - Docker is not installed. Installing Docker. It may take a while." - getAJoke - case "$OS_TYPE" in - "almalinux") - dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo >/dev/null 2>&1 - dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin >/dev/null 2>&1 - 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 >/dev/null 2>&1 - systemctl enable docker >/dev/null 2>&1 - ;; - "alpine") - apk add docker docker-cli-compose >/dev/null 2>&1 - rc-update add docker default >/dev/null 2>&1 - service docker start >/dev/null 2>&1 - if ! [ -x "$(command -v docker)" ]; then - echo " - Failed to install Docker with apk. Try to install it manually." - echo " Please visit https://wiki.alpinelinux.org/wiki/Docker for more information." - exit 1 - fi - ;; - "arch") - pacman -Sy docker docker-compose --noconfirm >/dev/null 2>&1 - systemctl enable docker.service >/dev/null 2>&1 - if ! [ -x "$(command -v docker)" ]; then - 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 1 - fi - ;; - "amzn") - dnf install docker -y >/dev/null 2>&1 - DOCKER_CONFIG=${DOCKER_CONFIG:-/usr/local/lib/docker} - mkdir -p $DOCKER_CONFIG/cli-plugins >/dev/null 2>&1 - curl -sL https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o $DOCKER_CONFIG/cli-plugins/docker-compose >/dev/null 2>&1 - chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose >/dev/null 2>&1 - systemctl start docker >/dev/null 2>&1 - systemctl enable docker >/dev/null 2>&1 - if ! [ -x "$(command -v docker)" ]; then - echo " - Failed to install Docker with dnf. Try to install it manually." - echo " Please visit https://www.cyberciti.biz/faq/how-to-install-docker-on-amazon-linux-2/ for more information." - exit 1 - fi - ;; - "fedora") - if [ -x "$(command -v dnf5)" ]; then - # dnf5 is available - dnf config-manager addrepo --from-repofile=https://download.docker.com/linux/fedora/docker-ce.repo --overwrite >/dev/null 2>&1 - else - # dnf5 is not available, use dnf - dnf config-manager --add-repo=https://download.docker.com/linux/fedora/docker-ce.repo >/dev/null 2>&1 - fi - dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin >/dev/null 2>&1 - 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 >/dev/null 2>&1 - systemctl enable docker >/dev/null 2>&1 - ;; - *) - if [ "$OS_TYPE" = "ubuntu" ] && [ "$OS_VERSION" = "24.10" ]; then - echo "Docker automated installation is not supported on Ubuntu 24.10 (non-LTS release)." - echo "Please install Docker manually." - exit 1 - fi - curl -s https://releases.rancher.com/install-docker/${DOCKER_VERSION}.sh | sh 2>&1 - if ! [ -x "$(command -v docker)" ]; then - curl -s https://get.docker.com | sh -s -- --version ${DOCKER_VERSION} 2>&1 - if ! [ -x "$(command -v docker)" ]; then - echo " - Docker installation failed." - 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 - ;; - esac - echo " - Docker installed successfully." -else - echo " - Docker is installed." -fi - -echo -e "4. Check Docker Configuration. " -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 </etc/docker/daemon.json.coolify <"$TEMP_FILE"; then - echo "Error merging JSON files" - exit 1 -fi -mv "$TEMP_FILE" /etc/docker/daemon.json - -restart_docker_service() { - # Check if systemctl is available - if command -v systemctl >/dev/null 2>&1; then - echo " - Using systemctl to restart Docker." - systemctl restart docker - - if [ $? -eq 0 ]; then - echo " - Docker restarted successfully using systemctl." - else - echo " - Failed to restart Docker using systemctl." - return 1 - fi - - # Check if service command is available - elif command -v service >/dev/null 2>&1; then - echo " - Using service command to restart Docker." - service docker restart - - if [ $? -eq 0 ]; then - echo " - Docker restarted successfully using service." - else - echo " - Failed to restart Docker using service." - return 1 - fi - - # If neither systemctl nor service is available - else - echo " - Neither systemctl nor service command is available on this system." - return 1 - fi -} - -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")) - if [ "$DIFF" != "" ]; then - echo " - Docker configuration updated, restart docker daemon..." - restart_docker_service - else - echo " - Docker configuration is up to date." - fi -else - echo " - Docker configuration updated, restart docker daemon..." - restart_docker_service -fi - -echo -e "5. Download 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/upgrade.sh -o /data/coolify/source/upgrade.sh - -echo -e "6. Make backup of .env to .env-$DATE" - -# Copy .env.example if .env does not exist -if [ -f $ENV_FILE ]; then - cp $ENV_FILE $ENV_FILE-$DATE -else - echo " - File does not exist: $ENV_FILE" - echo " - Copying .env.production to .env-$DATE" - cp /data/coolify/source/.env.production $ENV_FILE-$DATE - # Generate a secure APP_ID and APP_KEY - sed -i "s|^APP_ID=.*|APP_ID=$(openssl rand -hex 16)|" "$ENV_FILE-$DATE" - sed -i "s|^APP_KEY=.*|APP_KEY=base64:$(openssl rand -base64 32)|" "$ENV_FILE-$DATE" - - # Generate a secure Postgres DB username and password - # Causes issues: database "random-user" does not exist - # sed -i "s|^DB_USERNAME=.*|DB_USERNAME=$(openssl rand -hex 16)|" "$ENV_FILE-$DATE" - sed -i "s|^DB_PASSWORD=.*|DB_PASSWORD=$(openssl rand -base64 32)|" "$ENV_FILE-$DATE" - - # Generate a secure Redis password - sed -i "s|^REDIS_PASSWORD=.*|REDIS_PASSWORD=$(openssl rand -base64 32)|" "$ENV_FILE-$DATE" - - # Generate secure Pusher credentials - sed -i "s|^PUSHER_APP_ID=.*|PUSHER_APP_ID=$(openssl rand -hex 32)|" "$ENV_FILE-$DATE" - sed -i "s|^PUSHER_APP_KEY=.*|PUSHER_APP_KEY=$(openssl rand -hex 32)|" "$ENV_FILE-$DATE" - sed -i "s|^PUSHER_APP_SECRET=.*|PUSHER_APP_SECRET=$(openssl rand -hex 32)|" "$ENV_FILE-$DATE" -fi - -# Add default root user credentials from environment variables -if [ -n "$ROOT_USERNAME" ] && [ -n "$ROOT_USER_EMAIL" ] && [ -n "$ROOT_USER_PASSWORD" ]; then - if grep -q "^ROOT_USERNAME=" "$ENV_FILE-$DATE"; then - sed -i "s|^ROOT_USERNAME=.*|ROOT_USERNAME=$ROOT_USERNAME|" "$ENV_FILE-$DATE" - fi - if grep -q "^ROOT_USER_EMAIL=" "$ENV_FILE-$DATE"; then - sed -i "s|^ROOT_USER_EMAIL=.*|ROOT_USER_EMAIL=$ROOT_USER_EMAIL|" "$ENV_FILE-$DATE" - fi - if grep -q "^ROOT_USER_PASSWORD=" "$ENV_FILE-$DATE"; then - sed -i "s|^ROOT_USER_PASSWORD=.*|ROOT_USER_PASSWORD=$ROOT_USER_PASSWORD|" "$ENV_FILE-$DATE" - fi -fi - -# Merge .env and .env.production. New values will be added to .env -echo -e "7. Propagating .env with new values - if necessary." -awk -F '=' '!seen[$1]++' "$ENV_FILE-$DATE" /data/coolify/source/.env.production >$ENV_FILE - -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 -fi -echo -e "8. Checking for SSH key for localhost access." -if [ ! -f ~/.ssh/authorized_keys ]; then - mkdir -p ~/.ssh - chmod 700 ~/.ssh - touch ~/.ssh/authorized_keys - chmod 600 ~/.ssh/authorized_keys -fi - -set +e -IS_COOLIFY_VOLUME_EXISTS=$(docker volume ls | grep coolify-db | wc -l) -set -e - -if [ "$IS_COOLIFY_VOLUME_EXISTS" -eq 0 ]; then - echo " - Generating SSH key." - ssh-keygen -t ed25519 -a 100 -f /data/coolify/ssh/keys/id.$CURRENT_USER@host.docker.internal -q -N "" -C coolify - chown 9999 /data/coolify/ssh/keys/id.$CURRENT_USER@host.docker.internal - sed -i "/coolify/d" ~/.ssh/authorized_keys - cat /data/coolify/ssh/keys/id.$CURRENT_USER@host.docker.internal.pub >>~/.ssh/authorized_keys - rm -f /data/coolify/ssh/keys/id.$CURRENT_USER@host.docker.internal.pub -fi - -chown -R 9999:root /data/coolify -chmod -R 700 /data/coolify - -echo -e "9. Installing Coolify ($LATEST_VERSION)" -echo -e " - It could take a while based on your server's performance, network speed, stars, etc." -echo -e " - Please wait." -getAJoke - -bash /data/coolify/source/upgrade.sh "${LATEST_VERSION:-latest}" "${LATEST_HELPER_VERSION:-latest}" -echo " - Coolify installed successfully." -rm -f $ENV_FILE-$DATE - -echo " - Waiting for 20 seconds for Coolify (database migrations) to be ready." -getAJoke - -sleep 20 -echo -e "\033[0;35m - ____ _ _ _ _ _ - / ___|___ _ __ __ _ _ __ __ _| |_ _ _| | __ _| |_(_) ___ _ __ ___| | - | | / _ \| '_ \ / _\` | '__/ _\` | __| | | | |/ _\` | __| |/ _ \| '_ \/ __| | - | |__| (_) | | | | (_| | | | (_| | |_| |_| | | (_| | |_| | (_) | | | \__ \_| - \____\___/|_| |_|\__, |_| \__,_|\__|\__,_|_|\__,_|\__|_|\___/|_| |_|___(_) - |___/ -\033[0m" -echo -e "\nYour instance is ready to use!\n" -echo -e "You can access Coolify through your Public IP: http://$(curl -4s https://ifconfig.io):8000" - -set +e -DEFAULT_PRIVATE_IP=$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p') -PRIVATE_IPS=$(hostname -I 2>/dev/null || ip -o addr show scope global | awk '{print $4}' | cut -d/ -f1) -set -e - -if [ -n "$PRIVATE_IPS" ]; then - echo -e "\nIf your Public IP is not accessible, you can use the following Private IPs:\n" - for IP in $PRIVATE_IPS; do - if [ "$IP" != "$DEFAULT_PRIVATE_IP" ]; then - echo -e "http://$IP:8000" - fi - done -fi -echo -e "\nWARNING: It is highly recommended to backup your Environment variables file (/data/coolify/source/.env) to a safe location, outside of this server (e.g. into a Password Manager).\n" -cp /data/coolify/source/.env /data/coolify/source/.env.backup diff --git a/scripts/install-1.7.sh b/scripts/install-1.7.sh deleted file mode 100755 index 282ecc669..000000000 --- a/scripts/install-1.7.sh +++ /dev/null @@ -1,789 +0,0 @@ -#!/bin/bash -## Do not modify this file. You will lose the ability to install and auto-update! - -## Environment variables that can be set: -## ROOT_USERNAME - Predefined root username -## ROOT_USER_EMAIL - Predefined root user email -## ROOT_USER_PASSWORD - Predefined root user password -## DOCKER_ADDRESS_POOL_BASE - Custom Docker address pool base (default: 10.0.0.0/8) -## DOCKER_ADDRESS_POOL_SIZE - Custom Docker address pool size (default: 24) -## DOCKER_POOL_FORCE_OVERRIDE - Force override Docker address pool configuration (default: false) -## AUTOUPDATE - Set to "false" to disable auto-updates - -set -e # Exit immediately if a command exits with a non-zero status -## $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 -CDN="https://cdn.coollabs.io/coolify" -DATE=$(date +"%Y%m%d-%H%M%S") - -VERSION="1.7" -DOCKER_VERSION="27.0" -# TODO: Ask for a user -CURRENT_USER=$USER - -if [ $EUID != 0 ]; then - echo "Please run this script as root or with sudo" - exit -fi - -echo -e "Welcome to Coolify Installer!" -echo -e "This script will install everything for you. Sit back and relax." -echo -e "Source code: https://github.com/coollabsio/coolify/blob/main/scripts/install.sh\n" - -# Predefined root user -ROOT_USERNAME=${ROOT_USERNAME:-} -ROOT_USER_EMAIL=${ROOT_USER_EMAIL:-} -ROOT_USER_PASSWORD=${ROOT_USER_PASSWORD:-} - -# Docker address pool configuration defaults -DOCKER_ADDRESS_POOL_BASE_DEFAULT="10.0.0.0/8" -DOCKER_ADDRESS_POOL_SIZE_DEFAULT=24 - -# Check if environment variables were explicitly provided -DOCKER_POOL_BASE_PROVIDED=false -DOCKER_POOL_SIZE_PROVIDED=false -DOCKER_POOL_FORCE_OVERRIDE=${DOCKER_POOL_FORCE_OVERRIDE:-false} - -if [ -n "${DOCKER_ADDRESS_POOL_BASE+x}" ]; then - DOCKER_POOL_BASE_PROVIDED=true -fi - -if [ -n "${DOCKER_ADDRESS_POOL_SIZE+x}" ]; then - DOCKER_POOL_SIZE_PROVIDED=true -fi - -restart_docker_service() { - # Check if systemctl is available - if command -v systemctl >/dev/null 2>&1; then - systemctl restart docker - if [ $? -eq 0 ]; then - echo " - Docker daemon restarted successfully" - else - echo " - Failed to restart Docker daemon" - return 1 - fi - # Check if service command is available - elif command -v service >/dev/null 2>&1; then - service docker restart - if [ $? -eq 0 ]; then - echo " - Docker daemon restarted successfully" - else - echo " - Failed to restart Docker daemon" - return 1 - fi - # If neither systemctl nor service is available - else - echo " - Error: No service management system found" - return 1 - fi -} - -# Function to compare address pools -compare_address_pools() { - local base1="$1" - local size1="$2" - local base2="$3" - local size2="$4" - - # Normalize CIDR notation for comparison - local ip1=$(echo "$base1" | cut -d'/' -f1) - local prefix1=$(echo "$base1" | cut -d'/' -f2) - local ip2=$(echo "$base2" | cut -d'/' -f1) - local prefix2=$(echo "$base2" | cut -d'/' -f2) - - # Compare IPs and prefixes - if [ "$ip1" = "$ip2" ] && [ "$prefix1" = "$prefix2" ] && [ "$size1" = "$size2" ]; then - return 0 # Pools are the same - else - return 1 # Pools are different - fi -} - -# Docker address pool configuration -DOCKER_ADDRESS_POOL_BASE=${DOCKER_ADDRESS_POOL_BASE:-"$DOCKER_ADDRESS_POOL_BASE_DEFAULT"} -DOCKER_ADDRESS_POOL_SIZE=${DOCKER_ADDRESS_POOL_SIZE:-$DOCKER_ADDRESS_POOL_SIZE_DEFAULT} - -# Load Docker address pool configuration from .env file if it exists and environment variables were not provided -if [ -f "/data/coolify/source/.env" ] && [ "$DOCKER_POOL_BASE_PROVIDED" = false ] && [ "$DOCKER_POOL_SIZE_PROVIDED" = false ]; then - ENV_DOCKER_ADDRESS_POOL_BASE=$(grep -E "^DOCKER_ADDRESS_POOL_BASE=" /data/coolify/source/.env | cut -d '=' -f2) - ENV_DOCKER_ADDRESS_POOL_SIZE=$(grep -E "^DOCKER_ADDRESS_POOL_SIZE=" /data/coolify/source/.env | cut -d '=' -f2) - - if [ -n "$ENV_DOCKER_ADDRESS_POOL_BASE" ]; then - DOCKER_ADDRESS_POOL_BASE="$ENV_DOCKER_ADDRESS_POOL_BASE" - fi - - if [ -n "$ENV_DOCKER_ADDRESS_POOL_SIZE" ]; then - DOCKER_ADDRESS_POOL_SIZE="$ENV_DOCKER_ADDRESS_POOL_SIZE" - fi -fi - -# Check if daemon.json exists and extract existing address pool configuration -EXISTING_POOL_CONFIGURED=false -if [ -f /etc/docker/daemon.json ]; then - if jq -e '.["default-address-pools"]' /etc/docker/daemon.json >/dev/null 2>&1; then - EXISTING_POOL_BASE=$(jq -r '.["default-address-pools"][0].base' /etc/docker/daemon.json 2>/dev/null) - EXISTING_POOL_SIZE=$(jq -r '.["default-address-pools"][0].size' /etc/docker/daemon.json 2>/dev/null) - - if [ -n "$EXISTING_POOL_BASE" ] && [ -n "$EXISTING_POOL_SIZE" ] && [ "$EXISTING_POOL_BASE" != "null" ] && [ "$EXISTING_POOL_SIZE" != "null" ]; then - echo "Found existing Docker network pool: $EXISTING_POOL_BASE/$EXISTING_POOL_SIZE" - EXISTING_POOL_CONFIGURED=true - - # Check if environment variables were explicitly provided - if [ "$DOCKER_POOL_BASE_PROVIDED" = false ] && [ "$DOCKER_POOL_SIZE_PROVIDED" = false ]; then - DOCKER_ADDRESS_POOL_BASE="$EXISTING_POOL_BASE" - DOCKER_ADDRESS_POOL_SIZE="$EXISTING_POOL_SIZE" - else - # Check if force override is enabled - if [ "$DOCKER_POOL_FORCE_OVERRIDE" = true ]; then - echo "Force override enabled - network pool will be updated with $DOCKER_ADDRESS_POOL_BASE/$DOCKER_ADDRESS_POOL_SIZE." - else - echo "Custom pool provided but force override not enabled - using existing configuration." - echo "To force override, set DOCKER_POOL_FORCE_OVERRIDE=true" - echo "This won't change the existing docker networks, only the pool configuration for the newly created networks." - DOCKER_ADDRESS_POOL_BASE="$EXISTING_POOL_BASE" - DOCKER_ADDRESS_POOL_SIZE="$EXISTING_POOL_SIZE" - DOCKER_POOL_BASE_PROVIDED=false - DOCKER_POOL_SIZE_PROVIDED=false - fi - fi - fi - fi -fi - -# Validate Docker address pool configuration -if ! [[ $DOCKER_ADDRESS_POOL_BASE =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]+$ ]]; then - echo "Warning: Invalid network pool base format: $DOCKER_ADDRESS_POOL_BASE" - if [ "$EXISTING_POOL_CONFIGURED" = true ]; then - echo "Using existing configuration: $EXISTING_POOL_BASE" - DOCKER_ADDRESS_POOL_BASE="$EXISTING_POOL_BASE" - else - echo "Using default configuration: $DOCKER_ADDRESS_POOL_BASE_DEFAULT" - DOCKER_ADDRESS_POOL_BASE="$DOCKER_ADDRESS_POOL_BASE_DEFAULT" - fi -fi - -if ! [[ $DOCKER_ADDRESS_POOL_SIZE =~ ^[0-9]+$ ]] || [ "$DOCKER_ADDRESS_POOL_SIZE" -lt 16 ] || [ "$DOCKER_ADDRESS_POOL_SIZE" -gt 28 ]; then - echo "Warning: Invalid network pool size: $DOCKER_ADDRESS_POOL_SIZE (must be 16-28)" - if [ "$EXISTING_POOL_CONFIGURED" = true ]; then - echo "Using existing configuration: $EXISTING_POOL_SIZE" - DOCKER_ADDRESS_POOL_SIZE="$EXISTING_POOL_SIZE" - else - echo "Using default configuration: $DOCKER_ADDRESS_POOL_SIZE_DEFAULT" - DOCKER_ADDRESS_POOL_SIZE=$DOCKER_ADDRESS_POOL_SIZE_DEFAULT - fi -fi - -TOTAL_SPACE=$(df -BG / | awk 'NR==2 {print $2}' | sed 's/G//') -AVAILABLE_SPACE=$(df -BG / | awk 'NR==2 {print $4}' | sed 's/G//') -REQUIRED_TOTAL_SPACE=30 -REQUIRED_AVAILABLE_SPACE=20 -WARNING_SPACE=false - -if [ "$TOTAL_SPACE" -lt "$REQUIRED_TOTAL_SPACE" ]; then - WARNING_SPACE=true - cat < >(tee -a $INSTALLATION_LOG_WITH_DATE) 2>&1 - -getAJoke() { - JOKES=$(curl -s --max-time 2 "https://v2.jokeapi.dev/joke/Programming?blacklistFlags=nsfw,religious,political,racist,sexist,explicit&format=txt&type=single" || true) - if [ "$JOKES" != "" ]; then - echo -e " - Until then, here's a joke for you:\n" - echo -e "$JOKES\n" - fi -} -OS_TYPE=$(grep -w "ID" /etc/os-release | cut -d "=" -f 2 | tr -d '"') -ENV_FILE="/data/coolify/source/.env" - -# Check if the OS is manjaro, if so, change it to arch -if [ "$OS_TYPE" = "manjaro" ] || [ "$OS_TYPE" = "manjaro-arm" ]; then - OS_TYPE="arch" -fi - -# Check if the OS is Endeavour OS, if so, change it to arch -if [ "$OS_TYPE" = "endeavouros" ]; then - OS_TYPE="arch" -fi - -# Check if the OS is Asahi Linux, if so, change it to fedora -if [ "$OS_TYPE" = "fedora-asahi-remix" ]; then - OS_TYPE="fedora" -fi - -# Check if the OS is popOS, if so, change it to ubuntu -if [ "$OS_TYPE" = "pop" ]; then - OS_TYPE="ubuntu" -fi - -# Check if the OS is linuxmint, if so, change it to ubuntu -if [ "$OS_TYPE" = "linuxmint" ]; then - OS_TYPE="ubuntu" -fi - -#Check if the OS is zorin, if so, change it to ubuntu -if [ "$OS_TYPE" = "zorin" ]; then - OS_TYPE="ubuntu" -fi - -if [ "$OS_TYPE" = "arch" ] || [ "$OS_TYPE" = "archarm" ]; then - OS_VERSION="rolling" -else - OS_VERSION=$(grep -w "VERSION_ID" /etc/os-release | cut -d "=" -f 2 | tr -d '"') -fi - -# Install xargs on Amazon Linux 2023 - lol -if [ "$OS_TYPE" = 'amzn' ]; then - dnf install -y findutils >/dev/null -fi - -LATEST_VERSION=$(curl --silent $CDN/versions.json | grep -i version | xargs | awk '{print $2}' | tr -d ',') -LATEST_HELPER_VERSION=$(curl --silent $CDN/versions.json | grep -i version | xargs | awk '{print $6}' | tr -d ',') -LATEST_REALTIME_VERSION=$(curl --silent $CDN/versions.json | grep -i version | xargs | awk '{print $8}' | tr -d ',') - -if [ -z "$LATEST_HELPER_VERSION" ]; then - LATEST_HELPER_VERSION=latest -fi - -if [ -z "$LATEST_REALTIME_VERSION" ]; then - LATEST_REALTIME_VERSION=latest -fi - -case "$OS_TYPE" in -arch | ubuntu | debian | raspbian | centos | fedora | rhel | ol | rocky | sles | opensuse-leap | opensuse-tumbleweed | almalinux | amzn | alpine) ;; -*) - echo "This script only supports Debian, Redhat, Arch Linux, Alpine Linux, or SLES based operating systems for now." - exit - ;; -esac - -# Overwrite LATEST_VERSION if user pass a version number -if [ "$1" != "" ]; then - LATEST_VERSION=$1 - LATEST_VERSION="${LATEST_VERSION,,}" - LATEST_VERSION="${LATEST_VERSION#v}" -fi - -echo -e "---------------------------------------------" -echo "| Operating System | $OS_TYPE $OS_VERSION" -echo "| Docker | $DOCKER_VERSION" -echo "| Coolify | $LATEST_VERSION" -echo "| Helper | $LATEST_HELPER_VERSION" -echo "| Realtime | $LATEST_REALTIME_VERSION" -echo "| Docker Pool | $DOCKER_ADDRESS_POOL_BASE (size $DOCKER_ADDRESS_POOL_SIZE)" -echo -e "---------------------------------------------\n" -echo -e "1. Installing required packages (curl, wget, git, jq, openssl). " - -case "$OS_TYPE" in -arch) - pacman -Sy --noconfirm --needed curl wget git jq openssl >/dev/null || true - ;; -alpine) - sed -i '/^#.*\/community/s/^#//' /etc/apk/repositories - apk update >/dev/null - apk add curl wget git jq openssl >/dev/null - ;; -ubuntu | debian | raspbian) - apt-get update -y >/dev/null - apt-get install -y curl wget git jq openssl >/dev/null - ;; -centos | fedora | rhel | ol | rocky | almalinux | amzn) - if [ "$OS_TYPE" = "amzn" ]; then - dnf install -y wget git jq openssl >/dev/null - else - if ! command -v dnf >/dev/null; then - yum install -y dnf >/dev/null - fi - if ! command -v curl >/dev/null; then - dnf install -y curl >/dev/null - fi - dnf install -y wget git jq openssl >/dev/null - fi - ;; -sles | opensuse-leap | opensuse-tumbleweed) - zypper refresh >/dev/null - zypper install -y curl wget git jq openssl >/dev/null - ;; -*) - echo "This script only supports Debian, Redhat, Arch Linux, or SLES based operating systems for now." - exit - ;; -esac - -echo -e "2. Check OpenSSH server configuration. " - -# Detect OpenSSH server -SSH_DETECTED=false -if [ -x "$(command -v systemctl)" ]; then - if systemctl status sshd >/dev/null 2>&1; then - echo " - OpenSSH server is installed." - SSH_DETECTED=true - elif 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 - echo " - OpenSSH server is installed." - SSH_DETECTED=true - elif service ssh status >/dev/null 2>&1; then - echo " - OpenSSH server is installed." - SSH_DETECTED=true - fi -fi - -if [ "$SSH_DETECTED" = "false" ]; then - echo " - OpenSSH server not detected. Installing OpenSSH server." - case "$OS_TYPE" in - arch) - pacman -Sy --noconfirm openssh >/dev/null - systemctl enable sshd >/dev/null 2>&1 - systemctl start sshd >/dev/null 2>&1 - ;; - alpine) - apk add openssh >/dev/null - rc-update add sshd default >/dev/null 2>&1 - service sshd start >/dev/null 2>&1 - ;; - ubuntu | debian | raspbian) - apt-get update -y >/dev/null - apt-get install -y openssh-server >/dev/null - systemctl enable ssh >/dev/null 2>&1 - systemctl start ssh >/dev/null 2>&1 - ;; - centos | fedora | rhel | ol | rocky | almalinux | amzn) - if [ "$OS_TYPE" = "amzn" ]; then - dnf install -y openssh-server >/dev/null - else - dnf install -y openssh-server >/dev/null - fi - systemctl enable sshd >/dev/null 2>&1 - systemctl start sshd >/dev/null 2>&1 - ;; - sles | opensuse-leap | opensuse-tumbleweed) - zypper install -y openssh >/dev/null - systemctl enable sshd >/dev/null 2>&1 - systemctl start sshd >/dev/null 2>&1 - ;; - *) - echo "###############################################################################" - echo "WARNING: Could not detect and install OpenSSH server - this does not mean that it is not installed or not running, just that we could not detect it." - echo -e "Please make sure it is installed and running, otherwise Coolify cannot connect to the host system. \n" - echo "###############################################################################" - exit 1 - ;; - esac - echo " - OpenSSH server installed successfully." - SSH_DETECTED=true -fi - -# Detect SSH PermitRootLogin -SSH_PERMIT_ROOT_LOGIN=$(sshd -T | grep -i "permitrootlogin" | awk '{print $2}') || true -if [ "$SSH_PERMIT_ROOT_LOGIN" = "yes" ] || [ "$SSH_PERMIT_ROOT_LOGIN" = "without-password" ] || [ "$SSH_PERMIT_ROOT_LOGIN" = "prohibit-password" ]; then - echo " - SSH PermitRootLogin is enabled." -else - echo " - SSH PermitRootLogin is disabled." - echo " If you have problems with SSH, please read this: https://coolify.io/docs/knowledge-base/server/openssh" -fi - -# Detect if docker is installed via snap -if [ -x "$(command -v snap)" ]; then - SNAP_DOCKER_INSTALLED=$(snap list docker >/dev/null 2>&1 && echo "true" || echo "false") - if [ "$SNAP_DOCKER_INSTALLED" = "true" ]; then - echo " - Docker is installed via snap." - echo " Please note that Coolify does not support Docker installed via snap." - echo " Please remove Docker with snap (snap remove docker) and reexecute this script." - exit 1 - fi -fi - -echo -e "3. Check Docker Installation. " -if ! [ -x "$(command -v docker)" ]; then - echo " - Docker is not installed. Installing Docker. It may take a while." - getAJoke - case "$OS_TYPE" in - "almalinux") - dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo >/dev/null 2>&1 - dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin >/dev/null 2>&1 - 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 >/dev/null 2>&1 - systemctl enable docker >/dev/null 2>&1 - ;; - "alpine") - apk add docker docker-cli-compose >/dev/null 2>&1 - rc-update add docker default >/dev/null 2>&1 - service docker start >/dev/null 2>&1 - if ! [ -x "$(command -v docker)" ]; then - echo " - Failed to install Docker with apk. Try to install it manually." - echo " Please visit https://wiki.alpinelinux.org/wiki/Docker for more information." - exit 1 - fi - ;; - "arch") - pacman -Sy docker docker-compose --noconfirm >/dev/null 2>&1 - systemctl enable docker.service >/dev/null 2>&1 - if ! [ -x "$(command -v docker)" ]; then - 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 1 - fi - ;; - "amzn") - dnf install docker -y >/dev/null 2>&1 - DOCKER_CONFIG=${DOCKER_CONFIG:-/usr/local/lib/docker} - mkdir -p $DOCKER_CONFIG/cli-plugins >/dev/null 2>&1 - curl -sL https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o $DOCKER_CONFIG/cli-plugins/docker-compose >/dev/null 2>&1 - chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose >/dev/null 2>&1 - systemctl start docker >/dev/null 2>&1 - systemctl enable docker >/dev/null 2>&1 - if ! [ -x "$(command -v docker)" ]; then - echo " - Failed to install Docker with dnf. Try to install it manually." - echo " Please visit https://www.cyberciti.biz/faq/how-to-install-docker-on-amazon-linux-2/ for more information." - exit 1 - fi - ;; - "centos" | "fedora" | "rhel") - if [ -x "$(command -v dnf5)" ]; then - # dnf5 is available - dnf config-manager addrepo --from-repofile=https://download.docker.com/linux/$OS_TYPE/docker-ce.repo --overwrite >/dev/null 2>&1 - else - # dnf5 is not available, use dnf - dnf config-manager --add-repo=https://download.docker.com/linux/$OS_TYPE/docker-ce.repo >/dev/null 2>&1 - fi - dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin >/dev/null 2>&1 - 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 >/dev/null 2>&1 - systemctl enable docker >/dev/null 2>&1 - ;; - *) - if [ "$OS_TYPE" = "ubuntu" ] && [ "$OS_VERSION" = "24.10" ]; then - echo "Docker automated installation is not supported on Ubuntu 24.10 (non-LTS release)." - echo "Please install Docker manually." - exit 1 - fi - curl -s https://releases.rancher.com/install-docker/${DOCKER_VERSION}.sh | sh 2>&1 - if ! [ -x "$(command -v docker)" ]; then - curl -s https://get.docker.com | sh -s -- --version ${DOCKER_VERSION} 2>&1 - if ! [ -x "$(command -v docker)" ]; then - echo " - Docker installation failed." - 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 - ;; - esac - echo " - Docker installed successfully." -else - echo " - Docker is installed." -fi - -echo -e "4. Check Docker Configuration. " - -echo " - Network pool configuration: ${DOCKER_ADDRESS_POOL_BASE}/${DOCKER_ADDRESS_POOL_SIZE}" -echo " - To override existing configuration: DOCKER_POOL_FORCE_OVERRIDE=true" - -mkdir -p /etc/docker - -# Backup original daemon.json if it exists -if [ -f /etc/docker/daemon.json ]; then - cp /etc/docker/daemon.json /etc/docker/daemon.json.original-"$DATE" -fi - -# Create coolify configuration with or without address pools based on whether they were explicitly provided -if [ "$DOCKER_POOL_FORCE_OVERRIDE" = true ] || [ "$EXISTING_POOL_CONFIGURED" = false ]; then - # First check if the configuration would actually change anything - if [ -f /etc/docker/daemon.json ]; then - CURRENT_POOL_BASE=$(jq -r '.["default-address-pools"][0].base' /etc/docker/daemon.json 2>/dev/null) - CURRENT_POOL_SIZE=$(jq -r '.["default-address-pools"][0].size' /etc/docker/daemon.json 2>/dev/null) - - if [ "$CURRENT_POOL_BASE" = "$DOCKER_ADDRESS_POOL_BASE" ] && [ "$CURRENT_POOL_SIZE" = "$DOCKER_ADDRESS_POOL_SIZE" ]; then - echo " - Network pool configuration unchanged, skipping update" - NEED_MERGE=false - else - # If force override is enabled or no existing configuration exists, - # create a new configuration with the specified address pools - echo " - Creating new Docker configuration with network pool: ${DOCKER_ADDRESS_POOL_BASE}/${DOCKER_ADDRESS_POOL_SIZE}" - cat >/etc/docker/daemon.json </etc/docker/daemon.json </dev/null 2>&1; then - echo " - Log configuration is up to date" - NEED_MERGE=false - else - # Create a configuration without address pools to preserve existing ones - cat >/etc/docker/daemon.json.coolify </etc/docker/daemon.json <$ENV_FILE - -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 -fi - -# Save Docker address pool configuration to .env file -if ! grep -q "DOCKER_ADDRESS_POOL_BASE=" /data/coolify/source/.env; then - echo "DOCKER_ADDRESS_POOL_BASE=$DOCKER_ADDRESS_POOL_BASE" >>/data/coolify/source/.env -else - # Only update if explicitly provided - if [ "$DOCKER_POOL_BASE_PROVIDED" = true ]; then - sed -i "s|DOCKER_ADDRESS_POOL_BASE=.*|DOCKER_ADDRESS_POOL_BASE=$DOCKER_ADDRESS_POOL_BASE|g" /data/coolify/source/.env - fi -fi - -if ! grep -q "DOCKER_ADDRESS_POOL_SIZE=" /data/coolify/source/.env; then - echo "DOCKER_ADDRESS_POOL_SIZE=$DOCKER_ADDRESS_POOL_SIZE" >>/data/coolify/source/.env -else - # Only update if explicitly provided - if [ "$DOCKER_POOL_SIZE_PROVIDED" = true ]; then - sed -i "s|DOCKER_ADDRESS_POOL_SIZE=.*|DOCKER_ADDRESS_POOL_SIZE=$DOCKER_ADDRESS_POOL_SIZE|g" /data/coolify/source/.env - fi -fi - -echo -e "8. Checking for SSH key for localhost access." -if [ ! -f ~/.ssh/authorized_keys ]; then - mkdir -p ~/.ssh - chmod 700 ~/.ssh - touch ~/.ssh/authorized_keys - chmod 600 ~/.ssh/authorized_keys -fi - -set +e -IS_COOLIFY_VOLUME_EXISTS=$(docker volume ls | grep coolify-db | wc -l) -set -e - -if [ "$IS_COOLIFY_VOLUME_EXISTS" -eq 0 ]; then - echo " - Generating SSH key." - ssh-keygen -t ed25519 -a 100 -f /data/coolify/ssh/keys/id.$CURRENT_USER@host.docker.internal -q -N "" -C coolify - chown 9999 /data/coolify/ssh/keys/id.$CURRENT_USER@host.docker.internal - sed -i "/coolify/d" ~/.ssh/authorized_keys - cat /data/coolify/ssh/keys/id.$CURRENT_USER@host.docker.internal.pub >>~/.ssh/authorized_keys - rm -f /data/coolify/ssh/keys/id.$CURRENT_USER@host.docker.internal.pub -fi - -chown -R 9999:root /data/coolify -chmod -R 700 /data/coolify - -echo -e "9. Installing Coolify ($LATEST_VERSION)" -echo -e " - It could take a while based on your server's performance, network speed, stars, etc." -echo -e " - Please wait." -getAJoke - -bash /data/coolify/source/upgrade.sh "${LATEST_VERSION:-latest}" "${LATEST_HELPER_VERSION:-latest}" -echo " - Coolify installed successfully." -rm -f $ENV_FILE-$DATE - -echo " - Waiting for 20 seconds for Coolify (database migrations) to be ready." -getAJoke - -sleep 20 -echo -e "\033[0;35m - ____ _ _ _ _ _ - / ___|___ _ __ __ _ _ __ __ _| |_ _ _| | __ _| |_(_) ___ _ __ ___| | - | | / _ \| '_ \ / _\` | '__/ _\` | __| | | | |/ _\` | __| |/ _ \| '_ \/ __| | - | |__| (_) | | | | (_| | | | (_| | |_| |_| | | (_| | |_| | (_) | | | \__ \_| - \____\___/|_| |_|\__, |_| \__,_|\__|\__,_|_|\__,_|\__|_|\___/|_| |_|___(_) - |___/ -\033[0m" -echo -e "\nYour instance is ready to use!\n" -echo -e "You can access Coolify through your Public IP: http://$(curl -4s https://ifconfig.io):8000" - -set +e -DEFAULT_PRIVATE_IP=$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p') -PRIVATE_IPS=$(hostname -I 2>/dev/null || ip -o addr show scope global | awk '{print $4}' | cut -d/ -f1) -set -e - -if [ -n "$PRIVATE_IPS" ]; then - echo -e "\nIf your Public IP is not accessible, you can use the following Private IPs:\n" - for IP in $PRIVATE_IPS; do - if [ "$IP" != "$DEFAULT_PRIVATE_IP" ]; then - echo -e "http://$IP:8000" - fi - done -fi -echo -e "\nWARNING: It is highly recommended to backup your Environment variables file (/data/coolify/source/.env) to a safe location, outside of this server (e.g. into a Password Manager).\n" -cp /data/coolify/source/.env /data/coolify/source/.env.backup From 5b637c1de13d6aae8655a56bd2da17ac9479ff34 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 29 Aug 2025 15:26:28 +0200 Subject: [PATCH 02/80] refactor(installer): improve install script - remove unused VERSION variable. - fix the source code link of the install script. - properly back up the `.env` file on each run of the install script. - do not delete the backup .env file at the end of the install script. - Add improved handling and more logging for updating environment variable values. --- scripts/install.sh | 126 +++++++++++++++++++++------------------------ 1 file changed, 60 insertions(+), 66 deletions(-) diff --git a/scripts/install.sh b/scripts/install.sh index 064fc7e4d..64913d599 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -20,7 +20,6 @@ DATE=$(date +"%Y%m%d-%H%M%S") OS_TYPE=$(grep -w "ID" /etc/os-release | cut -d "=" -f 2 | tr -d '"') ENV_FILE="/data/coolify/source/.env" -VERSION="21" DOCKER_VERSION="27.0" # TODO: Ask for a user CURRENT_USER=$USER @@ -32,7 +31,7 @@ fi echo -e "Welcome to Coolify Installer!" echo -e "This script will install everything for you. Sit back and relax." -echo -e "Source code: https://github.com/coollabsio/coolify/blob/main/scripts/install.sh\n" +echo -e "Source code: https://github.com/coollabsio/coolify/blob/v4.x/scripts/install.sh" # Predefined root user ROOT_USERNAME=${ROOT_USERNAME:-} @@ -711,84 +710,80 @@ curl -fsSL $CDN/docker-compose.prod.yml -o /data/coolify/source/docker-compose.p curl -fsSL $CDN/.env.production -o /data/coolify/source/.env.production curl -fsSL $CDN/upgrade.sh -o /data/coolify/source/upgrade.sh -echo -e "6. Make backup of .env to .env-$DATE" +echo -e "6. Setting up environment variable file" -# Copy .env.example if .env does not exist if [ -f $ENV_FILE ]; then + # If .env exists, create backup + echo " - Creating backup of existing .env file to .env-$DATE" cp $ENV_FILE $ENV_FILE-$DATE + # Merge .env.production values into .env + echo " - Merging .env.production values into .env" + awk -F '=' '!seen[$1]++' $ENV_FILE /data/coolify/source/.env.production > $ENV_FILE.tmp && mv $ENV_FILE.tmp $ENV_FILE + echo " - .env file merged successfully" else - echo " - File does not exist: $ENV_FILE" - echo " - Copying .env.production to .env-$DATE" - cp /data/coolify/source/.env.production $ENV_FILE-$DATE - # Generate a secure APP_ID and APP_KEY - sed -i "s|^APP_ID=.*|APP_ID=$(openssl rand -hex 16)|" "$ENV_FILE-$DATE" - sed -i "s|^APP_KEY=.*|APP_KEY=base64:$(openssl rand -base64 32)|" "$ENV_FILE-$DATE" - - # Generate a secure Postgres DB username and password - # Causes issues: database "random-user" does not exist - # sed -i "s|^DB_USERNAME=.*|DB_USERNAME=$(openssl rand -hex 16)|" "$ENV_FILE-$DATE" - sed -i "s|^DB_PASSWORD=.*|DB_PASSWORD=$(openssl rand -base64 32)|" "$ENV_FILE-$DATE" - - # Generate a secure Redis password - sed -i "s|^REDIS_PASSWORD=.*|REDIS_PASSWORD=$(openssl rand -base64 32)|" "$ENV_FILE-$DATE" - - # Generate secure Pusher credentials - sed -i "s|^PUSHER_APP_ID=.*|PUSHER_APP_ID=$(openssl rand -hex 32)|" "$ENV_FILE-$DATE" - sed -i "s|^PUSHER_APP_KEY=.*|PUSHER_APP_KEY=$(openssl rand -hex 32)|" "$ENV_FILE-$DATE" - sed -i "s|^PUSHER_APP_SECRET=.*|PUSHER_APP_SECRET=$(openssl rand -hex 32)|" "$ENV_FILE-$DATE" + # If no .env exists, copy .env.production to .env + echo " - No .env file found, copying .env.production to .env" + cp /data/coolify/source/.env.production $ENV_FILE fi +echo -e "7. Checking and updating environment variables if necessary..." + +update_env_var() { + local key="$1" + local value="$2" + + # If variable "key=" exists but has no value, update the value of the existing line + if grep -q "^${key}=$" "$ENV_FILE"; then + sed -i "s|^${key}=$|${key}=${value}|" "$ENV_FILE" + echo " - Updated value of ${key} as the current value was empty" + # If variable "key=" doesn't exist, append it to the file with value + elif ! grep -q "^${key}=" "$ENV_FILE"; then + printf '%s=%s\n' "$key" "$value" >>"$ENV_FILE" + echo " - Added ${key} with default value as the variable was missing" + fi +} + +update_env_var "APP_ID" "$(openssl rand -hex 16)" +update_env_var "APP_KEY" "base64:$(openssl rand -base64 32)" +# update_env_var "DB_USERNAME" "$(openssl rand -hex 16)" # Causes issues: database "random-user" does not exist +update_env_var "DB_PASSWORD" "$(openssl rand -base64 32)" +update_env_var "REDIS_PASSWORD" "$(openssl rand -base64 32)" +update_env_var "PUSHER_APP_ID" "$(openssl rand -hex 32)" +update_env_var "PUSHER_APP_KEY" "$(openssl rand -hex 32)" +update_env_var "PUSHER_APP_SECRET" "$(openssl rand -hex 32)" + # Add default root user credentials from environment variables if [ -n "$ROOT_USERNAME" ] && [ -n "$ROOT_USER_EMAIL" ] && [ -n "$ROOT_USER_PASSWORD" ]; then - if grep -q "^ROOT_USERNAME=" "$ENV_FILE-$DATE"; then - sed -i "s|^ROOT_USERNAME=.*|ROOT_USERNAME=$ROOT_USERNAME|" "$ENV_FILE-$DATE" - fi - if grep -q "^ROOT_USER_EMAIL=" "$ENV_FILE-$DATE"; then - sed -i "s|^ROOT_USER_EMAIL=.*|ROOT_USER_EMAIL=$ROOT_USER_EMAIL|" "$ENV_FILE-$DATE" - fi - if grep -q "^ROOT_USER_PASSWORD=" "$ENV_FILE-$DATE"; then - sed -i "s|^ROOT_USER_PASSWORD=.*|ROOT_USER_PASSWORD=$ROOT_USER_PASSWORD|" "$ENV_FILE-$DATE" - fi + echo " - Setting predefined root user credentials from environment" + update_env_var "ROOT_USERNAME" "$ROOT_USERNAME" + update_env_var "ROOT_USER_EMAIL" "$ROOT_USER_EMAIL" + update_env_var "ROOT_USER_PASSWORD" "$ROOT_USER_PASSWORD" fi -# Add registry URL to .env file if [ -n "${REGISTRY_URL+x}" ]; then # Only update if REGISTRY_URL was explicitly provided - if grep -q "^REGISTRY_URL=" "$ENV_FILE-$DATE"; then - sed -i "s|^REGISTRY_URL=.*|REGISTRY_URL=$REGISTRY_URL|" "$ENV_FILE-$DATE" - else - echo "REGISTRY_URL=$REGISTRY_URL" >>"$ENV_FILE-$DATE" - fi + update_env_var "REGISTRY_URL" "$REGISTRY_URL" fi -# Merge .env and .env.production. New values will be added to .env -echo -e "7. Propagating .env with new values - if necessary." -awk -F '=' '!seen[$1]++' "$ENV_FILE-$DATE" /data/coolify/source/.env.production >$ENV_FILE - 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 + update_env_var "AUTOUPDATE" "false" +fi + +if [ "$DOCKER_POOL_BASE_PROVIDED" = true ]; then + update_env_var "DOCKER_ADDRESS_POOL_BASE" "$DOCKER_ADDRESS_POOL_BASE" +else + # Add with default value if missing + if ! grep -q "^DOCKER_ADDRESS_POOL_BASE=" "$ENV_FILE"; then + update_env_var "DOCKER_ADDRESS_POOL_BASE" "$DOCKER_ADDRESS_POOL_BASE" fi fi -# Save Docker address pool configuration to .env file -if ! grep -q "DOCKER_ADDRESS_POOL_BASE=" /data/coolify/source/.env; then - echo "DOCKER_ADDRESS_POOL_BASE=$DOCKER_ADDRESS_POOL_BASE" >>/data/coolify/source/.env +if [ "$DOCKER_POOL_SIZE_PROVIDED" = true ]; then + update_env_var "DOCKER_ADDRESS_POOL_SIZE" "$DOCKER_ADDRESS_POOL_SIZE" else - # Only update if explicitly provided - if [ "$DOCKER_POOL_BASE_PROVIDED" = true ]; then - sed -i "s|DOCKER_ADDRESS_POOL_BASE=.*|DOCKER_ADDRESS_POOL_BASE=$DOCKER_ADDRESS_POOL_BASE|g" /data/coolify/source/.env - fi -fi - -if ! grep -q "DOCKER_ADDRESS_POOL_SIZE=" /data/coolify/source/.env; then - echo "DOCKER_ADDRESS_POOL_SIZE=$DOCKER_ADDRESS_POOL_SIZE" >>/data/coolify/source/.env -else - # Only update if explicitly provided - if [ "$DOCKER_POOL_SIZE_PROVIDED" = true ]; then - sed -i "s|DOCKER_ADDRESS_POOL_SIZE=.*|DOCKER_ADDRESS_POOL_SIZE=$DOCKER_ADDRESS_POOL_SIZE|g" /data/coolify/source/.env + # Add with default value if missing + if ! grep -q "^DOCKER_ADDRESS_POOL_SIZE=" "$ENV_FILE"; then + update_env_var "DOCKER_ADDRESS_POOL_SIZE" "$DOCKER_ADDRESS_POOL_SIZE" fi fi @@ -824,14 +819,13 @@ echo -e " - Please wait." getAJoke if [[ $- == *x* ]]; then - bash -x /data/coolify/source/upgrade.sh "${LATEST_VERSION:-latest}" "${LATEST_HELPER_VERSION:-latest}" "${REGISTRY_URL:-ghcr.io}" + bash -x /data/coolify/source/upgrade.sh "${LATEST_VERSION:-latest}" "${LATEST_HELPER_VERSION:-latest}" "${REGISTRY_URL:-ghcr.io}" "true" else - bash /data/coolify/source/upgrade.sh "${LATEST_VERSION:-latest}" "${LATEST_HELPER_VERSION:-latest}" "${REGISTRY_URL:-ghcr.io}" + bash /data/coolify/source/upgrade.sh "${LATEST_VERSION:-latest}" "${LATEST_HELPER_VERSION:-latest}" "${REGISTRY_URL:-ghcr.io}" "true" fi echo " - Coolify installed successfully." -rm -f $ENV_FILE-$DATE -echo " - Waiting for 20 seconds for Coolify (database migrations) to be ready." +echo " - Waiting for 20 seconds for Coolify database migrations to be ready." getAJoke sleep 20 @@ -868,5 +862,5 @@ if [ -n "$PRIVATE_IPS" ]; then fi done fi + echo -e "\nWARNING: It is highly recommended to backup your Environment variables file (/data/coolify/source/.env) to a safe location, outside of this server (e.g. into a Password Manager).\n" -cp /data/coolify/source/.env /data/coolify/source/.env.backup From 64f3fdc4634974021b9661b0974d9e46e2ffe7e9 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 29 Aug 2025 15:28:31 +0200 Subject: [PATCH 03/80] refactor(upgrade): improve upgrade script - remove unused VERSION variable. - add backup functionality of the .env file on each run of the upgrade script. - skip .env backup when coming from the install script - add improved handling and more logging for updating environment-variable values. - remove not needed line --- scripts/upgrade.sh | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/scripts/upgrade.sh b/scripts/upgrade.sh index 32bffad48..5d52b44fe 100644 --- a/scripts/upgrade.sh +++ b/scripts/upgrade.sh @@ -1,11 +1,12 @@ #!/bin/bash ## Do not modify this file. You will lose the ability to autoupdate! -VERSION="15" CDN="https://cdn.coollabs.io/coolify" LATEST_IMAGE=${1:-latest} LATEST_HELPER_VERSION=${2:-latest} REGISTRY_URL=${3:-ghcr.io} +SKIP_BACKUP=${4:-false} +ENV_FILE="/data/coolify/source/.env" DATE=$(date +%Y-%m-%d-%H-%M-%S) LOGFILE="/data/coolify/source/upgrade-${DATE}.log" @@ -14,20 +15,39 @@ 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 -# Merge .env and .env.production. New values will be added to .env -awk -F '=' '!seen[$1]++' /data/coolify/source/.env /data/coolify/source/.env.production >/data/coolify/source/.env.tmp && mv /data/coolify/source/.env.tmp /data/coolify/source/.env -# Check if PUSHER_APP_ID or PUSHER_APP_KEY or PUSHER_APP_SECRET is empty in /data/coolify/source/.env -if grep -q "PUSHER_APP_ID=$" /data/coolify/source/.env; then - sed -i "s|PUSHER_APP_ID=.*|PUSHER_APP_ID=$(openssl rand -hex 32)|g" /data/coolify/source/.env +# Backup existing .env file before making any changes +if [ "$SKIP_BACKUP" != "true" ]; then + if [ -f "$ENV_FILE" ]; then + echo "Creating backup of existing .env file to .env-$DATE" >>$LOGFILE + cp $ENV_FILE $ENV_FILE-$DATE + else + echo "No existing .env file found to backup" >>$LOGFILE + fi fi -if grep -q "PUSHER_APP_KEY=$" /data/coolify/source/.env; then - sed -i "s|PUSHER_APP_KEY=.*|PUSHER_APP_KEY=$(openssl rand -hex 32)|g" /data/coolify/source/.env -fi +echo "Merging .env.production values into .env" >>$LOGFILE +awk -F '=' '!seen[$1]++' $ENV_FILE /data/coolify/source/.env.production > $ENV_FILE.tmp && mv $ENV_FILE.tmp $ENV_FILE +echo ".env file merged successfully" >>$LOGFILE -if grep -q "PUSHER_APP_SECRET=$" /data/coolify/source/.env; then - sed -i "s|PUSHER_APP_SECRET=.*|PUSHER_APP_SECRET=$(openssl rand -hex 32)|g" /data/coolify/source/.env -fi +update_env_var() { + local key="$1" + local value="$2" + + # If variable "key=" exists but has no value, update the value of the existing line + if grep -q "^${key}=$" "$ENV_FILE"; then + sed -i "s|^${key}=$|${key}=${value}|" "$ENV_FILE" + echo " - Updated value of ${key} as the current value was empty" >>$LOGFILE + # If variable "key=" doesn't exist, append it to the file with value + elif ! grep -q "^${key}=" "$ENV_FILE"; then + printf '%s=%s\n' "$key" "$value" >>"$ENV_FILE" + echo " - Added ${key} with default value as the variable was missing" >>$LOGFILE + fi +} + +echo "Checking and updating environment variables if necessary..." >>$LOGFILE +update_env_var "PUSHER_APP_ID" "$(openssl rand -hex 32)" +update_env_var "PUSHER_APP_KEY" "$(openssl rand -hex 32)" +update_env_var "PUSHER_APP_SECRET" "$(openssl rand -hex 32)" # Make sure coolify network exists # It is created when starting Coolify with docker compose @@ -37,7 +57,6 @@ if ! docker network inspect coolify >/dev/null 2>&1; then docker network create --attachable coolify 2>/dev/null fi fi -# docker network create --attachable --driver=overlay coolify-overlay 2>/dev/null # Check if Docker config file exists DOCKER_CONFIG_MOUNT="" From 983197b74282d57aab7a31b5b25b366afd6269c4 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 29 Aug 2025 18:42:46 +0200 Subject: [PATCH 04/80] chore: adjust wording --- scripts/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/install.sh b/scripts/install.sh index 64913d599..3bbabf648 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -739,7 +739,7 @@ update_env_var() { # If variable "key=" doesn't exist, append it to the file with value elif ! grep -q "^${key}=" "$ENV_FILE"; then printf '%s=%s\n' "$key" "$value" >>"$ENV_FILE" - echo " - Added ${key} with default value as the variable was missing" + echo " - Added ${key} and it's value as the variable was missing" fi } From 7a7f2c64bb53972da97be1c500b3f5f6f58e7e7e Mon Sep 17 00:00:00 2001 From: Kimmo Salmela Date: Thu, 4 Sep 2025 13:41:20 +0300 Subject: [PATCH 05/80] Update Coolify logo files --- public/coolify-logo-dev-transparent.png | Bin 7866 -> 1775 bytes public/coolify-logo-dev-transparent.svg | 1 + public/coolify-logo.svg | 10 +--------- public/coolify-transparent.png | Bin 7872 -> 1797 bytes 4 files changed, 2 insertions(+), 9 deletions(-) create mode 100644 public/coolify-logo-dev-transparent.svg diff --git a/public/coolify-logo-dev-transparent.png b/public/coolify-logo-dev-transparent.png index 9beeb9ba3f402d0aee0ec2c580d4dc233e6684ee..4e65e8b72160821db2ebf40d06a919ef703c2675 100644 GIT binary patch literal 1775 zcmeAS@N?(olHy`uVBq!ia0y~yU`zmE4mO}jYvN)bAg3|Y**Ty%$lXc7)79C`(9+CI z*GSKhfk9(p>BQaM%#H%>`;T;dY;6(~6Kh`)suZZ0ku3O;HEW{FhpQ^-dV)nK3&jOD zisrDgUOX1Qu)c9y(^dtIE`@8iv~I1KQ*5cIls4_=&u`nU55Lo?cpMqJy+-juF{`na zP~fukw5hAoSABe_?&9mTwWsq&!JJLs>bj42UUys`_OtkZ)LW-hK?fg;%LVXmRFq42{7O>vQZg*6ik30Lp+Zt<@)E9mdUo9CdK5hEt zb?MWu%>Qknzta2ZvLvC~N1``&7&)=D8n#KO_?Z7SYUjMUg+R(MRn!8Nh><%O`4c`^yUBi`=X-q`=j^jF-`5?_V*TJ=PcxGZ|* z%ud_iH=n=Yd$jsf==2Snx#t$`OZ+G8(Vc#Sp?CiaV4QFkctjR6Fz_7#VaBQ2e9{aI ztRkK+jv*Cu-d;OBvBf}y#gX$^&W+x`J8Uz~tY|ipt&o-BI=gY_SG%yij2UM>&wToK zu?^n_V@9?P4g&|521X?&9s$9Gh7Ja17ZwQxr2`Ct)RT()%FuACwm04~+vip?(!gWbLaOpAbJlm$u*(1M>(6|$yYP`-UZ!r8Ve=WS zlE=uj%jh*DIGKDuZqHF>dR{$u!7m2tXFY6TJM(M9tt$D|_ZUp}?VJB)pE%9)Kg1Ce tBl&OK1(pK&3{r7aEncws5t>%*{B>j&JfHCySWq%Bc)I$ztaD0e0swNf?Op%? literal 7866 zcmeGhe^gWF^?n~OkQmU=OvBX4Yd1}6t;yV(FvpLFKZd_bn6>^mBBbp+$1|Cs!vPu~ zU({MX#|^vHXZDX& zU_fX&HI!R!y`<8}f9?5@Nhzn)@W#h^NIW!nFa~E(mLLNKbD;pqb9-*EoO)t_0 zlX;Ez`qdLs;`>{r?Q?8ZWB!J@&^}2VFsYTSe^kwU_#2H_r5|Bfwn@IuU?8f%Q00})PEA`z}=#QfXQ4W zKxsPjkgi^rjih;8ot`NgxEl7<)>!;n4E)9?d8nvF=7GT)+GwL!F$cm>O%dOOc)`1F z1XN4z2EVU{VyabOHVh(aSFh7_pT7y*;h+lfiftPN*zdQ6N1eF7m5HYqboJn?yCtX+ zqpJOAu`gjrWwuH=WWV1tU_rp`h{e^`gzNt@8Ch9_IixGs{vsibHIPF}{T@ByStIvd zltVDRT2Q-6L@o9A>LIK*&gJ3kBvH?NkuYa$vo*M$;-Nk0irnqR^$fwhR)AZBy|~^J z=FAe;j@AT7h--A(9Ej&1Z9+gO+En6khq?Ri#dWI#ZaKtev?d2WcRL(d1MC}7-4;YW ziymbWZJJI4?j$cdH(EpQIX`q~^xKM1AadJNUzRYmXk7hf4Q*~zbO`mS8u)4W;P0sS z(yZU~X&|-rG&fPHWC<&j>3Og_r2C$lsW%KIb5jYq(p>V|Y&cc=*p7)rbAH+iFJq9| zxO*s-6ZYDkI|FfsaUcGduvw4}0}`no3%%Ye_L(}|2h$Tf@|ftEj4`=P8Xs%1SS{UI zZJ>c*?VRjXdkRL|;CdJj86z2m61@_I*9*++1vul@0p*><0o}QfP!DZGifs%0kd zndy`gS*}__ihY*P-ey8(A?`|)L#x&y z_sb?J(AjoQ1{XC8C=v_C8LXsnk^d{l`e{j9+i$lFB?*@-nS@@z0zR(ALoM1LyvZq7 zs+B+vL?NVOuX@U;ER@00juJRFzDLU&=kUM@JED}oo^b@^FyZ0DVI4f-`jk^9$4HO5 zVCh(jUXXWF$wtN%{}v;_u|5N=s=c7nq~RGz`D`0GaA#Tp6B`+Zd;gd^E;8=ec=*JV zBwh;QHI^KRpCs|~@{8yShDo76I{a4OJJow^(pcfoGTs1t;l2BT-OisGF5!&qkc4a)fN|quwj?vL@KSi8yD6a*I0+ zr2PTA{D&a?fMMeu!GHm7M-@UVTvcHU$Uc?V$7sFBuIC$P^ROlZy;o3L3`f@OdYL!k zuraGMI&i#(KBTn%VJfY-?*lc{ZW+>Wv+!2nS~m{r?^ckqP1>Wo#G`l-;2!f^ZdJl( z5jCqK?OM61yl^@AU5MOK2(AQ^V18DBlUsZJaHOjhGEXN?$}_JLVCAVEKNPKRf#!Er z9eHLGUP$;p@x%1)_aO63a@|7nO1waMYP_y8aKf7bvyHUjY`Rs(Lb*vWj{#$+Y3szytjxt8QiEW%(27cqm$mB0!hF0rYaXx z%J0mbw+5!KUp$&d>wlhcNHFjimam#{oQov^XCTTb`~ovM@S>Ton \ No newline at end of file diff --git a/public/coolify-logo.svg b/public/coolify-logo.svg index 6f4f641f5..9d10de243 100644 --- a/public/coolify-logo.svg +++ b/public/coolify-logo.svg @@ -1,9 +1 @@ - - - - - - - - - + \ No newline at end of file diff --git a/public/coolify-transparent.png b/public/coolify-transparent.png index 96fc0db36db2febba387bbf48d31163361cf9985..99a56acbe3cae04dfc76a4bb38fed8b9b84453bd 100644 GIT binary patch literal 1797 zcmeAS@N?(olHy`uVBq!ia0y~yU`zmE4mO}jYvN)bAg3|Y**Ty%$lXc7)79C`(9+CI z*GSKhfk9(p>BQaM%#H%>`;T;dY;6(~6Kh`)suZZ0ku3O;HEW{FhpQ^-dV)nK3&jOD zisrDgUOX1Qu)c9y(^dtIE`@8iv~I1KQ*5cIls4_=&u`nU55Lo?cpMqJy+-juF{`na zP~fukw5hAoSABe_?&9mTwWsq&!JJLs>bj42UUys`_OtkZ)LW-hK?fg;%LVXmRFq42{7O>vQZg*6ik30Lp+Zt<@)E9mdUo9CdK5hEt zb?MWu%>Qknzta2ZvLvC~N1``&7&)=D8n#KO_?Z7SYUjMUg+R(MRn!8Nh><%O`4c`^yUBi`=X-q`=j^jF-`5?_V*TJ=PcxGZ|* z%ud_iH=n=Yd$jsf==2Snx#t$`OZ+G8(Vc#Sp?CiaV4QFkctjR6Fz_7#VaBQ2e9{aI ztXiHfjv*Cu-d-~dJnA6f7C5a_kmm@q>#OIgtgb9e798--;<8C#P|i=ASlB%$`N8k> zZfonfymvJ=>9x!kEY_t?`Mv(B#eun;1`aL_j7m&A0)hz*9SqDaED{Pz2N(ny**Z9= zCbj7bJ448}()myK$y3ct{EnPhXg6=O-J+71(;DBmm+t@i`|#YKjI{9_hC?D>F=yT0 zb-w8T@9)`DemflJr$LBfSW3g#8?}oznd8I?{u|e7r~Q7PKmVzXfYmzH+y!*Y9)a=! z*7D~g?=zUx{j!@r1Z<7BNU{T88>FVdQ I&MBb@0D3U=`~Uy| literal 7872 zcmeHMYj6`)6h3#mDVwIT+eS#0N*A0V0)=!CZGF&e5ovi0RD4heNaF*i4q`isQYcAo z#4<3J#|Y9og|y@Fm_ddDqgbG27s}KTM_VW_Tic{mjkTspc_nRL-d&t=${+uzKb+0X z$=;m3=X|^8oO|xMCz}fv=4lfiOaK7w-2B;#0Vp!0fQcuUTV3W&EY(04W z#N2YBF}w{BMKf%*E;v2VVy?dXt4s}fJeJ1sDq3`3Y?>}lV&QF>$s{H)_{_fY6_O;! z!H;*PQtxMB!~DQ`iOKWOAj@!>k8luQHSmd=FfoSGIQh1vfQQ6sT~l;~2?)94B^fN% zVMtwea>+y)oD#JX6CAk+Wj3s?Um%0ic&sc#ZJ;PiX`lI18JvMESw?wa#llKR{PT-W z3~C$gv2dEfKTN-&>bBViUHAvDVBTeF3=8JvP??Ue){bGJy_B|h$6_)Ss z5N}eHd+p8nI+eI@72P@ksMQav(~?=p8**@z+`upx7Y0WWl)8oVJNTt`Q%_s&w_WWN({92365bs zzLQkfNAFV6{3$Eq;Nn=nx-Nn&PdXO!uyeS6$#An^y=`i@Qhv4j>_h9~sgEeCuInWD zjnJnJ67f;EkDiB6!EYq_#3*-6)fQFH*drdnP+V0T_10V8tA%Kae?Hb9ZhMryMk*z5 zw+b(kr0KROWbWZ7aWKzX3+o9)T|`&>q~jHY+NPNzokgMFa!`;i?V)DIIhGUVfEj}H z_HH8WO@emyPVy+10&39!wa{U5?AN7|MCiTIE=0bpAJCCm`e_p6Xu=#&Apb4Hia`V3 z<}zK>+=}CV&e{!<`$!<&)Wam9hh`Er44~~!0rH2m2HsN01A}jcRs8vqY(zCv6c2kn zMp$fXRmo~DR~Z?q%UD3(bz zlBJB?FFFmsu5qiGL!uU61xZ)nqEFhe3zKlgK=Ad(=3Lm5@4N`ryvC608 zh4rY-C+gTjQU!lr6HvR){h|^#KUT(2JBZ$Qyg6vu%cr2>n7TFBvWSP@z2VxD-`Bu( z(wrzmEpkQO{B7VVh}=-|Lfj(W@*)q1-tP9n?rV*ZeKbBP*FsJT3l4Yr;2uRk`XH_2 z1Z01axNVkY0S}c^!$tM|RnR+9^?W>1b+omdyjxj};>>tZs`^B~1U>RKj9_@&2n!FL zd4{bfCyE^_W1)RkY7=RhTvw$ol8VekqswrQS$#Tj^LHAoTj^)%iA3*D9agI0*!zDT z%AKUA(m7;uUGu>`MqC5Kl8Z(;v3L+eVOOIIWglION?+BE`#{`_p?cXV7rIB$2{Px4 zcTs8a1LG>hYU1~$LBV|0h+0ParwT$NREKK=cZ{TuV{iJa<&qV(kVcJ_~9%YMZn(wu(I7qy=`PV0Co-WC7#F5s5m~u9ch4Imf3zYlpn5W|$b9k6B zuw;J%o>H^P`3%hVx1?l~=JkCUU|b*w`g(@N#=b zi%El9Y)v$t!X25yK}VMcU$NUxLbVA2Nm_NwPeXCUb3lWKbRgxU4if6hg#VQtT&v|j w!nQLE{;;b+9=DOr=!(MU6g&Li;~|_h`O;@=^Sv9IfqdpZyKwg5S(Xp}0JX-Y*Z=?k From c8b6ffe549e728654e26aa62a625a808f633214d Mon Sep 17 00:00:00 2001 From: Kimmo Salmela Date: Thu, 4 Sep 2025 14:07:19 +0300 Subject: [PATCH 06/80] Add SVG role attributes and title tags --- public/coolify-logo-dev-transparent.svg | 2 +- public/coolify-logo.svg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/coolify-logo-dev-transparent.svg b/public/coolify-logo-dev-transparent.svg index 5427fe0a4..a4159154f 100644 --- a/public/coolify-logo-dev-transparent.svg +++ b/public/coolify-logo-dev-transparent.svg @@ -1 +1 @@ - \ No newline at end of file +Coolify \ No newline at end of file diff --git a/public/coolify-logo.svg b/public/coolify-logo.svg index 9d10de243..bff8f6b40 100644 --- a/public/coolify-logo.svg +++ b/public/coolify-logo.svg @@ -1 +1 @@ - \ No newline at end of file +Coolify \ No newline at end of file From 1530d35b63fc893a69b7f3d428781c91abba35fa Mon Sep 17 00:00:00 2001 From: Kimmo Salmela Date: Thu, 4 Sep 2025 14:09:43 +0300 Subject: [PATCH 07/80] Add monochrome logo --- public/coolify-logo-monochrome.png | Bin 0 -> 1826 bytes public/coolify-logo-monochrome.svg | 1 + 2 files changed, 1 insertion(+) create mode 100644 public/coolify-logo-monochrome.png create mode 100644 public/coolify-logo-monochrome.svg diff --git a/public/coolify-logo-monochrome.png b/public/coolify-logo-monochrome.png new file mode 100644 index 0000000000000000000000000000000000000000..48605e8fda6d5830ab19195f32049d8a20df39eb GIT binary patch literal 1826 zcmeAS@N?(olHy`uVBq!ia0y~yU`zmE4mO}jYvN)bAg3|Y**Ty%$lXc7)79C`(9+CI z*GSKhfk9(p>BQaM%#H%>`;T;dY;6(~6Kh`)suZZ0ku3O;HEW{FhpQ^-dV)nK3&jOD zisrDgUOX1Qu)c9y(^dtIE`@8iv~I1KQ*5cIls4_=&u`nU55Lo?cpMqJy+-juF{`na zP~fukw5hAoSABe_?&9mTwWsq&!JJLs>bj42UUys`_OtkZ)LW-hK?fg;%LVXmRFq42{7O>vQZg*6ik30Lp+Zt<@)E9mdUo9CdK5hEt zb?MWu%>Qknzta2ZvLvC~N1``&7&)=D8n#KO_?Z7SYUjMUg+R(MRn!8Nh><%O`4c`^yUBi`=X-q`=j^jF-`5?_V*TJ=PcxGZ|* z%ud_iH=n=Yd$jsf==2Snx#t$`OZ+G8(Vc#Sp?CiaV4QFkctjR6Fz_7#VaBQ2e9{aI ztnQvJjv*Cu-rm{hd&EJ+^`iX=&Y9i|Qnj|ONXSeOZo0VjgC*-58^M^~HGMY!4)9Xj zY#fd~VQ9R*$|VQr)$}4}EPez!sTe4^{oGylH6QtQ)Up5hvftijn!f;b{e9pp(A#-- z$+`b(A1u2=+fc?45;Td?QM*XaFfv~oX8)cy^L!P{2m7@%E3Yait(If3nT$2XsYlFv zcyRJk-V$s{_uYs08tc#Q|8Hy@Kl?nxkImLBKi04_h}1MOP%$ePU13g3yUNUPZ%5j* zJCzO6G%q6{DQeCoolify \ No newline at end of file From 45a7370b5542f5a70be99f730c910d02f11c1028 Mon Sep 17 00:00:00 2001 From: sepcnt <30561671+sepcnt@users.noreply.github.com> Date: Tue, 9 Sep 2025 21:47:02 +0800 Subject: [PATCH 08/80] fix(socialite): add custom base URL support for GitLab provider in OAuth settings --- bootstrap/helpers/socialite.php | 8 +++++++- resources/views/livewire/settings-oauth.blade.php | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/bootstrap/helpers/socialite.php b/bootstrap/helpers/socialite.php index 961f6809b..3b20f2d89 100644 --- a/bootstrap/helpers/socialite.php +++ b/bootstrap/helpers/socialite.php @@ -70,8 +70,14 @@ function get_socialite_provider(string $provider) 'infomaniak' => \SocialiteProviders\Infomaniak\Provider::class, ]; - return Socialite::buildProvider( + $socialite = Socialite::buildProvider( $provider_class_map[$provider], $config ); + + if ($provider == 'gitlab' && !empty($oauth_setting->base_url)) { + $socialite->setHost($oauth_setting->base_url); + } + + return $socialite; } diff --git a/resources/views/livewire/settings-oauth.blade.php b/resources/views/livewire/settings-oauth.blade.php index 859c79ce1..6a967504d 100644 --- a/resources/views/livewire/settings-oauth.blade.php +++ b/resources/views/livewire/settings-oauth.blade.php @@ -40,7 +40,8 @@ @if ( $oauth_setting->provider == 'authentik' || $oauth_setting->provider == 'clerk' || - $oauth_setting->provider == 'zitadel') + $oauth_setting->provider == 'zitadel' || + $oauth_setting->provider == 'gitlab') @endif From a4e13f56c0576616bb63992e8ee3457b5a61faf2 Mon Sep 17 00:00:00 2001 From: Ahmed A Date: Tue, 9 Sep 2025 17:25:55 +0300 Subject: [PATCH 09/80] Adding support for using config values for process --- app/Traits/ExecuteRemoteCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Traits/ExecuteRemoteCommand.php b/app/Traits/ExecuteRemoteCommand.php index a228a5d10..a37a2c768 100644 --- a/app/Traits/ExecuteRemoteCommand.php +++ b/app/Traits/ExecuteRemoteCommand.php @@ -44,7 +44,7 @@ public function execute_remote_command(...$commands) } } $remote_command = SshMultiplexingHelper::generateSshCommand($this->server, $command); - $process = Process::timeout(3600)->idleTimeout(3600)->start($remote_command, function (string $type, string $output) use ($command, $hidden, $customType, $append) { + $process = Process::timeout(config('constants.ssh.command_timeout'))->idleTimeout(3600)->start($remote_command, function (string $type, string $output) use ($command, $hidden, $customType, $append) { $output = str($output)->trim(); if ($output->startsWith('â•”')) { $output = "\n".$output; From c2d6cd14452b7951f7d95a00181d789c2e061642 Mon Sep 17 00:00:00 2001 From: Ahmed A Date: Tue, 9 Sep 2025 17:28:58 +0300 Subject: [PATCH 10/80] spacing fix --- app/Traits/ExecuteRemoteCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Traits/ExecuteRemoteCommand.php b/app/Traits/ExecuteRemoteCommand.php index a37a2c768..3b88c3f16 100644 --- a/app/Traits/ExecuteRemoteCommand.php +++ b/app/Traits/ExecuteRemoteCommand.php @@ -44,7 +44,7 @@ public function execute_remote_command(...$commands) } } $remote_command = SshMultiplexingHelper::generateSshCommand($this->server, $command); - $process = Process::timeout(config('constants.ssh.command_timeout'))->idleTimeout(3600)->start($remote_command, function (string $type, string $output) use ($command, $hidden, $customType, $append) { + $process = Process::timeout(config('constants.ssh.command_timeout'))->idleTimeout(3600)->start($remote_command, function (string $type, string $output) use ($command, $hidden, $customType, $append) { $output = str($output)->trim(); if ($output->startsWith('â•”')) { $output = "\n".$output; From 843935d679b0b23b714e4305f1146931d33fbfa9 Mon Sep 17 00:00:00 2001 From: nikita Date: Sat, 13 Sep 2025 02:14:10 +0600 Subject: [PATCH 11/80] fix(ui): improve mobile sidebar close behavior - Add click handler to close sidebar when clicking overlay - Fix sidebar positioning by changing inset-0 to h-full - Improves mobile navigation UX --- resources/views/layouts/app.blade.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 47ea71ecc..e02877527 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -16,8 +16,8 @@ } }" x-cloak class="mx-auto" :class="pageWidth === 'full' ? '' : 'max-w-7xl'"> @else -
-

You don't have permission to create new S3 storage configurations.

-

Please contact your team administrator for access.

-
+ + You don't have permission to create new S3 storage configurations. Please contact your team administrator for access. + @endcan diff --git a/resources/views/livewire/subscription/actions.blade.php b/resources/views/livewire/subscription/actions.blade.php index e54cb0bd4..516a57dd3 100644 --- a/resources/views/livewire/subscription/actions.blade.php +++ b/resources/views/livewire/subscription/actions.blade.php @@ -26,10 +26,11 @@
{{ currentTeam()->servers->count() }}
@if (currentTeam()->serverOverflow()) -
WARNING: You must delete - {{ currentTeam()->servers->count() - $server_limits }} servers, + + You must delete {{ currentTeam()->servers->count() - $server_limits }} servers, or upgrade your subscription. {{ currentTeam()->servers->count() - $server_limits }} servers will be - deactivated.
+ deactivated. + @endif Change Server Quantity diff --git a/resources/views/livewire/subscription/index.blade.php b/resources/views/livewire/subscription/index.blade.php index 0ca786988..d1d933e04 100644 --- a/resources/views/livewire/subscription/index.blade.php +++ b/resources/views/livewire/subscription/index.blade.php @@ -55,10 +55,10 @@

Subscription

-
You are not an admin so you cannot manage your Team's subscription. If this does not make sense, please - contact - us. -
+ + You are not an admin so you cannot manage your Team's subscription. If this does not make sense, please + contact us. + @endif From 9768deccd51a1417c3681e487287f57c456a766b Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Thu, 25 Sep 2025 11:15:17 +0200 Subject: [PATCH 37/80] chore(workflow): update pull request trigger to pull_request_target and refine permissions for enhanced security --- .github/workflows/chore-pr-comments.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/chore-pr-comments.yml b/.github/workflows/chore-pr-comments.yml index f20729346..8836c6632 100644 --- a/.github/workflows/chore-pr-comments.yml +++ b/.github/workflows/chore-pr-comments.yml @@ -1,6 +1,6 @@ name: Add comment based on label on: - pull_request: + pull_request_target: types: - labeled jobs: @@ -8,6 +8,15 @@ jobs: runs-on: ubuntu-latest permissions: pull-requests: write + contents: read + actions: none + checks: none + deployments: none + issues: none + packages: none + repository-projects: none + security-events: none + statuses: none strategy: matrix: include: From 2b402c9ce9535f5c63aba96f728f218eed8c0172 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Thu, 25 Sep 2025 11:33:32 +0200 Subject: [PATCH 38/80] Update app/Models/TeamInvitation.php Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- app/Models/TeamInvitation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Models/TeamInvitation.php b/app/Models/TeamInvitation.php index 92107c48c..c322982ed 100644 --- a/app/Models/TeamInvitation.php +++ b/app/Models/TeamInvitation.php @@ -18,7 +18,7 @@ class TeamInvitation extends Model /** * Set the email attribute to lowercase. */ - public function setEmailAttribute($value) + public function setEmailAttribute(string $value): void { $this->attributes['email'] = strtolower($value); } From 12afc1d6b661067c0778dad4c6ad0e0704a6e554 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Thu, 25 Sep 2025 11:38:56 +0200 Subject: [PATCH 39/80] Update resources/views/livewire/server/docker-cleanup.blade.php Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- resources/views/livewire/server/docker-cleanup.blade.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/resources/views/livewire/server/docker-cleanup.blade.php b/resources/views/livewire/server/docker-cleanup.blade.php index 4d440b23b..66e9de720 100644 --- a/resources/views/livewire/server/docker-cleanup.blade.php +++ b/resources/views/livewire/server/docker-cleanup.blade.php @@ -68,9 +68,8 @@ label="Delete Unused Volumes" helper="This option will remove all unused Docker volumes during cleanup.

Warning: Data from stopped containers will be lost!

Consequences include:
    -
  • Volumes not attached to running containers will be deleted and data will be permanently lost (stopped containers are affected).
  • -
  • Data from stopped containers volumes will be permanently lost.
  • -
  • No way to recover deleted volume data.
  • +
  • Volumes not attached to running containers will be permanently deleted (volumes from stopped containers are affected).
  • +
  • Data stored in deleted volumes cannot be recovered.
" /> Date: Thu, 25 Sep 2025 11:39:17 +0200 Subject: [PATCH 40/80] Update templates/service-templates.json Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- templates/service-templates.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/service-templates.json b/templates/service-templates.json index 2fd056a19..ce9ead7cf 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -187,7 +187,7 @@ "minversion": "0.0.0" }, "beszel": { - "documentation": "https://github.com/henrygd/beszel?tab=readme-ov-file#getting-started?utm_source=coolify.io", + "documentation": "https://github.com/henrygd/beszel?tab=readme-ov-file#getting-started&utm_source=coolify.io", "slogan": "A lightweight server resource monitoring hub with historical data, docker stats, and alerts.", "compose": "c2VydmljZXM6CiAgYmVzemVsOgogICAgaW1hZ2U6ICdoZW5yeWdkL2Jlc3plbDowLjEyLjEwJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0JFU1pFTF84MDkwCiAgICB2b2x1bWVzOgogICAgICAtICdiZXN6ZWxfZGF0YTovYmVzemVsX2RhdGEnCiAgICAgIC0gJ2Jlc3plbF9zb2NrZXQ6L2Jlc3plbF9zb2NrZXQnCiAgYmVzemVsLWFnZW50OgogICAgaW1hZ2U6ICdoZW5yeWdkL2Jlc3plbC1hZ2VudDowLjEyLjEwJwogICAgdm9sdW1lczoKICAgICAgLSAnYmVzemVsX2FnZW50X2RhdGE6L3Zhci9saWIvYmVzemVsLWFnZW50JwogICAgICAtICdiZXN6ZWxfc29ja2V0Oi9iZXN6ZWxfc29ja2V0JwogICAgICAtICcvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jazpybycKICAgIGVudmlyb25tZW50OgogICAgICAtIExJU1RFTj0vYmVzemVsX3NvY2tldC9iZXN6ZWwuc29jawogICAgICAtICdIVUJfVVJMPWh0dHA6Ly9iZXN6ZWw6ODA5MCcKICAgICAgLSAnVE9LRU49JHtUT0tFTn0nCiAgICAgIC0gJ0tFWT0ke0tFWX0nCg==", "tags": [ From 3477bbb240fb4baa3f07eb30ff5d2d643df129be Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Thu, 25 Sep 2025 11:40:23 +0200 Subject: [PATCH 41/80] Update resources/views/livewire/server/docker-cleanup.blade.php Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- resources/views/livewire/server/docker-cleanup.blade.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/resources/views/livewire/server/docker-cleanup.blade.php b/resources/views/livewire/server/docker-cleanup.blade.php index 66e9de720..7eb71aead 100644 --- a/resources/views/livewire/server/docker-cleanup.blade.php +++ b/resources/views/livewire/server/docker-cleanup.blade.php @@ -76,10 +76,9 @@ label="Delete Unused Networks" helper="This option will remove all unused Docker networks during cleanup.

Warning: Functionality may be lost and containers may not be able to communicate with each other!

Consequences include:
    -
  • Networks not attached to running containers will be permanently deleted (stopped containers are affected).
  • -
  • Custom networks for stopped containers will be permanently deleted.
  • -
  • Functionality may be lost and containers may not be able to communicate with each other.
  • -
" +
  • Networks not attached to running containers will be permanently deleted (networks used by stopped containers are affected).
  • +
  • Containers may lose connectivity if required networks are removed.
  • + " /> From 12c7e28a48a16692000c32b6024fb5571cb1ff4e Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Thu, 25 Sep 2025 11:44:34 +0200 Subject: [PATCH 42/80] fix(install): ensure proper quoting of environment file paths to prevent issues with spaces --- other/nightly/install.sh | 6 +++--- scripts/install.sh | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/other/nightly/install.sh b/other/nightly/install.sh index 899fa1184..bcd37e71f 100755 --- a/other/nightly/install.sh +++ b/other/nightly/install.sh @@ -712,18 +712,18 @@ curl -fsSL $CDN/upgrade.sh -o /data/coolify/source/upgrade.sh echo -e "6. Setting up environment variable file" -if [ -f $ENV_FILE ]; then +if [ -f "$ENV_FILE" ]; then # If .env exists, create backup echo " - Creating backup of existing .env file to .env-$DATE" cp "$ENV_FILE" "$ENV_FILE-$DATE" # Merge .env.production values into .env echo " - Merging .env.production values into .env" - awk -F '=' '!seen[$1]++' $ENV_FILE /data/coolify/source/.env.production > $ENV_FILE.tmp && mv $ENV_FILE.tmp $ENV_FILE + awk -F '=' '!seen[$1]++' "$ENV_FILE" "/data/coolify/source/.env.production" > "$ENV_FILE.tmp" && mv "$ENV_FILE.tmp" "$ENV_FILE" echo " - .env file merged successfully" else # If no .env exists, copy .env.production to .env echo " - No .env file found, copying .env.production to .env" - cp /data/coolify/source/.env.production $ENV_FILE + cp "/data/coolify/source/.env.production" "$ENV_FILE" fi echo -e "7. Checking and updating environment variables if necessary..." diff --git a/scripts/install.sh b/scripts/install.sh index 0a8139b93..f75ac8f73 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -712,18 +712,18 @@ curl -fsSL $CDN/upgrade.sh -o /data/coolify/source/upgrade.sh echo -e "6. Setting up environment variable file" -if [ -f $ENV_FILE ]; then +if [ -f "$ENV_FILE" ]; then # If .env exists, create backup echo " - Creating backup of existing .env file to .env-$DATE" cp "$ENV_FILE" "$ENV_FILE-$DATE" # Merge .env.production values into .env echo " - Merging .env.production values into .env" - awk -F '=' '!seen[$1]++' $ENV_FILE /data/coolify/source/.env.production > $ENV_FILE.tmp && mv $ENV_FILE.tmp $ENV_FILE + awk -F '=' '!seen[$1]++' "$ENV_FILE" "/data/coolify/source/.env.production" > "$ENV_FILE.tmp" && mv "$ENV_FILE.tmp" "$ENV_FILE" echo " - .env file merged successfully" else # If no .env exists, copy .env.production to .env echo " - No .env file found, copying .env.production to .env" - cp /data/coolify/source/.env.production $ENV_FILE + cp "/data/coolify/source/.env.production" "$ENV_FILE" fi echo -e "7. Checking and updating environment variables if necessary..." From 6cd3bc04617bb8a2dc7010c2b8aa9ef5050e9c27 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Thu, 25 Sep 2025 11:44:58 +0200 Subject: [PATCH 43/80] fix(security): implement authorization checks for terminal access management --- app/Livewire/Server/Security/TerminalAccess.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/Livewire/Server/Security/TerminalAccess.php b/app/Livewire/Server/Security/TerminalAccess.php index c5898314b..284eea7dd 100644 --- a/app/Livewire/Server/Security/TerminalAccess.php +++ b/app/Livewire/Server/Security/TerminalAccess.php @@ -4,6 +4,7 @@ use App\Models\InstanceSettings; use App\Models\Server; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Hash; use Livewire\Attributes\Validate; @@ -11,6 +12,8 @@ class TerminalAccess extends Component { + use AuthorizesRequests; + public Server $server; public array $parameters = []; @@ -22,6 +25,7 @@ public function mount(string $server_uuid) { try { $this->server = Server::ownedByCurrentTeam()->whereUuid($server_uuid)->firstOrFail(); + $this->authorize('update', $this->server); $this->parameters = get_route_parameters(); $this->syncData(); @@ -33,6 +37,8 @@ public function mount(string $server_uuid) public function toggleTerminal($password) { try { + $this->authorize('update', $this->server); + // Check if user is admin or owner if (! auth()->user()->isAdmin()) { throw new \Exception('Only team administrators and owners can modify terminal access.'); @@ -76,4 +82,4 @@ public function render() { return view('livewire.server.security.terminal-access'); } -} \ No newline at end of file +} From 47b060e29146241d9192932b7cee8ad4c34fffd4 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Thu, 25 Sep 2025 11:45:03 +0200 Subject: [PATCH 44/80] refactor(ui): improve styling and consistency in environment variable warning and docker cleanup components --- .../environment-variable-warning.blade.php | 4 +- .../livewire/server/docker-cleanup.blade.php | 6 +- .../TeamInvitationEmailNormalizationTest.php | 88 +++++++++---------- 3 files changed, 45 insertions(+), 53 deletions(-) diff --git a/resources/views/components/environment-variable-warning.blade.php b/resources/views/components/environment-variable-warning.blade.php index bb144172f..1ad05ed46 100644 --- a/resources/views/components/environment-variable-warning.blade.php +++ b/resources/views/components/environment-variable-warning.blade.php @@ -31,7 +31,7 @@ } }" x-if="showWarning"> -
    -
    +
    +
    diff --git a/resources/views/livewire/server/docker-cleanup.blade.php b/resources/views/livewire/server/docker-cleanup.blade.php index 7eb71aead..c2d33bdda 100644 --- a/resources/views/livewire/server/docker-cleanup.blade.php +++ b/resources/views/livewire/server/docker-cleanup.blade.php @@ -41,11 +41,11 @@ helper="The Docker cleanup tasks will run when the disk usage exceeds this threshold." /> @endif -
    +

    These options can cause permanent data loss and functional issues. Only enable if you fully understand the consequences

    -
    +
    +
    @@ -20,8 +20,6 @@ - - Check Now @if (isDev()) Send Test Email (dev only) @@ -30,6 +28,8 @@
    Update your servers semi-automatically.
    + + Check for Updates
    @@ -109,6 +109,9 @@
    @script