How to Deploy your Elixir/Phoenix Application to Production
Hi everyone! Today let's follow a simple deployment tutorial for Phoenix applications.
Step 1: Creating a new Phoenix Application
If you follow this tutorial, I assume you already have Elixir and Phoenix's dependencies installed locally. If you don't, you will probably want to read this tutorial.
To create a brand-new Phoenix application locally, we just need to type in our terminal:
$ mix phx.new <your application's name> # creating the new phoenix project $ cd <your application's name> $ mix ecto.create # creating database locally
Creating the database locally isn't crucial for this tutorial, but it can help if you want to code on your machine.
Note to OSX users
If you use OSX like me, you may encounter this error:
(Postgrex.Error) FATAL 28000 (invalid_authorization_specification) role "postgres" does not exist. This is because when installing PostgreSQL with brew, it creates a user with your short name, not
postgres. To fix this, open the project with your favorite text editor and replace
username: "postgres", by
username: "<your name>", in the file
config/dev.exs. For instance, my name is
valeriane venance in my computer so I replace with
Step 2: Getting our Application Ready for Production
From the code perspective, all we need to do is to edit
config/prod.secret.exs to replace
System.get_env("POSTGRESQL_ADDON_URI"). This is because we will use the PostgreSQL add-on environment variable provided by Clever Cloud to your application instead of the default value.
Back in our terminal, we will generate a secret token that we will save for later with
$ mix phx.gen.secret and check our elixir version with
$ elixir -v.
And that's it. Easy right? Now let's go into our Clever Cloud console.
Step 3: Creating the Prod Application and Database
If you already are a Clever Cloud user, these steps must be really familiar to you:
- Under the organization of your choice, click new, then application. Select Elixir, then name your application and choose its deployment zone.
- When prompted if you need an add-on, select PostgreSQL. Select your database size and name it.
- On the environment variable screen create two new ones:
- SECRET_KEY_BASE with the value obtained from
$ mix phx.gen.secretpreviously
- CC_ELIXIR_VERSION with the value of
$ elixir -vresult. (Available values as of today are
- Click on update changes
- Bonus: if you have migrations to run you could also set the environment variable CC_PHOENIX_RUN_ECTO_MIGRATE to
trueto trigger the command
$ mix ecto.migrate
Step 4: deploy!
Once the previous steps are made, Clever Cloud will provide you a git remote and the commands to add the remote and to push your code. If you had not done it before, initialize a new git repository in your terminal with
git init. Then add and commit your code. Now you should be able to copy and paste the provided git commands. If you go back to your Clever Cloud console, you will see that your deployment has started and logs should show up. Wait a few moments and your application will be up and running. You can visit it by clicking the link icon on top of your application's menu in the Clever Cloud console.
The magic explained
As Phoenix is a framework that was built to be as easy to use as RubyOnRails but less magical, let's demystify what just happened here.
When we push our code to the remote Clever Cloud provided, the following commands are run:
$ mix deps.get $ mix deps.compile $ npm install
These commands will compile your dependencies at the root of your project folder. If you want to use another folder for
npm install, specify it via the environment variable CC_PHOENIX_ASSETS_DIR. To change the folder for the entire build/run process, you should use the APP_FOLDER environment variable.
$ mix compile is run. If you want to override this behavior, you can set the environment variable CC_MIX_BUILD_GOAL to the value you desire.
At this point, there is the command
$ npm run deploy.
$ mix phx.digest is run. You can override this one with the variable CC_PHOENIX_DIGEST_GOAL.
$ mix phx.server is invoked, and as always, you can override this behavior, either with CC_RUN_COMMAND where you have to specify the full command, or CC_PHOENIX_SERVER_GOAL where it will be a mix task by default.
If you need to specify the time zone of your application, you can do it with the variable TZ set to the usual time zone format, for instance
And that's it really, now you have your Phoenix application deployed to production. All you have to do left is write code, commit and push it again! Happy hacking!