Try adding echo nl2br($posts); instead. HTML does not recognize the newline character.
Recommend removing the last \r\n from the file or do the following to get rid of the rogue line at the bottom:
// take off the last two characters
$posts = substr($posts, 0, -2));
// convert the newlines
$posts = nl2br($posts);
// output
echo $posts;
To fix the erroneous posts problem:
// get the message
$msg = $_POST["msg"];
// store the original posts from the file
$original_posts = file_get_contents("posts.txt");
// set permissions (this isn't really required)
chmod("posts.txt", 0777);
// prepend the message to the whole file of posts
$posts = "$msg\r\n" . $original_posts;
// output everything
echo nl2br($posts);
// write the entire file (no prepend) to the text file
file_put_contents("posts.txt", $posts);