Elixir
Back to home
On this page
Note
You can now use composable image (BETA) to install runtimes and tools in your application container. To find out more, see the dedicated documentation page.
Platform.sh supports building and deploying applications written in Elixir. There is no default flavor for the build phase, but you can define it explicitly in your build hook. Platform.sh Elixir images support both committed dependencies and download-on-demand. The underlying Erlang version is 22.0.7.
Supported versions
You can select the major and minor version.
Patch versions are applied periodically for bug fixes and the like. When you deploy your app, you always get the latest available patches.
Grid and Dedicated Gen 3 | Dedicated Gen 2 |
---|---|
|
None available |
Specify the language
To use Elixir, specify elixir
as your app’s type
:
myapp:
type: 'elixir:<VERSION_NUMBER>'
For example:
myapp:
type: 'elixir:1.15'
Built-in variables
Platform.sh exposes relationships and other configuration as environment variables. Most notably, it allows a program to determine at runtime what HTTP port it should listen on and what the credentials are to access other services.
To get the PORT
environment variable (the port on which your web application is supposed to listen) you would:
String.to_integer(System.get_env("PORT") || "8888")
Some of the environment variables are in JSON format and are base64 encoded. You would need to import a JSON parsing library such as JSON or Poison to read those. (There is an example for doing this to decode the PLATFORM_RELATIONSHIPS
environment variable in the section below.)
Tip
Remember config/prod.exs
is evaluated at build time and has no access to runtime configuration. Use config/releases.exs
to configure your runtime environment.
Building and running the application
If you are using Hex to manage your dependencies, you need to specify the MIX_ENV
environment variable:
variables:
env:
MIX_ENV: 'prod'
The SECRET_KEY_BASE
variable is generated automatically based on the PLATFORM_PROJECT_ENTROPY
variable.
You can change it.
Include in your build hook the steps to retrieve a local Hex and rebar
, and then run mix do deps.get, deps.compile, compile
on your application to build a binary.
hooks:
build: |
mix local.hex --force
mix local.rebar --force
mix do deps.get --only prod, deps.compile, compile
Note
That build hook works for most cases and assumes that your mix.exs
file is located at your app root.
Assuming mix.exs
is present at your app root and your build hook matches the above,
you can then start it from the web.commands.start
directive.
The following basic app configuration is sufficient to run most Elixir applications.
name: myapp
type: 'elixir:1.15'
variables:
env:
MIX_ENV: 'prod'
hooks:
build: |
mix local.hex --force
mix local.rebar --force
mix do deps.get --only prod, deps.compile, compile
web:
commands:
start: mix phx.server
locations:
/:
allow: false
passthru: true
Note that there is still an Nginx proxy server sitting in front of your application. If desired, certain paths may be served directly by Nginx without hitting your application (for static files, primarily) or you may route all requests to the Elixir application unconditionally, as in the example above.
Dependencies
The recommended way to handle Elixir dependencies on Platform.sh is using Hex.
You can commit a mix.exs
file in your repository and the system downloads the dependencies in your deps
section using the build hook above.
defp deps do
[
{:platformshconfig, "~> 0.1.0"}
]
end
Accessing Services
You can get all information about a deployed environment, including how to connect to services, through environment variables. Your app can access these variables.
If you are building a Phoenix app for example, it would suffice to add a database to .platform/services.yaml
and a relationship in .platform.app.yaml
. Put the lib in your deps
and, assuming you renamed the prod.secret.exs
to releases.exs
per the Phoenix guide, change:
System.get_env("DATABASE_URL")
to
Platformsh.Config.ecto_dsn_formatter("database")
See Config Reader Documentation for the full API.
Accessing Services Manually
The services configuration is available in the environment variable PLATFORM_RELATIONSHIPS
.
Given a relationship defined in .platform.app.yaml
:
# Relationships enable an app container's access to a service.
# The example below shows simplified configuration leveraging a default service
# (identified from the relationship name) and a default endpoint.
# See the Application reference for all options for defining relationships and endpoints.
relationships:
postgresql:
Assuming you have in mix.exs
the Poison library to parse JSON:
defp deps do
[
{:poison, "~> 3.0"}
]
end
And assuming you use ecto
you could put in config/config.exs
:
relationships = Poison.decode!(Base.decode64!(System.get_env("PLATFORM_RELATIONSHIPS")))
[postgresql_config | _tail] = relationships["postgresql"]
config :my_app, Repo,
database: postgresql_config["path"],
username: postgresql_config["username"],
password: postgresql_config["password"],
hostname: postgresql_config["host"]
and setup Ecto during the deploy hook:
hooks:
deploy: |
mix do ecto.setup
Configuration reader
While you can read the environment directly from your app, you might want to use the Elixir configuration reader library. It decodes service credentials, the correct port, and other information for you.