mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 13:10:37 -04:00
fix(upgrade): keep Coolify running when Docker reports IPv6 gateways with a prefix
Docker Engine 27.0 to 28.0.0 reports an IPv6 network gateway with its prefix length (fd00::1/64) until the daemon restarts (moby/moby#49520). The Docker CLI 29 and Compose 5 in the helper image reject it, so deployments failed and the upgrade left Coolify stopped. - Stop the upgrade before it changes containers when the coolify network has such a gateway, and tell the user to restart or upgrade Docker. - Create a new coolify network again without IPv6 when Docker reports its gateway with a prefix. - Report an error, not "Upgrade complete", when the new Coolify containers do not start. - Add the fix to deployment errors that contain this ParseAddr failure. Fixes #11583
This commit is contained in:
+52
-17
@@ -38,6 +38,47 @@ write_status() {
|
||||
echo "${step}|${message}|$(date -Iseconds)" > "$STATUS_FILE"
|
||||
}
|
||||
|
||||
# Print the first gateway of a network that Docker reports with a prefix length (fd00::1/64).
|
||||
# Docker Engine 27.0 to 28.0.0 does this for IPv6 until the daemon restarts (https://github.com/moby/moby/pull/49520).
|
||||
# The Docker CLI and Compose in the helper image fail on such a network with a ParseAddr error.
|
||||
network_gateway_with_prefix() {
|
||||
docker network inspect "$1" --format '{{range .IPAM.Config}}{{.Gateway}} {{end}}' 2>&1 | grep -oE '[0-9A-Fa-f:.]+/[0-9]+' | head -n1
|
||||
}
|
||||
|
||||
# Make sure the coolify network exists and the helper image can read it.
|
||||
# It is created when starting Coolify with docker compose
|
||||
ensure_coolify_network() {
|
||||
log "Checking Docker network 'coolify'..."
|
||||
if ! docker network inspect coolify >/dev/null 2>&1; then
|
||||
log "Network 'coolify' does not exist, creating..."
|
||||
if ! docker network create --attachable --ipv6 coolify 2>/dev/null; then
|
||||
log "Failed to create network with IPv6, trying without IPv6..."
|
||||
docker network create --attachable coolify 2>/dev/null
|
||||
log "Network 'coolify' created without IPv6"
|
||||
elif [ -n "$(network_gateway_with_prefix coolify)" ]; then
|
||||
# No container uses the new network yet, so it is safe to recreate it.
|
||||
log "Docker reports the IPv6 gateway of network 'coolify' with a prefix length, recreating it without IPv6..."
|
||||
docker network rm coolify >/dev/null 2>&1
|
||||
docker network create --attachable coolify 2>/dev/null
|
||||
log "Network 'coolify' created without IPv6"
|
||||
else
|
||||
log "Network 'coolify' created with IPv6 support"
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
|
||||
log "Network 'coolify' already exists"
|
||||
local gateway
|
||||
gateway=$(network_gateway_with_prefix coolify)
|
||||
if [ -n "$gateway" ]; then
|
||||
local message="Docker Engine $(docker version --format '{{.Server.Version}}' 2>/dev/null) reports the gateway of the 'coolify' network as ${gateway}, which Coolify cannot read (Docker Engine bug, fixed in 28.0.1). Run 'systemctl restart docker' (this restarts all containers) or upgrade Docker Engine, then upgrade Coolify again."
|
||||
log "ERROR: ${message}"
|
||||
write_status "error" "$message"
|
||||
echo " ERROR: ${message}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Pull an image. Retry with backoff, because the registry can rate limit many instances that pull at the same time.
|
||||
pull_image() {
|
||||
local image="$1"
|
||||
@@ -177,21 +218,7 @@ fi
|
||||
log "Environment variables check complete"
|
||||
echo " Done."
|
||||
|
||||
# Make sure coolify network exists
|
||||
# It is created when starting Coolify with docker compose
|
||||
log "Checking Docker network 'coolify'..."
|
||||
if ! docker network inspect coolify >/dev/null 2>&1; then
|
||||
log "Network 'coolify' does not exist, creating..."
|
||||
if ! docker network create --attachable --ipv6 coolify 2>/dev/null; then
|
||||
log "Failed to create network with IPv6, trying without IPv6..."
|
||||
docker network create --attachable coolify 2>/dev/null
|
||||
log "Network 'coolify' created without IPv6"
|
||||
else
|
||||
log "Network 'coolify' created with IPv6 support"
|
||||
fi
|
||||
else
|
||||
log "Network 'coolify' already exists"
|
||||
fi
|
||||
ensure_coolify_network || exit 1
|
||||
|
||||
mkdir -p /data/coolify/images/{avatars,project-icons}
|
||||
chown -R 9999:root /data/coolify/images
|
||||
@@ -316,8 +343,16 @@ nohup bash -c "
|
||||
fi
|
||||
|
||||
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:-docker.io}/coollabsio/coolify-helper:\${LATEST_HELPER_VERSION} bash -c \"LATEST_IMAGE=\${LATEST_IMAGE} docker compose --env-file /data/coolify/source/.env \${COMPOSE_FILES} up -d --remove-orphans --wait --wait-timeout 60\" >>\"\$LOGFILE\" 2>&1
|
||||
log 'Docker compose up completed'
|
||||
if docker run -v /data/coolify/source:/data/coolify/source -v /var/run/docker.sock:/var/run/docker.sock \${DOCKER_CONFIG_MOUNT} --rm \${REGISTRY_URL:-docker.io}/coollabsio/coolify-helper:\${LATEST_HELPER_VERSION} bash -c \"LATEST_IMAGE=\${LATEST_IMAGE} docker compose --env-file /data/coolify/source/.env \${COMPOSE_FILES} up -d --remove-orphans --wait --wait-timeout 60\" >>\"\$LOGFILE\" 2>&1; then
|
||||
log 'Docker compose up completed'
|
||||
elif [ \"\$(docker inspect --format '{{.State.Running}}' coolify 2>/dev/null)\" = 'true' ]; then
|
||||
# A slow first start (for example long migrations) can pass the wait timeout. Coolify is still starting.
|
||||
log 'Docker compose up did not finish waiting, but the coolify container is running'
|
||||
else
|
||||
log 'ERROR: Docker compose up failed and the coolify container is not running'
|
||||
write_status 'error' \"Coolify did not start. Check the upgrade log: \$LOGFILE\"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Final log entry
|
||||
echo '' >>\"\$LOGFILE\"
|
||||
|
||||
Reference in New Issue
Block a user