Category Archives: Elixir

Elixir Phoenix Cache

An implementation with ets.

Let’s start with implementation

defmodule SimpleCache do
  @table :simple_cache

  def init(_) do, [
      read_concurrency: true,
      write_concurrency: true

    {:ok, %{}}

  def start_link do
    GenServer.start_link(__MODULE__, [], name: __MODULE__)

  def fetch(key, expires_in_seconds, fun) do
    case lookup(key) do
      {:hit, value} ->

      :miss ->
        value = fun.()
        put(key, expires_in_seconds, value)

  defp lookup(key) do
    case :ets.lookup(@table, key) do
      [{^key, expires_at, value}] ->
        case now < expires_at do
          true -> {:hit, value}
          false -> :miss

      _ ->

  defp put(key, expires_in_seconds, value) do
    expires_at = now + expires_in_seconds
    :ets.insert(@table, {key, expires_at, value})

  defp now do

Update application.ex

 def start(_type, _args) do
    import Supervisor.Spec

    children = [
      supervisor(SimpleCache, [])
    opts = [strategy: :one_for_one, name: Supervisor]
    Supervisor.start_link(children, opts)

Finally, use it

    cache_for_seconds = 60
    key = 'key'

    SimpleCache.fetch(key, cache_for_seconds, fn ->
      {:ok, some_expensive_operation}

Relavent links:

Elixir Phoenix Deployment with Distillery

OS: Ubuntu 17.04/zesty

We’ll be deploying using a git hook. This is not intended to be used in a production environment, but works just fine for a personal side project.

Let’s start with the server setup

#Add Erlang Solutions repo
wget && sudo dpkg -i erlang-solutions_1.0_all.deb

sudo apt-get update

#Install Erlang/OTP
sudo apt-get install esl-erlang

We’ll be using kiex for Elixir

#Install Elixir
\curl -sSL | bash -s

#Add to .bashrc
test -s "$HOME/.kiex/scripts/kiex" && source "$HOME/.kiex/scripts/kiex"

kiex install 1.4.0
kiex use 1.4.0
kiex default 1.4.0

Let’s init a repo

apt-get install git-core
mkdir repos && cd repos
mkdir my_repo 
cd my_repo
git init --bare

Add a remote to your local repo:

git remote add some_name root@IP_ADDRESS:repos/your_repo.git

Go back to the server and create a post-deploy hook. This will generate a new release after each git push.

Create post-receive file inside of your git hooks directory with this content:

#!/bin/bash -l

[[ -s "$HOME/.kiex/scripts/kiex" ]] && source "$HOME/.kiex/scripts/kiex"



PORT=4000 _build/prod/rel/{app_name}/bin/{app_name} stop
cd $HOME

mix deps.get
cd assets
npm install
brunch build --production
cd ..
MIX_ENV=prod mix do compile, phx.digest, release --env=prod

MIX_ENV=prod mix ecto.migrate
PORT=4000 _build/prod/rel/{app_name}/bin/{app_name} start

This will stop your existing elixir app, remove old code, compile and release your new code, run the migration, and start the app on port 4000.

If you run it behind NGINX, set it up as a reverse proxy:

server {
  listen 80;
  listen [::]:80;


  location / {
     proxy_redirect off;

Let’s go back to your Phoenix project and add distillery
Add to mix.exs deps:

  {:distillery, "~> 1.5"}

Initialize reliase config:

mix release.init

Update config/prod.exs

  config :app_name, AiPhoenixWeb.Endpoint,
    http: [port: {:system, "PORT"}],
    url: [host: "localhost", port: {:system, "PORT"}], # This is critical for ensuring web-sockets properly authorize.
    cache_static_manifest: "priv/static/cache_manifest.json",
    server: true,
    root: ".",
    version: Mix.Project.config[:version]

If using PostgreSQL, let’s install Postgresql and create a deploy user for our database:

sudo apt-get install postgresql postgresql-contrib libpq-dev
sudo su - postgres
createuser --pwprompt deploy
createdb -O deploy my_app_name_production

Auto-start your phoenix app on reboot:
Create a new file:


cd $HOME/phoenix_app_location
PORT=4001 _build/prod/rel/phoenix_name/bin/phoenix_name start

Make it an executable
chmod +x

Schedule it as a cron task:
Crontab -e

@reboot /root/path_to_script/

The last step to to “git push” and verify that everything works.

Phoenix and Ecto. First Steps

Valid as of Phoenix 1.2

Show routes:
mix phoenix.routes

Generating resources:
mix phoenix.gen.html Post posts –no-model
mix phoenix.gen.json Post posts


  • :string
  • :integer
  • :map
  • :binary_id
  • :float
  • :boolean

Writing Queries
Two ways

  1. Query
    import Ecto.Query
    from p in context.Posts
    where p.Title.Contains("Stuff")
    select p;
  2. Expression
    |> where(titlle: "Stuff")
    |> limit(1)

Making changes –
changeset = Post.changeset(post, %{title: “updated”})

Generate migration:
mix ecto.gen.migration [migration_name] -r [repo]

Generate schema:
mix phoenix.gen.model [Schema] [table] [fields] -r [repo]

Run/Rollback migration
mix ecto.migrate -r [repo]
mix ecto.rollback -r [repo]

Generate migration:
Does not generate schema module:
mix ecto.gen.migration [migration_name] -r [repo]

Generates both schema model and a migration:
mix phoenix.gen.model [Schema] [table] [fields] -r [repo]

To avoid specifying repo all the time:
config :my_app, ecto_repos: [MyApp.Repo]

Starting with Phoenix. Installation.

Prerequisites (valid as of Phoenix 1.2)


  • Elixir – brew install elixir
  • node – brew install node
  • Postgres –

For Windows, can use Chocolatey to install node and Elixir. Postgres seems to be outdated as of time of this post. Or download from source and install:

Add to Windows path PostgreSQL (dependent on PostgreSQL version), so we can use psql on command line –
C:\Program Files\PostgreSQL\9.6\bin
C:\Program Files\PostgreSQL\9.6\lib

Install phoenix:

$ mix archive.install

Alternatively, download a specific version from

Generate and run a new project:

$ mix my_first_app
$ mix ecto.create
$ npm install
$ iex -S mix phoenix.server
iex> :observer.start

Elixir Data Types Summary

  • Numbers: Integers and Floats
  • Atoms: :named_constant
  • Binaries: strings are binaries. <<104>> is “h”
  • Maps: %{key: value}. Can use strings or atoms for keys. But only atoms allow map.key; else use map[key]
  • Tuples: {value,value…}. To access – elem(tuple, 0). To add: put_elem(tuple, 0, “value”)
  • Lists: [value, value…]
  • Functions: fn(args) -> … end. To call: fn.(args)
  • Character Lists: ‘h’ is [104]
  • Keyword Lists: [{:atom, value}…] == [atom: “value”,…]
  • Structs: %{key: value}
  • Range: 0..42
  • Regex: ~r/pattern/

Linting Elixir with Credo

Got excited about Credo on a recent episode of The Elixir Fountain.
Seems to work quite well. Though, I couldn’t get the Atom plugin to work. But the command line works great.

Github repo for Credo provides all of the instructions to install.
I installed it as stand alone:

$ git clone [email protected]:rrrene/credo.git
$ cd credo
$ mix deps.get
$ mix
$ mix archive.install

Also had to install bunt, since it is a dependency:
git clone
cd bunt
mix archive.install

After that, run “mix yourElixirFile.exs” and it will lint your file with something like this:

Credo Output

Elixir Learning Resources

As I recently started learning Elixir, I stumbled upon some cool learning material. Here are some links:

Some twitter accounts to follow:
@josevalim РJos̩ Valim Рcreator of Elixir