Expose Phoenix app via (free) ngrok
Need to test your Phoenix app from a mobile device? ngrok is the de facto solution for expose your local machine to the internet. Without a paid plan, each time you launch ngrok you receive a new hostname that has to be copied into your Phoenix app... until now ๐
With some clever bash scripting you can automatically populate the ngrok address and launch Phoenix with the correct HOST automatically set.
Configure Phoenix to use $HOST
Ensure your config/dev.exs
file is configured correctly to use the ENV["HOST"]
when running in development.
# config/dev.exs
config :my_app, MyApp.Endpoint,
http: [port: 4000],
url: [scheme: "https", host: {:system, "HOST"}, port: "443"],
debug_errors: true,
code_reloader: true,
check_origin: false,
watchers: [
node: [
"node_modules/webpack/bin/webpack.js",
"--mode",
"development",
"--watch-stdin",
cd: Path.expand("../assets", __DIR__)
]
]
The above assumes you want Phoenix to generate URLs with a HTTPS scheme. If you want HTTP instead, switch the port value to 80
instead of 443
.
Makefile to populate HOST from ngrok
I prefer to have Makefiles for all of my projects, but if you prefer a bash script this should be easily adapted.
FYI This script expects jq
and curl
to be installed.
NGROK_HOST := $$(curl --silent http://127.0.0.1:4040/api/tunnels | jq '.tunnels[0].public_url' | tr -d '"' | awk -F/ '{print $$3}')
.PHONY: serve-ngrok
serve-ngrok: ## Start Phoenix bound to ngrok address
@echo "๐ Exposing My App @ https://$(NGROK_HOST)"
env HOST=$(NGROK_HOST) mix phx.server
The first line extracts the host value from the built-in ngrok server and passes it into the make serve-ngrok
command.
Launch Steps
My development workflow now is:
- Open an empty shell and run
ngrok http 4000
- Open a second shell in our project directory and run
make serve-ngrok
to boot ย the Phoenix application.
And that is it! Hope this saves folks some headaches when testing remote devices in development.