Porto qualified for the Champions League last 16 and Manchester City sealed first place in Group C after Agustin Marchesin’s superb display for the hosts in Tuesday’s 0-0 draw at the Estadio do Dragao.
Sergio Conceicao’s side were on the defensive for long periods, but a series of superb saves from Marchesin secured the point they needed to advance.
City dominated throughout but Gabriel Jesus was denied a late winner after VAR ruled out his goal.
City had already booked their place in the last 16 after winning their first four games and, with top spot now secured, Pep Guardiola can now rest players for their final match against Marseille next week.
Guardiola insists City will thrive in the Champions League this season as they bid to make amends for last term’s shock quarter-final defeat against Lyon.
City have never won the Champions League and Guardiola, who last lifted the trophy with Barcelona in 2011, has been unable to take them past the quarter-finals.
Finishing on top of the group was the first step towards that target and Guardiola will be encouraged by City’s improved defence.
They have conceded just six goals in their last 13 games in all competitions, a run that includes four successive Champions League clean sheets.
Guardiola made seven changes as Kevin De Bruyne, Riyad Mahrez and Kyle Walker were among those resting on the bench following the 5-0 thrashing of Burnley.
Raheem Sterling felt he should have had an early penalty when Malang Sarr thudded into him without getting the ball, but VAR decided not to intervene despite the strong claim.
With Sergio Aguero still troubled by a knee injury and Jesus on the bench, Ferran Torres started up front for City.
Torres was denied the opening goal by a fine save from Marchesin after the Spaniard raced onto Phil Foden’s pass.
City had 70 percent of the first half possession and Sterling almost made the breakthrough when he cut in from the left for a fierce drive that was cleared off the line by Zaidu Sanusi.
Guardiola was angry with Conceicao’s accusations this week that the Spaniard and his staff attempted to influence officials during City’s win at the Etihad Stadium in October.
Cautious Porto weren’t as aggressive as their manager, but they finally showed a little ambition early in the second half when Sergio Oliveira tested Ederson from long range.
Sterling carried City’s biggest threat and should have put them ahead when Foden’s sublime pass put him clean through, only for Marchesin to rush from his line to make the save.
Marchesin denied the visitors again with a superb save from Torres’ overhead kick after City defender Ruben Dias accidently cleared Sterling’s effort off the Porto line.
Bernardo Silva’s low drive forced another good stop from Marchesin, who made an even better one-handed save to keep out Eric Garcia’s header.
Jesus thought he had broken Marchesin’s brilliant resistance in the 80th minute with a tap-in from the rebound after the Porto keeper had tipped his header onto the bar.
But after lengthy City celebrations, the goal was ruled out by VAR for offside against Silva during the build-up.