Turns out ACI are a half baked solution and there are no simple ways to expose a container instance while part of a vnet. The only practical solution is to use an Application Gateway, but ACIs resource IDs are not even available for backend pools, so you have to specify the IP address directly. So you need to somehow make sure that the IP address is updated each time the container is restarted, which happens a lot. One alternative one could explore is to use init containers to do this, which obviously makes something which is supposed to be simple, much more complicated and pointless.
Furthermore, after using ACI with an Application Gateway, it turns out that the cost to operate the Application Gateway is much higher than the Container Instance itself! Might as well use a normal VM and do away with ACI and Application Gateway.
Bottom line, do not use ACI for exposing a public service, unless you want to fight with all these issues.