Revise web/router.ex.
Uncomment the “/api” scope and add the “/memos” route.
web/router.ex.partial listing
Run the migration.
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.
Environment Variable Definitions
Define the following environment variables.
Feel free to use different values and a static value for SECRET_KEY_BASE.
Note that depending on how your database is configured,
DB_PASSWORD may be unnecessary for connections from localhost.
Configuring the Application
Set server to true in config/prod.exs.
Also add a version entry.
Replace static configuration with dynamic configuration that
will be pulled in from environment variables.
None of this needs to be kept out version control,
so it is safe to delete config/prod.secret.exs.
Those settings have been merged in.
config/prod.exs
Alternatively, keep hard coded values in config/prod.secret.exs
when running local release builds and use a version with dynamic
environment variable settings in a real production environment.
config/prod.secret.exs
Optionally, add dynamic configuration with a default values to config/dev.exs.
The environment variable replacement above is only suitable for releases.
The interpreted solution below is only suitable for development with mix.
config/dev.exs partial listing
Generating a Release
Add distillery to mix.exs as a project dependency.
mix.exs partial listing
Install and initialize distillery.
This will create the rel/ directory.
Environment variables will be used as knobs to configure the app.
Note that the REPLACE_OS_VARS=true environment variable needs to
be defined to use environment variables for dynamic configuration.
The rel/vm.args file is primarily used to configure the erlang VM.
It can also be used to define application configuration 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, rel/sys.config can be used to pass in application configuration parameters.
This file is written in Erlang.
rel/sys.config
The Elixir config/config.exs file is probably a better place to
define non-VM settings for an Elixir application.
The distillerydocumentation seems to indicate that a release
can either use sys.config or config.exs but not both.
The exact config.exs settings for this project were covered in
the Configuring the Application section above.
Adding Release Tasks
After deploying a release with distillery, mix is no longer available.
Define a module for release tasks with a mix ecto.migrate equivalent.
Note that this is an Erlang module written in Elixir.
lib/release_tasks.ex
After generating a release, this task can be run as follows.
The mix ecto.create and mix ecto.drop tasks are run less frequently
so it may just makes sense to just manually create or drop the database
and user. PostgreSQL commands follow.
The MySQL commands look like this.
Note that the password security in the above commands is less than ideal.
Also, an existing superuser and password may need to be explicily
specified when creating the new user and database.
Adding Custom Commands for Release Tasks
Distillery supports custom commands.
To wrap the above release tasks in custom commands,
first create the rel/commands directory.
Next add a command for ecto.migrate.
rel/commands/ecto_migrate
The PostgreSQL versions of the ecto.create and ecto.drop commands follow.
rel/commands/ecto_create
rel/commands/ecto_drop
Alternatively, the MySQL versions of ecto.create and ecto.drop look like this.
rel/commands/ecto_create
rel/commands/ecto_drop
Finally, modify rel/config.exs so that the custom commands are present.
The following version is a rewrite.
rel/config.exs
Running the Release
Build the release with the configuration files.
Run the ecto.create and ecto.migrate custom commands defined in the above sections.
Start the release.
Make sure the server responds.
Stop the release.
Custom Application Settings
Add this configuration gist to lib/config.ex.
This configuration wrapper allows the same convenient
{:system, "VARIABLE", "default"} convention to be used with both mix and releases.
Note that this will not help configure things like PhoenixEnvironmentSettings.Repo
because they were not written to get settings via this module.
The linked to version has the typespecs and documentation.
lib/config.ex
Add these lines to config/config.exs.
config/config.exs partial listing
Access the settings in iex -S mix like this.
You should get the default values.
iex -S mix
Define the environment variables and run the commands in iex again.
You should get the environment variable values this time.
This is useful for defining environment variable knobs to control run time behavior.
It is not a solution for problems that rely on compile time behavior,
like using environment variables to specify dynamic routes.
Other Considerations
Note that when using REPLACE_OS_VARS=true, the environment variables in rel/sys.conf or
config/config.exs will always be replaced with strings.
The following almost certainly does not work as expected.
config/prod.exs or
config/prod.secret.exs partial listing
The following will work in development, but not production.
config/dev.exs partial listing
If integers or atoms need to be passed in directly, use vm.args.
The author could not figure out how to pass DB_POOL_SIZE to Repo via vm.args.
Next Steps
Consider looking into conform, a library for working with init-style configuration.
Also consider looking into edeliver for deployment.