@@ -242,32 +242,33 @@ defmodule Mix.Tasks.Release do
242
242
but usually separate, and often there are many targets (either multiple
243
243
instances, or the release is deployed to heterogeneous environments).
244
244
245
- To deploy straight from a host to a separate target without cross-compilation,
246
- the following must be the same between the host and the target:
245
+ To deploy straight from a host to a separate target, the following must be
246
+ the same between the host and the target:
247
247
248
248
* Target architecture (for example, x86_64 or ARM)
249
249
* Target vendor + operating system (for example, Windows, Linux, or Darwin/macOS)
250
250
* Target ABI (for example, musl or gnu)
251
251
252
252
This is often represented in the form of target triples, for example,
253
253
`x86_64-unknown-linux-gnu`, `x86_64-unknown-linux-musl`, `x86_64-apple-darwin`.
254
-
255
- So to be more precise, to deploy straight from a host to a separate target,
256
- the Erlang Runtime System (ERTS), and any native dependencies (NIFs), must
257
- be compiled for the same target triple. If you are building on a MacBook
258
- (`x86_64-apple-darwin`) and trying to deploy to a typical Ubuntu machine
259
- (`x86_64-unknown-linux-gnu`), the release will not work. Instead you should
260
- build the release on a `x86_64-unknown-linux-gnu` host. As we will see, this
261
- can be done in multiple ways, such as releasing on the target itself, or by
262
- using virtual machines or containers, usually as part of your release pipeline.
254
+ If you are building on a MacBook (`x86_64-apple-darwin`) and trying to deploy
255
+ to a typical Ubuntu machine (`x86_64-unknown-linux-gnu`), the release will not
256
+ work. Instead you should build the release on a `x86_64-unknown-linux-gnu` host.
257
+
258
+ Typically, different versions of Erlang VM and Elixir are available for
259
+ different targets via package managers, precompiled artifacts, and similar.
260
+ However, to deploy from a host to a separate target, you must also guarantee
261
+ that any dependency with NIFs (Natively-Implemented Functions) are compiled
262
+ for the same triplet. As we will see, this can be done in different ways,
263
+ such as releasing on the target itself, or by using virtual machines or
264
+ containers, usually as part of your release pipeline.
263
265
264
266
In addition to matching the target triple, it is also important that the
265
267
target has all of the system packages that your application will need at
266
268
runtime. A common one is the need for OpenSSL when building an application
267
- that uses `:crypto` or `:ssl`, which is dynamically linked to ERTS. The other
268
- common source for native dependencies like this comes from dependencies
269
- containing NIFs (natively-implemented functions) which may expect to
270
- dynamically link to libraries they use.
269
+ that uses `:crypto` or `:ssl`, which is dynamically linked to the Erlang VM.
270
+ Project dependencies containing NIFs (natively-implemented functions) may
271
+ also dynamically link to system libraries, so check those accordingly.
271
272
272
273
Of course, some operating systems and package managers can differ between
273
274
versions, so if your goal is to have full compatibility between host and
@@ -276,26 +277,7 @@ defmodule Mix.Tasks.Release do
276
277
some systems, especially so with package managers that try to create fully
277
278
reproducible environments (Nix, Guix).
278
279
279
- Similarly, when creating a stand-alone package and release for Windows, note
280
- the Erlang Runtime System has a dependency to some Microsoft libraries
281
- (Visual C++ Redistributable Packages for Visual Studio 2013). These libraries
282
- are installed (if not present before) when Erlang is installed but it is not
283
- part of the standard Windows environment. Deploying a stand-alone release on
284
- a computer without these libraries will result in a failure when trying to
285
- run the release. One way to solve this is to download and install these
286
- Microsoft libraries the first time a release is deployed (the Erlang installer
287
- version 10.6 ships with “Microsoft Visual C++ 2013 Redistributable - 12.0.30501”).
288
-
289
- Alternatively, you can also bundle the compiled object files in the release,
290
- as long as they were compiled for the same target. If doing so, you need to
291
- update `LD_LIBRARY_PATH` environment variable with the paths containing the
292
- bundled objects on Unix-like systems or the `$PATH` environment variable on
293
- Windows systems.
294
-
295
- Currently, there is no official way to cross-compile a release from one
296
- target triple to another, due to the complexities involved in the process.
297
-
298
- ### Techniques
280
+ ### Using matching host and target
299
281
300
282
There are a couple of ways to guarantee that a release is built on a host with
301
283
the same properties as the target. A simple option is to fetch the source,
@@ -334,6 +316,8 @@ defmodule Mix.Tasks.Release do
334
316
production machines can fetch the deployment from the network storage
335
317
and run `bin/my_app start`.
336
318
319
+ ### Using images
320
+
337
321
Another mechanism to automate deployments is to use images, such as
338
322
Amazon Machine Images, or container platforms, such as Docker.
339
323
For instance, you can use Docker to run locally a system with the
@@ -342,9 +326,14 @@ defmodule Mix.Tasks.Release do
342
326
a complete image and/or container with the operating system, all
343
327
dependencies as well as the releases.
344
328
345
- In other words, there are multiple ways systems can be deployed and
346
- releases can be automated and incorporated into all of them as long
347
- as you remember to build the system in the same target triple.
329
+ However, when building such images on your machine, those technologies
330
+ use emulation which may not interplay well with Erlang VM's JIT
331
+ (just-in time) compiler. To address this, you can set this environment
332
+ variable on your build stage:
333
+
334
+ ENV ERL_AFLAGS "+JMsingle true"
335
+
336
+ ## Shutting down
348
337
349
338
Once a system is deployed, shutting down the system can be done by
350
339
sending SIGINT/SIGTERM to the system, which is what most containers,
0 commit comments