From 18e14e37c19d958b601162a3a4f4da564054b79d Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Wed, 24 Sep 2025 09:24:18 +0200 Subject: [PATCH] refactor(installer, upgrade): enhance environment variable management - Remove unused VERSION variable from both scripts. - Update the source code link in the install script to point to the correct version. - Improve backup functionality for the .env file in both scripts, allowing for conditional backups. - Enhance the handling and logging of environment variable updates, ensuring existing variables are updated or added as necessary. - Streamline the upgrade process by incorporating Docker configuration checks and adjustments. --- other/nightly/install.sh | 126 +++++++++++++++++++-------------------- other/nightly/upgrade.sh | 55 ++++++++++++----- 2 files changed, 100 insertions(+), 81 deletions(-) diff --git a/other/nightly/install.sh b/other/nightly/install.sh index 92ad12302..38be272a5 100755 --- a/other/nightly/install.sh +++ b/other/nightly/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} and it's 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 diff --git a/other/nightly/upgrade.sh b/other/nightly/upgrade.sh index 0b031ca75..018573ed0 100644 --- a/other/nightly/upgrade.sh +++ b/other/nightly/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-nightly" 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,11 +57,16 @@ 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="" +if [ -f /root/.docker/config.json ]; then + DOCKER_CONFIG_MOUNT="-v /root/.docker/config.json:/root/.docker/config.json" +fi if [ -f /data/coolify/source/docker-compose.custom.yml ]; then echo "docker-compose.custom.yml detected." >>$LOGFILE - docker run -v /data/coolify/source:/data/coolify/source -v /var/run/docker.sock:/var/run/docker.sock --rm ${REGISTRY_URL:-ghcr.io}/coollabsio/coolify-helper:${LATEST_HELPER_VERSION} bash -c "LATEST_IMAGE=${LATEST_IMAGE} docker compose --env-file /data/coolify/source/.env -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml -f /data/coolify/source/docker-compose.custom.yml up -d --remove-orphans --force-recreate --wait --wait-timeout 60" >>$LOGFILE 2>&1 + docker run -v /data/coolify/source:/data/coolify/source -v /var/run/docker.sock:/var/run/docker.sock ${DOCKER_CONFIG_MOUNT} --rm ${REGISTRY_URL:-ghcr.io}/coollabsio/coolify-helper:${LATEST_HELPER_VERSION} bash -c "LATEST_IMAGE=${LATEST_IMAGE} docker compose --env-file /data/coolify/source/.env -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml -f /data/coolify/source/docker-compose.custom.yml up -d --remove-orphans --force-recreate --wait --wait-timeout 60" >>$LOGFILE 2>&1 else - docker run -v /data/coolify/source:/data/coolify/source -v /var/run/docker.sock:/var/run/docker.sock --rm ${REGISTRY_URL:-ghcr.io}/coollabsio/coolify-helper:${LATEST_HELPER_VERSION} bash -c "LATEST_IMAGE=${LATEST_IMAGE} docker compose --env-file /data/coolify/source/.env -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml up -d --remove-orphans --force-recreate --wait --wait-timeout 60" >>$LOGFILE 2>&1 + docker run -v /data/coolify/source:/data/coolify/source -v /var/run/docker.sock:/var/run/docker.sock ${DOCKER_CONFIG_MOUNT} --rm ${REGISTRY_URL:-ghcr.io}/coollabsio/coolify-helper:${LATEST_HELPER_VERSION} bash -c "LATEST_IMAGE=${LATEST_IMAGE} docker compose --env-file /data/coolify/source/.env -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml up -d --remove-orphans --force-recreate --wait --wait-timeout 60" >>$LOGFILE 2>&1 fi