Initialize, Start Server and Create Database in Single Script
Try adding the "-w" flag to your pg_ctl -D . -l run.log start command, so that pg_ctl should only return once the server is up. If that worked, the problem was that your createdb command was running too quickly after pg_ctl, before Postgres was actually up and accepting connections, when those commands were executed in a script as opposed to manually.

(Re-posting comment as an answer, as requested.)