|
| 1 | + ## Caution |
| 2 | + |
| 3 | + Please never try to hot upgrade a running application without |
| 4 | + having first a good understand of how a hot upgrade is performed, |
| 5 | + its limitations and steps required. |
| 6 | + |
| 7 | + See next sections for an overview of the hot upgrade process. |
| 8 | + |
| 9 | + ## Hot upgrading a running application |
| 10 | + |
| 11 | + Hot upgrade is the process that allows to seamlessly change |
| 12 | + the code of a running application without the need to |
| 13 | + stopping and restarting it, i.e. mantaining active the |
| 14 | + service in production. |
| 15 | + |
| 16 | + This is one of the most interesting capabilities of Erlang/OTP, |
| 17 | + but it is a very complex process that *cannot* be fully |
| 18 | + automated, i.e. require a good knowledge of the tecnologies |
| 19 | + involved and the configurations files needed and their locations |
| 20 | + at every stage of the process. You have also to know how to |
| 21 | + recognize when a hot upgrade isn't an advisable action, |
| 22 | + because it could have some severe limitations |
| 23 | + and unwanted consequences in some circumstances. |
| 24 | + |
| 25 | + Therefore it is strongly advised you read the official |
| 26 | + documentation about the hot upgrade stuff on the Erlang/OTP |
| 27 | + website, and how Distillery, the technolgy underlying |
| 28 | + the Bootleg task, accomplished that. |
| 29 | + |
| 30 | + Here it is a selected - but not exaustive - list of important |
| 31 | + pieces of documentation to read: |
| 32 | + |
| 33 | + # OTP Design Principles - Releases |
| 34 | + http://erlang.org/doc/design_principles/release_structure.html |
| 35 | + |
| 36 | + # OTP Design Principles - Release Handling |
| 37 | + http://erlang.org/doc/design_principles/release_handling.html |
| 38 | + |
| 39 | + # System Architecture Support Libraries - appup |
| 40 | + http://erlang.org/doc/man/appup.html |
| 41 | + |
| 42 | + # Distillery - Hot upgrades and downgrades |
| 43 | + https://hexdocs.pm/distillery/guides/upgrades_and_downgrades.html |
| 44 | + |
| 45 | + # Distillery - Appups |
| 46 | + https://hexdocs.pm/distillery/guides/appups.html |
| 47 | + |
| 48 | + ### Bootleg hot upgrade task |
| 49 | + |
| 50 | + In the following description we assume that the development |
| 51 | + enviroinment is organized in this way (the build and |
| 52 | + the production places can be the same machine): |
| 53 | + |
| 54 | + * the development machine - where you edit and |
| 55 | + test locally your app source files; |
| 56 | + |
| 57 | + * the build machine - the computer where you will transfer to |
| 58 | + and compile the committed source code; |
| 59 | + |
| 60 | + * the production server - the server where you will deploy |
| 61 | + (transfer to and run) the code previously compiled on |
| 62 | + the build machine. |
| 63 | + |
| 64 | + Bootleg helps you in the hot upgrade process providing |
| 65 | + some specific tasks: |
| 66 | + |
| 67 | + * mix bootleg.build_upgrade |
| 68 | + will tranfer the last committed source code of your application |
| 69 | + from the development machine to the build directory of |
| 70 | + your build machine (for example `~/build/myapp/`), then |
| 71 | + it will clean the directory from the previous code deleting |
| 72 | + every file but the `_build` directory, it will generate the |
| 73 | + `appup` file and compile the newest app release. |
| 74 | + |
| 75 | + Please note that before you can use this task for the first time, |
| 76 | + you have to deploy your _first version_ of your app using |
| 77 | + `bootleg.build`, `bootleg.deploy` and `bootleg.start` |
| 78 | + (or `bootleg.update`); |
| 79 | + |
| 80 | + * mix bootleg.deploy_upgrade |
| 81 | + will transfer the tarball of the compiled app from the |
| 82 | + build machine to the production directory of the production |
| 83 | + machine (e.g. `~/production/myapp/`), then it will extract |
| 84 | + and setting up the needed files; |
| 85 | + |
| 86 | + * mix bootleg.hot_upgrade |
| 87 | + will call `mix distillery <myapp> upgrade <version>` that |
| 88 | + will upgrade the running app to the last version. Notice that |
| 89 | + you *cannot* use this task if the app is not running, or |
| 90 | + if it there is a mismatch in the version numbers of the |
| 91 | + deployed versions. |
| 92 | + |
| 93 | + * mix bootleg.upgrade |
| 94 | + Call in sequences the above tasks in just one command. |
| 95 | + |
| 96 | + ### A step-by-step example |
| 97 | + |
| 98 | + Given you have configured the first version of your app with all |
| 99 | + the needed and appropriately customized Bootleg configuration files, |
| 100 | + you can go through the following steps to release and run the |
| 101 | + first version, and subsequentely hot upgrade it to the newest |
| 102 | + versions: |
| 103 | + |
| 104 | + First version of your app |
| 105 | + |
| 106 | + # Step 1 - deploy the first version of your app |
| 107 | + edit the version number of your in the mix.exs file |
| 108 | + (or in the file if you use an external reference), |
| 109 | + to the first version (e.g. 0.1.0); |
| 110 | + |
| 111 | + # Step 2 - Commit |
| 112 | + commit the changes you've made in step 1; |
| 113 | + |
| 114 | + # Step 3 - Build the first version |
| 115 | + use `mix bootleg.build` (not bootleg.build_upgrade!) to build |
| 116 | + your first version; |
| 117 | + |
| 118 | + # Step 4 - Deploy the first version |
| 119 | + use `mix bootleg.deploy` (not bootleg.build_upgrade!) to deploy |
| 120 | + your first version; |
| 121 | + |
| 122 | + # Step 5 - Run the first version |
| 123 | + use `mix bootleg.start` to run the app |
| 124 | + |
| 125 | + now your first version is up and running. To upgrade it |
| 126 | + to the future version, you have to follow these steps instead: |
| 127 | + |
| 128 | + Following versions |
| 129 | + |
| 130 | + # Step 1 - update the version number |
| 131 | + e.g. 0.2.0 |
| 132 | + |
| 133 | + # Step 2 - Commit |
| 134 | + |
| 135 | + # Step 3 - Build the new version |
| 136 | + use `mix bootleg.build_upgrade` |
| 137 | + |
| 138 | + # Step 4 - Deploy the new version |
| 139 | + use `mix bootleg.deploy_upgrade` |
| 140 | + |
| 141 | + # Step 5 - Hot upgrade the new version |
| 142 | + use `mix bootleg.hot_upgrade` |
| 143 | + |
| 144 | + (or you can execute just the `bootleg.upgrade` |
| 145 | + that packs the previous tasks together if you don't need to |
| 146 | + manually adjust the created `appup` file) |
| 147 | + |
| 148 | + Now you have an upgraded version running. But if you stop |
| 149 | + and restart it, the previous version will be launched instead |
| 150 | + of the most recent. This is useful because if your new version |
| 151 | + has some blocking bug, you can easily restart the service to the last |
| 152 | + working release. |
| 153 | + |
| 154 | + If you are shure that you want to having the last version restarted, |
| 155 | + just delete the folder `~/production/myapp/var`. This folder contains |
| 156 | + the file `start_erl.data` that lists the version number to start with. |
| 157 | + Deleting the `var` folder will automatically create it next time the app |
| 158 | + is started, with the last version number. |
0 commit comments