Use nohup for container restart to survive SSH disconnect

When upgrade is triggered from Coolify UI, the SSH connection is lost when
the coolify container stops. Using nohup ensures the container stop/start
sequence continues in the background even after the connection drops.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Andras Bacsai 2025-12-12 15:41:09 +01:00
parent f4dbae1805
commit 1f7888f515
2 changed files with 98 additions and 57 deletions

View file

@ -77,18 +77,32 @@ echo "All images pulled successfully." >>"$LOGFILE"
# Stop and remove existing Coolify containers to prevent conflicts # Stop and remove existing Coolify containers to prevent conflicts
# This handles both old installations (project "source") and new ones (project "coolify") # This handles both old installations (project "source") and new ones (project "coolify")
echo "Stopping existing Coolify containers..." >>"$LOGFILE" # Use nohup to ensure the script continues even if SSH connection is lost
for container in coolify coolify-db coolify-redis coolify-realtime; do echo "Starting container restart sequence (detached)..." >>"$LOGFILE"
if docker ps -a --format '{{.Names}}' | grep -q "^${container}$"; then
docker stop "$container" >>"$LOGFILE" 2>&1 || true
docker rm "$container" >>"$LOGFILE" 2>&1 || true
echo " - Removed container: $container" >>"$LOGFILE"
fi
done
if [ -f /data/coolify/source/docker-compose.custom.yml ]; then nohup bash -c "
echo "docker-compose.custom.yml detected." >>"$LOGFILE" LOGFILE='$LOGFILE'
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 --project-name coolify --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 --wait --wait-timeout 60" >>"$LOGFILE" 2>&1 DOCKER_CONFIG_MOUNT='$DOCKER_CONFIG_MOUNT'
else REGISTRY_URL='$REGISTRY_URL'
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 --project-name coolify --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 --wait --wait-timeout 60" >>"$LOGFILE" 2>&1 LATEST_HELPER_VERSION='$LATEST_HELPER_VERSION'
fi LATEST_IMAGE='$LATEST_IMAGE'
# Stop and remove containers
echo 'Stopping existing Coolify containers...' >>\"\$LOGFILE\"
for container in coolify coolify-db coolify-redis coolify-realtime; do
if docker ps -a --format '{{.Names}}' | grep -q \"^\${container}\$\"; then
docker stop \"\$container\" >>\"\$LOGFILE\" 2>&1 || true
docker rm \"\$container\" >>\"\$LOGFILE\" 2>&1 || true
echo \" - Removed container: \$container\" >>\"\$LOGFILE\"
fi
done
# Start new containers
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 \${DOCKER_CONFIG_MOUNT} --rm \${REGISTRY_URL:-ghcr.io}/coollabsio/coolify-helper:\${LATEST_HELPER_VERSION} bash -c \"LATEST_IMAGE=\${LATEST_IMAGE} docker compose --project-name coolify --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 --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 \${DOCKER_CONFIG_MOUNT} --rm \${REGISTRY_URL:-ghcr.io}/coollabsio/coolify-helper:\${LATEST_HELPER_VERSION} bash -c \"LATEST_IMAGE=\${LATEST_IMAGE} docker compose --project-name coolify --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 --wait --wait-timeout 60\" >>\"\$LOGFILE\" 2>&1
fi
echo 'Upgrade completed.' >>\"\$LOGFILE\"
" >>"$LOGFILE" 2>&1 &

View file

@ -172,56 +172,83 @@ fi
log "All images pulled successfully" log "All images pulled successfully"
echo " All images pulled successfully." echo " All images pulled successfully."
log_section "Step 4/6: Stopping existing containers" log_section "Step 4/6: Stopping and restarting containers"
echo "" echo ""
echo "4/6 Stopping existing containers..." echo "4/6 Stopping containers and starting new ones..."
for container in coolify coolify-db coolify-redis coolify-realtime; do echo " This step will restart all Coolify containers."
if docker ps -a --format '{{.Names}}' | grep -q "^${container}$"; then echo " Check the log file for details: ${LOGFILE}"
echo " - Stopping ${container}..."
log "Stopping container: ${container}" # From this point forward, we need to ensure the script continues even if
docker stop "$container" >>"$LOGFILE" 2>&1 || true # the SSH connection is lost (which happens when coolify container stops)
log "Removing container: ${container}" # We use a subshell with nohup to ensure completion
docker rm "$container" >>"$LOGFILE" 2>&1 || true log "Starting container restart sequence (detached)..."
log "Container ${container} stopped and removed"
nohup bash -c "
LOGFILE='$LOGFILE'
DOCKER_CONFIG_MOUNT='$DOCKER_CONFIG_MOUNT'
REGISTRY_URL='$REGISTRY_URL'
LATEST_HELPER_VERSION='$LATEST_HELPER_VERSION'
LATEST_IMAGE='$LATEST_IMAGE'
log() {
echo \"[\$(date '+%Y-%m-%d %H:%M:%S')] \$1\" >>\"\$LOGFILE\"
}
# Stop and remove containers
for container in coolify coolify-db coolify-redis coolify-realtime; do
if docker ps -a --format '{{.Names}}' | grep -q \"^\${container}\$\"; then
log \"Stopping container: \${container}\"
docker stop \"\$container\" >>\"\$LOGFILE\" 2>&1 || true
log \"Removing container: \${container}\"
docker rm \"\$container\" >>\"\$LOGFILE\" 2>&1 || true
log \"Container \${container} stopped and removed\"
else
log \"Container \${container} not found (skipping)\"
fi
done
log \"Container cleanup complete\"
# Start new containers
echo '' >>\"\$LOGFILE\"
echo '============================================================' >>\"\$LOGFILE\"
log 'Step 5/6: Starting new containers'
echo '============================================================' >>\"\$LOGFILE\"
if [ -f /data/coolify/source/docker-compose.custom.yml ]; then
log 'Using custom docker-compose.yml'
log 'Running docker compose up with custom configuration...'
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 --project-name coolify --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 --wait --wait-timeout 60\" >>\"\$LOGFILE\" 2>&1
else else
log "Container ${container} not found (skipping)" log 'Using standard docker-compose configuration'
log 'Running docker compose up...'
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 --project-name coolify --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 --wait --wait-timeout 60\" >>\"\$LOGFILE\" 2>&1
fi fi
done log 'Docker compose up completed'
log "Container cleanup complete"
echo " Done."
log_section "Step 5/6: Starting new containers" # Final log entry
echo '' >>\"\$LOGFILE\"
echo '============================================================' >>\"\$LOGFILE\"
log 'Step 6/6: Upgrade complete'
echo '============================================================' >>\"\$LOGFILE\"
log 'Coolify upgrade completed successfully'
log 'Version: \${LATEST_IMAGE}'
echo '' >>\"\$LOGFILE\"
echo '============================================================' >>\"\$LOGFILE\"
echo \"Upgrade completed: \$(date '+%Y-%m-%d %H:%M:%S')\" >>\"\$LOGFILE\"
echo '============================================================' >>\"\$LOGFILE\"
" >>"$LOGFILE" 2>&1 &
# Give the background process a moment to start
sleep 2
log "Container restart sequence started in background (PID: $!)"
echo "" echo ""
echo "5/6 Starting new containers..." echo "5/6 Containers are being restarted in the background..."
if [ -f /data/coolify/source/docker-compose.custom.yml ]; then echo "6/6 Upgrade process initiated!"
echo " Custom docker-compose.yml detected."
log "Using custom docker-compose.yml"
log "Running docker compose up with custom configuration..."
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 --project-name coolify --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 --wait --wait-timeout 60" >>"$LOGFILE" 2>&1
else
log "Using standard docker-compose configuration"
log "Running docker compose up..."
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 --project-name coolify --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 --wait --wait-timeout 60" >>"$LOGFILE" 2>&1
fi
log "Docker compose up completed"
echo " Done."
log_section "Step 6/6: Upgrade complete"
log "Coolify upgrade completed successfully"
log "Version: ${LATEST_IMAGE}"
echo ""
echo "6/6 Upgrade complete!"
echo "" echo ""
echo "==========================================" echo "=========================================="
echo " Coolify has been upgraded to ${LATEST_IMAGE}" echo " Coolify upgrade to ${LATEST_IMAGE} in progress"
echo "==========================================" echo "=========================================="
echo "" echo ""
echo " The upgrade will continue in the background."
echo " Coolify will be available again shortly."
echo " Log file: ${LOGFILE}" echo " Log file: ${LOGFILE}"
echo ""
# Final log entry
echo "" >>"$LOGFILE"
echo "============================================================" >>"$LOGFILE"
echo "Upgrade completed: $(date '+%Y-%m-%d %H:%M:%S')" >>"$LOGFILE"
echo "============================================================" >>"$LOGFILE"