Deploying to a host that is still receiving traffic means the requests in flight during the swap see a half-updated application, and there is no version of that which is correct.
# take it out of rotation and wait for in-flight requests
touch /var/www/app/shared/.draining
sleep 15 # > the health check interval x threshold
./deploy.sh
rm /var/www/app/shared/.draining
# the health endpoint checks for the file and returns 503 when present.
A file the health endpoint checks is the simplest mechanism and it works with any load balancer that does health checks at all. The sleep has to exceed the check interval multiplied by the unhealthy threshold, which is a number to look up rather than guess — too short and the balancer has not noticed yet. Connections already established still need to finish, which is what the fpm graceful reload handles at the other end.