Skip to content

Commit 60d584b

Browse files
DAdjadjclaude
andcommitted
Fix self-update: use helper container to avoid race condition
The old approach ran docker stop/rm/run from inside the container being updated. When docker stop killed the container, the shell died with it, so docker rm and docker run never executed — leaving the container dead (white screen) or stuck in an update loop. Now spawns a separate helper container that runs docker compose up -d from the outside. The compose directory is mounted at its real host path so relative volume paths resolve correctly for the Docker daemon. Existing users not using Watchtower/Portainer need a one-time manual update: docker compose pull && docker compose up -d Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0bad4c4 commit 60d584b

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

app/web/server.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -817,16 +817,22 @@ def update_run():
817817
return jsonify({"error": "Compose file mount not found. Make sure the docker-compose.yml directory is mounted at /compose."}), 400
818818
# Spawn a helper container to run docker compose up -d. This avoids the
819819
# race condition of trying to stop/recreate ourselves from within.
820-
compose_cmd = f"sleep 2 && docker compose -f /compose/docker-compose.yml up -d --force-recreate"
820+
# Mount the compose directory at its real host path so that relative
821+
# volume paths (./data:/data etc.) resolve to correct host paths.
822+
compose_file = f"{compose_host_path}/docker-compose.yml"
823+
compose_cmd = f"sleep 2 && docker compose -f '{compose_file}' up -d --force-recreate"
821824
helper_cmd = [
822825
"docker", "run", "-d", "--rm",
823826
"-v", "/var/run/docker.sock:/var/run/docker.sock",
824-
"-v", f"{compose_host_path}:/compose:ro",
827+
"-v", f"{compose_host_path}:{compose_host_path}:ro",
825828
IMAGE_NAME,
826829
"sh", "-c", compose_cmd,
827830
]
828831
logger.info("Update via helper container: %s", " ".join(helper_cmd))
829-
subprocess.run(helper_cmd, capture_output=True, text=True, timeout=15)
832+
result = subprocess.run(helper_cmd, capture_output=True, text=True, timeout=15)
833+
if result.returncode != 0:
834+
logger.error("Failed to start update helper: %s", result.stderr.strip())
835+
return jsonify({"error": "Failed to start update. Try running: docker compose pull && docker compose up -d"}), 500
830836
db.set_setting("update_available", "0")
831837
return jsonify({"updating": True})
832838
except FileNotFoundError:

0 commit comments

Comments
 (0)