-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for Fly.io deployments #167
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# Deploying on Fly.io | ||
|
||
Elixir WebRTC-based apps can be easily deployed on [Fly.io](https://fly.io)! | ||
|
||
There are just two things you need to do: | ||
|
||
* configure a STUN server both on the client and server side | ||
* use a custom Fly.io IP filter on the server side | ||
|
||
In theory, configuring a STUN server just on one side should be enough but we recommend doing it on both sides. | ||
|
||
In JavaScript code: | ||
|
||
```js | ||
pc = new RTCPeerConnection({ | ||
iceServers: [{ urls: "stun:stun.l.google.com:19302" }], | ||
}); | ||
``` | ||
|
||
In Elixir code: | ||
|
||
```elixir | ||
ip_filter = Application.get_env(:your_app, :ice_ip_filter) | ||
|
||
{:ok, pc} = | ||
PeerConnection.start_link( | ||
ice_ip_filter: ip_filter, | ||
ice_servers: [%{urls: "stun:stun.l.google.com:19302"}] | ||
) | ||
``` | ||
|
||
In `runtime.exs`: | ||
|
||
```elixir | ||
if System.get_env("FLY_IO") do | ||
config :your_app, ice_ip_filter: &ExWebRTC.ICE.FlyIpFilter.ip_filter/1 | ||
end | ||
``` | ||
|
||
In fly.toml: | ||
|
||
```toml | ||
[env] | ||
# add one additional env | ||
FLY_IO = 'true' | ||
``` | ||
|
||
That's it! | ||
No special UDP port exports or dedicated IP address are needed. | ||
Just run `fly launch` and enjoy your deployment :) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
defmodule ExWebRTC.ICE.FlyIpFilter do | ||
@moduledoc """ | ||
ICE IP filter for Fly.io deployments. | ||
|
||
This module defines a single function, which filters IP addresses, | ||
which ICE Agent will use as its host candidates. | ||
It accepts only the IPv4 address that `fly-global-services` resolves to. | ||
""" | ||
|
||
@spec ip_filter(:inet.ip_address()) :: boolean() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nitpick] We could add a behaviour in ExICE. Then again, it's only one function -- up to you There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's stay with the current version for know. In debugging and testing it's verry convenient to pass anonymous function instead of creating a module with a single function. I thought about returning an anonymous function from |
||
def ip_filter(ip_address) do | ||
case :inet.gethostbyname(~c"fly-global-services") do | ||
# Assume that fly-global-services has to resolve | ||
# to a single ipv4 address. | ||
# In other case, don't even try to connect. | ||
{:ok, {:hostent, _, _, :inet, 4, [addr]}} -> | ||
addr == ip_address | ||
|
||
_ -> | ||
false | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] When
:ice_ip_filter
is unset in the application, we're passingice_ip_filter: nil
toPeerConnection
, which meansex_webrtc/lib/ex_webrtc/peer_connection/configuration.ex
Line 242 in e42c09d
doesn't insert the default filter.
When we pass it to ICE, however, this line
https://github.com/elixir-webrtc/ex_ice/blob/4c5190687e11b28a8209f2c930895647d0b2a64c/lib/ex_ice/priv/ice_agent.ex#L137
makes it work again, as it gets the
nil
stored in the keyword list and overrides it with the default filter.I feel like this creates a kind of ambiguity and depends on ExICE not changing its behaviour of parsing options, which can potentially lead to hard-to-find errors in the future. To avoid this in this example, I would explicitly not insert
ice_ip_filter
to the PC options when it's missing from the application's environment.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch!