up -d alone assumes the previous container releases port 8420 cleanly before the new one binds -- it doesn't force that. The last three deploys all failed with "port is already allocated" at exactly that step; running compose down first (confirmed working when done manually over SSH) guarantees the old container is fully stopped and removed before the new one starts, closing the race.