tags:

views:

257

answers:

4

I have an erlang application I have been writing which uses the erldis library for communicating with redis.

Being a bit of a newbie with actually deploying erlang applications to production, I wanted to know if there was anyway to 'bundle' these external libraries with the application rather than installing into my system wide /usr/lib/erlang/lib/ folder.

Currently my directory structure looks like...

\
--\conf
--\ebin
--\src

I have a basic Makefile that I stole from a friend's project, but I am unsure how to write them properly.

I suspect this answer could involve telling me how to write my Makefile properly rather than just which directory to plonk some external library code into.

+1  A: 

The simplest way to do this would be to just create a folder named erldir and put the beams you need into it and then in your start script just use the -pa flag to the erlang runtime to point out where it should fetch the beams.

The correct way (at least if you buy into the OTP distribution model) would be to create a release using reltool (http://www.erlang.org/doc/man/reltool.html) or systools (http://www.erlang.org/doc/man/systools.html) which includes both your application and erldis.

Lukas
+1  A: 

Add the external libraries that you need, anywhere you want them, and add them to your ERL_LIBS environment variable. Separate the paths with colon in unix or semicolon in dos.

Erlang will add the "ebin"-named subdirs to its code loading path.

Have your *.app file point out the other applications it depends on.

This is a good halfway-there approach for setting up larger applications.

Christian
+1  A: 

I use mochiweb-inspired style. To see example of this get your copy of mochiweb:

svn checkout http://mochiweb.googlecode.com/svn/trunk/ mochiweb

and use

path/to/mochiweb/scripts/new_mochiweb.erl new_project_name

to create sample project of the structure (feel free to delete everything inside src afterwards and use it for your project).

It looks like this:

/
/ebin/
/deps/
/src/
/include/
/support/
/support/include.mk
Makefile
start.sh
  • ebin contains *.beam files
  • src contains ***.erl files and local *.hrl files
  • include contains global *.hrl files
  • deps contains symlinks to root directories of dependencies

Makefile and include.mk takes care of including appropriate paths when project is built.

start.sh takes care of including appropriate paths when project is run.

So using symlinks in deps directory you are able to fine tune the versions of libraries you use for every project. It is advised to use relative paths, so afterwards it is enough to rsync this structure to the production server and run it.

On more global scale I use the following structure:

~/code/erlang/libs/*/
~/code/category/project/*/
~/code/category/project/*/deps/*/

Where every symlink in deps points to the library in ~/code/erlang/libs/ or to another project in the same category.

gleber
+1  A: 

You should really try to avoid project nesting whenever possible. It can lead to all sorts of problems because of how module/application version is structured within Erlang.

In my development environment, I do a few things to simplify dependancies and multiple developed projects. Specifically, I keep most of my projects sourced in a dev directory and create symlinks into an elibs dir that is set in the ERL_LIBS environmental variables.

~/dev/ngerakines-etap
~/dev/jacobvorreuter-log_roller
~/dev/elib/etap -> ~/dev/ngerakines-etap
~/dev/elib/log_roller -> ~/dev/jacobvorreuter-log_roller

For projects that are deployed, I've either had package-rpm or package-apt make targets that create individual packages per project. Applications get boot scripts and init.d scripts for easy start/stop controls but libraries and dependancy projects just get listed as package dependencies.

Nick Gerakines