Use [^/]+ instead of .* as * means 0 or more whereas + means 1 or more repetition
And [^/] means any character which is not a slash.
Also why do you need the parenthesis for? These are useful to extract groups when it matches. If you only need a boolean result (match or not) you could drop them from the expression.
You edited the question so here is my edited answer:
[^/]+\.[^/.]+/([^/.]+/)?[^/.]+(:.+)?
Explanation:
[^/]: any character not a slash
[^/]+: any string not containing a slash
\.: a dot (escape do not mean any character)
[^/.]+: any string not containing a slash nor a dot
[^/]+\.[^/.]+/: any string separated by a dot and ending with a slash (typically docker.io).
()? means this could occur 0 or 1 time (optional)
(:.+)?: an optional string consisting of a colon followed by any string but not empty.