This sample project needs to be simple.
Let’s make a JSON memo service.
Revise the web/router.ex file.
The “/api” scope needs to be uncommented and the “/memos” route needs to be added.
web/router.ex file
Run the migration.
Set server to true in config/prod.exs.
Also make sure a dynamic port configuration is used.
config/prod.exs partial listing
Optionally, add a dynamic port configuration with a default value to config/dev.exs.
The above build time solution is suitable for releases.
The interpreted solution below is suitable for development.
config/dev.exs partial listing
Tests should pass
Start the server.
POST and GET a memo to make sure the server works.
A prior post covers a shell script for conveniently
interacting with this sample app.
Generating a Release
Now that the Phoenix app is working, it is time to build a release.
Add the elixir release manager (exrm) to mix.exs as a project dependency.
mix.exs partial listing
Install exrm and build a release.
This will create the rel/ directory.
The rc script will use environment variable knobs to configure the app.
Note that the RELX_REPLACE_OS_VARS=true environment variable needs
to be defined to use environment variables for dynamic configuration.
The vm.args file is primarily used to configure the erlang VM.
It can also be used to define application configure parameters.
Application configuration parameters defined in this file can be
passed into the program as atoms or integers.
Note that the location of this file can be configured
with the RELEASE_CONFIG_DIR environment variable.
Add the following to rel/vm.args.
rel/vm.args
Alternatively, sys.config can be used to pass in
application configuration parameters.
In this file, application configuration parameters
defined with environment variables must be strings.
Pass the port setting in as above or add the following
to rel/sys.config.
The app module should work with either solution.
Adding both files will not break anything.
Note that rel/sys.config is written in Erlang.
rel/sys.config
Rebuild the release with the configuration files.
Start the release in the console.
Make sure the server responds.
Exit the console with ^C.
Installing the Release as a Service
Now that the release is working, it is time to set it up as a service.
Perform the initial install.
An rc script defines the the service.
phoenix_service_run() is called from the other functions.
It configures and calls the release.
HOME is set to the installation directory to force the
erlang cookie file to be written there regardless of the
phoenix_service_user setting.
phoenix_service_status() echoes a user friendly
message if the release can be pinged.
extra_commands is used to add the console and
remote_console commands.
console is used to start a new service and attach a console to it.
remote_console() is used to connect a console to the service
if it is already running.
Add shutdown to the keyword list if the service needs to
gracefull shutdown when the machine restarts.
The rest is standard rc configuration.
Add following to /usr/local/etc/rc.d/phoenix_service
/usr/local/etc/rc.d/phoenix_service
Make /usr/local/etc/rc.d/phoenix_service read only and executable.
Enable and configure the service in /etc/rc.conf.
/etc/rc.conf lines to add
The service can now be started. If the service is enabled, it will automatically start when the machine boots.
Optional: Adding a Release to the Systemwide Path
Adding a release to the systemwide path is not necessary, but it can be convenient.
Create a directory for the convenience pass through script.
PORT, NODE_NAME and COOKIE need default values because vm.args has no useful default fallbacks.
There is no good way to automatically select a port, so 8080 is a hard coded default.
Add the following script to /usr/local/opt/bin/phoenix_service.
/usr/local/opt/bin/phoenix_service
Make the script executable.
Add /usr/local/opt/bin to the global path in /etc/profile for sh,
and /etc/csh.cshrc for csh.
Consider updating the root path in /root/.cshrc.
/usr/local/opt/bin partial listing
/etc/csh.cshrc partial listing
/root/.cshrc partial listing
Update the path in the current shell if necessary.
Fix permissions if you want to be able to run as any user.
This may have security implications.
The release can now be conveniently controlled.
Setup complete. Switch from root to a normal user.
Updating
Casual updates on a development machine can be performed as follows.
Note that the path permissions will need to be fixed again if
you added the release to the systemwide path and want to be able
to run it as any user.
Troubleshooting
Make sure to set server to true in config/prod.exs.
If the server is mysteriously not working, start the release
with console to see error messages.
What Next?
Consider looking into edeliver for deployment.
“edeliver is based on deliver and provides a bash script to build and deploy
Elixir and Erlang applications and perform hot-code upgrades.”