Hi @axelson, thanks for putting together main_proxy. I want to use it to do the same thing you’ve used it for: running multiple applications from one BEAM instance. I have an umbrella application with three phoenix endpoints (3 separate child apps): one for an e-commerce shop, another for the store’s admin area, and a third for its cms admin area. I want to route the requests for the admin areas to the single exposed web port for the e-commerce shop since the other two will never see much traffic. However, I’m having difficulty getting it to work with my release.
I have the functionality working correctly in both my local dev and prod environments, but once I use mix release
to produce a release nothing is served when I start it. I’m seeing logs such as Configuration :server was not enabled for MyAppWeb.Endpoint, http/https services won't start
for each web app that I’m trying to spin up locally in my release. Upon deployment (we build & start the release on Render) I’m seeing those logs plus the following ==> No open HTTP ports detected on 0.0.0.0, continuing to scan...
Do you have any idea what the issue could be?
You probably don’t have this part in your config/runtime.exs
:
config :main_proxy,
server: true,
http: [
port: 8080,
ip: {0, 0, 0, 0}
],
# ...
Change the port accordingly.
1 Like
Hey @stefanluptak thanks for the suggestion. I had port
already in config/config.exs
and I’ve added ip
(tried them in both config.exs
and runtime.exs
), but I’m still running into the same error logs.
Two suspects:
- Are you starting
MyApp.Proxy
(or whatever you called it) in your application.ex in the supervision tree? This is this step in the readme:
children = [
# ... other children
MyApp.Proxy,
]
This should be done in one of the applications you have in app/. In my case I created a separate application just to serve that.
- Are you including and starting the application mentioned in the paragraph above (may be your “ui” or “web” app too if you don’t use dedicated one for proxy) in the release configuration?
You should have something like this in the top-level mix.exs of your project
deps: deps(),
releases: releases()
...
defp releases do
[
my_app: [
applications: [
proxy: :permanent
...
]
]
end
I strongly suspect you’re not doing 1 or 2 or both and the OTP application that should have main proxy as a child either does not start at all, or does not start the child.
2 Likes
I am also suspecting not exposing ports in Docker, if it is being used.
1 Like
Hey @hubertlepicki thanks! #2 fixed the release locally and I’m now seeing the other two apps when I start it. The app deployed correctly and I’m no longer seeing the No open HTTP ports detected
logs. Unfortunately the admin apps still aren’t being served according to the backends I defined in MyApp.Proxy
. What could I be doing wrong there?
Do you include these admin apps in the release as well? They both should have entries with :permanent just like your main app does.
1 Like
Yea one entry for the main app, one each for the admin apps, and now one for the proxy app.
And it’s broken as well on the local release and when you deploy, or only when you deploy?
But it works when you start with iex -S mix ?
Also: what does it mean it’s broken. It renders 404 page out of the main app?
1 Like
Only when I deploy. The local release is starting normally and I can access the admin apps from the domains defined in backends
. On the deployed version I’m seeing a “This site can’t provide a secure connection my-shop-admin.my-app-lhrl.onrender.com uses an unsupported protocol.” page (ERR_SSL_VERSION_OR_CIPHER_MISMATCH
). It doesn’t actually produce a log with more information.
This does look like a problem on Render.com rather than in Phoenix already. I’ve never used it myself. I suspect now the Phoenix app works and main_proxy too as expected but there’s some additional problem with generating SSL certificate or serving it over render.com…
1 Like
Yea I think you’re right. I’ve removed my https configurations for main_proxy after reading about their policy on TLS (SSH) certificates and this post in their community. I’m going to try reaching out to their support team about it. If things don’t work out with Render, which service would you suggest using for this sort of setup with main_proxy?
I was using it with both Heroku and Gigalixir, also have the app now moved to Google Kubernetes Engine. This library is pretty deployment-agnostic.
1 Like
I think there could be a mismatch between your backends specification and the custom domains (with certificates) you set-up in the render.com settings for your app.
EDIT: I ran few apps with MainProxy on render.com successfully.
2 Likes
So you’re saying that I need to have the actual custom domains configured in the backends specification, @stefanluptak?
Right now I’ve got the backends configured to use the domain from the RENDER_EXTERNAL_HOSTNAME
env variable that Render provides for their provisional onrender.com domains (I haven’t got to setting up the custom domain yet).
Could you provide your main_proxy backends setup?
1 Like
defmodule MyAppProxy.Proxy do
use MainProxy.Proxy
@render_external_hostname Application.compile_env!(:my_app_proxy, :render_external_hostname)
@impl MainProxy.Proxy
def backends do
[
%{
domain: @render_external_hostname,
phoenix_endpoint: MyAppWeb.Endpoint
},
%{
domain: "my-cms.#{@render_external_hostname}",
phoenix_endpoint: MyCmsWeb.Endpoint
},
%{
domain: "my-admin.#{@render_external_hostname}",
phoenix_endpoint: MyAppAdminWeb.Endpoint
}
]
end
end
If the RENDER_EXTERNAL_HOSTNAME
is app-123.onrender.com
for example, then it means that for MyCmsWeb
and MyAppAdminWeb
to work, domains my-cms.app-123.onrender.com
and my-admin.app-123.onrender.com
would have to exist, but that’s not the case, because you’re not able to create DNS records for onrender.com
subdomains.
If you don’t want to use your own custom domain, you should probably use :path
instead of :domain
.
But I suggest to set up your custom domain. Then save it’s value to a CUSTOM_DOMAIN
env var for example and use that one in your MyAppProxy.Proxy
code instead of the RENDER_EXTERNAL_HOSTNAME
.
3 Likes
Ok I gave :path
a try, but the problem I’m running into now is that the cms is taking up all the spare paths. That is to say all the paths which aren’t already defined in the router file as routes for the app’s functionality are reserved for the cms. There’s probably a way to skirt around this, but I’d prefer not to complicate things further.
I think the only way forward is to use a custom domain as you suggested, but I was hoping to test things out with Render’s provided onrender.com
subdomain first. I’ll continue to experiment with this and I’ll drop an update here if there’s anything useful to share. Thanks for your help @stefanluptak!
2 Likes