StreamHacker Weotta be Hacking

2Jul/0921

How to Create an Erlang First Target System

One of the neatest aspects of erlang is the OTP release system, which allows you to do real-time upgrades of your application code. But before you can take advantage of it, you need to create a embedded first target system. Unfortunately, the documentation can be quite hard to follow, so this is my attempt at clearly explaining how to create your own first target system. At 12 steps, it's definitely not simple, but you only have to get it right once :)

Assumptions

  • You're running linux/unix, probably Ubuntu.
  • You already have the desired version of erlang installed. I'll refer to the install dir as $ERLDIR, which should be the same as code:root_dir(). The latest release, as of 6/1/2009, is R13B01, with erts-5.7.2.
  • You have your own application code that you want to include in the target system. These apps are located in $REPODIR/lib/, follow the OTP directory structure, and have app files in ebin/.

Steps

  1. Create the initial release resource file , which I'll refer to as FIRST.rel. I'll also assume the release version is 1.0. The rel file should include your own applications as well as any OTP applications your code depends on. Put FIRST.rel in the directory you want to use for creating your target system, such as /tmp/build/. Warning: do not put this file in $REPODIR/releases/. Otherwise step 5 will not work because systools will have issues creating the package.
  2. Optional: Create sys.config in the same directory as FIRST.rel. sys.config can be used to override the default application configuration for any application include in the release.
  3. Open an erlang console in the same directory as FIRST.rel. This directory is where the target system will be created.
  4. Call systools:make_script("FIRST", [no_module_tests, {path, ["$REPODIR/lib/*/ebin"]}]). This will create a boot script for the target system. The script file must be created for the next step to work.
  5. Call systools:make_tar("FIRST", [no_module_tests, {path, ["$REPODIR/lib/*/ebin"]}, {dirs, [include, src]}, {erts, "$ERLDIR"}]). This will create a release package containing your code and include files, plus all the .beam files for the included OTP applications. Noteno_module_tests will ignore errors that don't matter, such as missing src code, which is common for OTP apps.
  6. Exit the console. You should find FIRST-1.0.tar.gz in your current directory. Ideally, this would be the last step, but more likely, you'll need to do the customizations covered below. Unpack the tarball into your target directory and cd into it. For a different take on these first steps, check out An Introduction to Releases with Erlybank.
  7. Copy erts-5.7.2/bin/start into bin/ (if bin/ doesn't exist, create it). Edit bin/start and set the ROOTDIR to your target directory (which should also be your current directory). This is the same $ROOTDIR referred to below. Also copy erts-5.7.2/bin/run_erl and erts-5.7.2/bin/start_erl into bin/, then do mkdir log (or change the paths at the bottom of bin/start). At this point, you may also want to add your own emulator flags, such as -sname NODE -smp auto -setcookie MYCOOKIE +A 128.
  8. Copy erts-5.7.2/bin/erl into bin/ and set the same ROOTDIR as you did in bin/start.
  9. Copy $ERLDIR/bin/start_clean.boot or $ERLDIR/bin/start_sasl.boot to bin/start.boot. I like using start_sasl.boot since it provides more logging. But if you don't want extra logging, use start_clean.boot.
  10. Run echo "5.7.2 1.0" > releases/start_erl.data. This tells erlang which version of erts to run, and which release version to use at startup.
  11. Run bin/erl and call release_handler:create_RELEASES("$ROOTDIR", "$ROOTDIR/releases/", "$ROOTDIR/releases/FIRST.rel", []). Exit the console, and there should be a file releases/RELEASES containg a spec.
  12. That's it, you're done! At this point you should be able to run bin/start, then use bin/to_erl to get the console (Ctrl-D to exit). If you want to deploy to other nodes, you can repack the target system, distribute it to each node, then unpack it and run bin/start. If you do distribute to other nodes, make sure to unpack in the same location on each node, otherwise you'll have to go back to step 7 and modify ROOTDIR.

Fin

At this point you should have customized, self-contained erlang target system that you can distribute and run on all your nodes. Now you can finally take advantage of release handling with hot code swapping. In an upcoming article, I'll cover how to deploy release upgrades using reltools and fab.

  • scrod

    Thanks for summarizing the process! Most Erlang/OTP tutorials neglect the critical deployment step, so this post is quite valuable.

  • scrod

    Thanks for summarizing the process! Most Erlang/OTP tutorials neglect the critical deployment step, so this post is quite valuable.

  • Matteo

    Hi.

    Thank for the tutorial, it works :)

    Just one thing is strange: when I unpack FIRST.tar.gz, erts-5.7.2/bin/ contains start_erl.src instead of start_erl.

    It’s not a big deal, a rename and chmod +x and everything works, but still.. why?

    Any idea? Thanks.

  • Matteo

    Hi.

    Thank for the tutorial, it works :)

    Just one thing is strange: when I unpack FIRST.tar.gz, erts-5.7.2/bin/ contains start_erl.src instead of start_erl.

    It’s not a big deal, a rename and chmod +x and everything works, but still.. why?

    Any idea? Thanks.

  • http://streamhacker.com/ Jacob Perkins

    Could be something new in erts-5.7.2, which I hadn’t tested with. I’ll look into it, thanks for the heads up.

  • Jacob

    Could be something new in erts-5.7.2, which I hadn’t tested with. I’ll look into it, thanks for the heads up.

  • pablo

    I think that copying bin/to_erl is missing.

    I’m following all the steps but when trying:
    bin/start
    bin/to_erl
    I’m getting: No running Erlang on pipe /tmp/erlang.pipe.

    Any idea what I’m doing wrong?

    Thanks

  • pablo

    I think that copying bin/to_erl is missing.

    I’m following all the steps but when trying:
    bin/start
    bin/to_erl
    I’m getting: No running Erlang on pipe /tmp/erlang.pipe.

    Any idea what I’m doing wrong?

    Thanks

  • http://streamhacker.com/ Jacob Perkins

    Pablo, sounds like something’s wrong or missing in bin/start. Make sure all the paths and commands exist. Could be that bin/start is referencing another command in bin/ that isn’t there, such as start_erl or run_erl. Or maybe bin/start is working fine, but bin/to_erl is looking in the wrong directory.

    And you’re right, I should add a sentence in step 8 about copying bin/to_erl.

  • Jacob

    Pablo, sounds like something’s wrong or missing in bin/start. Make sure all the paths and commands exist. Could be that bin/start is referencing another command in bin/ that isn’t there, such as start_erl or run_erl. Or maybe bin/start is working fine, but bin/to_erl is looking in the wrong directory.

    And you’re right, I should add a sentence in step 8 about copying bin/to_erl.

  • pablo

    Jacob, I’ve repeated all the steps from scratch but still getting:
    No running Erlang on pipe /tmp/erlang.pipe.
    The only thing I didn’t do is set emulator flags because I’m not sure what it means.

    Thanks

  • pablo

    Jacob, I’ve repeated all the steps from scratch but still getting:
    No running Erlang on pipe /tmp/erlang.pipe.
    The only thing I didn’t do is set emulator flags because I’m not sure what it means.

    Thanks

  • pablo

    I’ve found several problems:
    1. Without sys.config bin/start won’t run.
    2. I’m using target_system module that automates all the steps you list here:
    http://erlang.org/doc/system_principles/create_target.html#3
    but I had to change the permissions of several files in the bin directory to executable.
    3. In my case the path created by target_system was relative and it might also cause problems, so I changed it to absolute path in several places.

    Thanks

  • pablo

    I’ve found several problems:
    1. Without sys.config bin/start won’t run.
    2. I’m using target_system module that automates all the steps you list here:
    http://erlang.org/doc/system_principles/create_target.html#3
    but I had to change the permissions of several files in the bin directory to executable.
    3. In my case the path created by target_system was relative and it might also cause problems, so I changed it to absolute path in several places.

    Thanks

  • http://www.dolby.com/ f00biebletch

    I looked at create_target in system principles but this post is much more useful and accessible for a first time erlang releaser. Incidentally, I initally created the release on a 32 bit dev machine and deployed out to a 64 bit stage machine which of course did not work well at all – I got cryptic libcrypto errors. I’m trying to be “good” and migrate an scp ebin/* + init.d system to proper erlang release handling, and this post has been by far the most helpful thing on the entire web.

  • http://www.dolby.com f00biebletch

    I looked at create_target in system principles but this post is much more useful and accessible for a first time erlang releaser. Incidentally, I initally created the release on a 32 bit dev machine and deployed out to a 64 bit stage machine which of course did not work well at all – I got cryptic libcrypto errors. I’m trying to be “good” and migrate an scp ebin/* + init.d system to proper erlang release handling, and this post has been by far the most helpful thing on the entire web.

  • http://streamhacker.com/ Jacob Perkins

    Thanks, I’m really glad this post has been helpful.

  • Jacob

    Thanks, I’m really glad this post has been helpful.

  • Michkire_Dmitriy

    Thanks

  • Michkire_Dmitriy

    Thanks

  • Mxz1987918

    I looked at create_target in system principles but this post is much more useful and accessible for a first time erlang releaser[url=http://www.shoppandorabeads.com/]pandora[/url]. Incidentally, I initally created the release on a 32 bit dev machine and deployed out to a 64 bit stage machine which of course did not work well at all – I got cryptic libcrypto errors. I’m trying to be “good” and migrate an scp ebin/* + init.d system to proper erlang release handling, and this post has been by far the most helpful thing on the entire web.

%d bloggers like this: