Skip to content

Instantly share code, notes, and snippets.

@henrik
Last active April 14, 2024 00:32
Show Gist options
  • Star 65 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save henrik/c70e32544e09c1a79841 to your computer and use it in GitHub Desktop.
Save henrik/c70e32544e09c1a79841 to your computer and use it in GitHub Desktop.
Deploying Elixir's Phoenix Framework on Dokku.

Deploying Phoenix on Dokku

Worked 2015-09-08 for Phoenix 1.0.1 on Dokku 0.3.25.

These instructions assume you've set up Dokku. If not, go find a tutorial for that part. My notes for setting it up on Digital Ocean.

On your local machine, in the app's repo

Create a Dokku app:

$ ssh dokku apps:create my_app_name

Make it support multiple buildpacks:

$ ssh dokku config:set my_app_name BUILDPACK_URL=https://github.com/ddollar/heroku-buildpack-multi.git

List the two buildpacks you need:

$ echo "https://github.com/HashNuke/heroku-buildpack-elixir.git" >> .buildpacks
$ echo "https://github.com/gjaldon/heroku-buildpack-phoenix-static.git" >> .buildpacks
$ cat .buildpacks
https://github.com/HashNuke/heroku-buildpack-elixir.git
https://github.com/gjaldon/heroku-buildpack-phoenix-static.git

For Phoenix 1.1, you may need to configure the static buildpack to use node 5+:

echo node_version=5.3.0 > phoenix_static_buildpack.config

If you want to lock down the versions or Erlang and/or Elixir, you can configure the Elixir buildpack.

Get rid of a locale-related warning ("warning: the VM is running with native name encoding of latin1 which may cause Elixir to malfunction as it expects utf8. Please ensure your locale is set to UTF-8 (which can be verified by running "locale" in your shell)"):

$ ssh dokku config:set my_app_name LC_ALL=en_US.utf8

Put your SECRET_KEY_BASE in Dokku config:

# Change these values as appropriate…
$ ssh dokku config:set my_app_name SECRET_KEY_BASE=the_value_in_my_prod_secret_file

In config/prod.secret.exs, read from that config (replacing the old hard-coded value):

secret_key_base: System.get_env("SECRET_KEY_BASE")

Set the domain/host of your site in the same way:

# Change these values as appropriate…
$ ssh dokku config:set my_app_name HOSTNAME=my_hostname.example.com

In prod.exs, read from that config (replacing "example.com"):

url: [host: System.get_env("HOSTNAME"), port: 80]

If you're using a database, read that from config as well, like you did above.

# This varies depending on what you use for DBs in Dokku.
$ ssh dokku psql:create my_app_name

config :hello_phoenix, HelloPhoenix.Repo,
  adapter: Ecto.Adapters.Postgres,
  url: System.get_env("DATABASE_URL"),
  pool_size: 20

In .gitignore, comment this out:

#/config/prod.secret.exs

Now your secret-less prod.secret.exs can be committed and deployed.

So, commit! Push to Dokku! Done:

git commit -am "All done"
git remote add dokku dokku@example.com:my_app_name
git push dokku

Sources

@josegonzalez
Copy link

You could probably get the domain in your config.prod.exs as an environment variable as well, right?

@henrik
Copy link
Author

henrik commented Sep 8, 2015

@josegonzalez Yup, that's actually what I've done for the app I deployed. Guess I might as well document it that way :) Thanks. EDIT: Fixed.

@joakimk
Copy link

joakimk commented Sep 9, 2015

Curious if you really need a Procfile?, the buildpack handles that on heroku.

@henrik
Copy link
Author

henrik commented Sep 9, 2015

@joakimk Oh, you're right. Updated the instructions! Thank you.

@josegonzalez
Copy link

You forgot the following instruction:

dokku apps:create my_app_name

Should allow a user to then run any of the rest of the dokku commands.

@josegonzalez
Copy link

Also, avoid clownpenis.fart as a hostname. It's funny, but a bit crass. Maybe themanualpug.dog instead 😄 ?

@josegonzalez
Copy link

Also, is the multi-buildpack plugin necessary? The latest dokku uses herokuish, which should detect your .buildpacks file and do the right thing automatically.

@henrik
Copy link
Author

henrik commented Nov 8, 2015

@josegonzales Didn't see your comment until now :O GitHub doesn't seem to send notifications about them.

Added the apps:create and cleaned up the domain example (I so love that sketch, but you're right :p). About multi-buildpack, I'm on 0.3.25 and herokuish seems to be new in 0.3.26. Haven't dared update Dokku yet :)

@henrik
Copy link
Author

henrik commented Nov 15, 2015

Updated to skip the multi-buildpack plugin since you can just use BUILDPACK_URL as @josegonzales points out in josegonzalez/dokku-multi-buildpack@129fdc8.

@littlekid
Copy link

@henrik your notes still suggest using buildpack-multi.

@henrik
Copy link
Author

henrik commented Jan 2, 2016

@littlekid Hm, I think the idea was to get rid of installing a Dokku plugin, by instead using a BUILDPACK_URL: https://gist.github.com/henrik/c70e32544e09c1a79841/revisions#diff-3b9b397e786892ecd90567a332d9e596R2

So I think that bit has to remain, but it's been a while since I set this up. Let me know if you confirm that some part of the instructions can be removed.

@littlekid
Copy link

@henrik 👍
I misunderstood before, please ignore my comment. :)

@ktec
Copy link

ktec commented Feb 4, 2016

Hey @henrik, thanks for sharing this useful guide. Do you think its worth "pinning" the buildpacks? dokku/dokku@bfcf834

Also, it might be helpful for some users to mention the last little bit of adding dokku as a git remote, it's easy to find elsewhere but nice to have here too:

git remote add dokku dokku@example.com:hello_phoenix

@henrik
Copy link
Author

henrik commented Feb 5, 2016

@ktec Wasn't aware that you can pin buildpacks. Good to know; thank you! Another similar option is to configure the buildpacks as documented in each buildpack – that's what I'm doing: For example specifying the Elixir and Erlang version.

Good point on mentioning the remote – added that.

@nhu313
Copy link

nhu313 commented Feb 8, 2016

@henrik, thank you for this guide. It's really helpful. Have you upload files to the server? I am having problem setting it up. I can access the folder using the application, but when I upload the picture, the file is not saved. And it's not giving me any error :(

I followed this guide and was able to create folders after I link it. Do you have any other guide I should follow?
http://dokku.viewdocs.io/dokku/docker-options/

@henrik
Copy link
Author

henrik commented Feb 11, 2016

@nhu313 I've done local file uploads in a Rails app using Dokku. I did two things that may be of interest:

  1. Used docker-options to link folders: dokku docker-options:add my-app deploy "-v /my/path/outside/docker:/app/public/uploads" I believe it was crucial to specify the deploy stage and nothing else, for it to work.
  2. Tweaked nginx to allow bigger uploads: http://dokku.viewdocs.io/dokku/nginx/#user-content-customizing-via-configuration-files-included-by-the-default-templates

@nhu313
Copy link

nhu313 commented Feb 17, 2016

Thanks @henrik. I was able to hack it to work using those options. I link the app folder to the physical folder, but that prevented me from running ecto.migrate. I have to play with this some more. Thanks :) 👍

@josephan
Copy link

Thanks @henrik everything worked great. The only issue I faced was when I pushed out updates to my deployed app.
Dokku now supports multiple buildpacks so you can remove this line.

$ ssh dokku config:set my_app_name BUILDPACK_URL=https://github.com/ddollar/heroku-buildpack-multi.git

@robconery
Copy link

This:

ssh dokku config:set my_app_name BUILDPACK_URL=https://github.com/ddollar/heroku-buildpack-multi.git

No longer works, and results in this:

       WARNING: This buildpack is no longer maintained.
       
       Please choose a different buildpack or go to https://github.com/ddollar/heroku-buildpack-multi
       and fork it to your own account.
       
       This buildpack will cease to function at the stroke of midnight on January 1, 2017.

Which is pretty unfortunate. I removed the config and things started working again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment