Your problem is your custom query. Do not use variables that is used by default by WordPress. $posts and $post is WordPress reserved global variables. Change $post to a unique variable, something like $posts_query.
When using get_posts and you need to setup postdata to make use of template tags, you have no choiche but to use $post as setup_postdata() needs $post to be passed to it. This breaks the main query $post global, so you need to reset that once done. This is done with wp_reset_postdata().
Just a note on your code, template tags are not available by default when usng get_posts, so you need to add setup_postdata( $post ); inside your foreach loop to make the use of template tags available
Your custom query should look something like this
$posts_query = get_posts( 'YOUR ARGUMENTS' );
if ( $posts_query ) {
foreach ( $posts_query as $post ) {
setup_postdata( $post );
// You can now use template tags like the_title() and the_content()
}
wp_reset_postdata();
}