Nicd

Nicd

I recently got an ARM laptop to replace my old amd64 one. This poses a problem for me. I run my production service on an amd64 VPS (Hetzner) that runs Ubuntu Server.

Thus far I’ve used a Vagrant box with Ubuntu to build a release in, and then uploaded that release to my production server, unpacked it, and restarted (it’s quite manual, yes, but I don’t release often). Now, of course, due to NIFs such as Comeonin and AppSignal, I cannot build on ARM.

How have you typically handled this? I found some earlier threads suggesting the use of Docker or building the release on GitHub (I use GitLab though):

Is this still the way to go? I have tried Burrito earlier, but I could not get it to build the release correctly (problem with NIFs).

I know nowadays I could run an ARM VM with amd64 binaries inside using Rosetta 2, but I don’t know how big of a hassle it would be.

One thought was GitLab CI, I guess I could use that to build a release out of every push to some branch? Could I get it to match the Ubuntu environment closely enough so that it would work? Though, I’m on a free account so I don’t know how much processing it allows me to do.

Showing Posts 21 to 12

binaryape

binaryape

I’m using Docker in buildx mode to create releases for amd64 - I wouldn’t call it fast but it’s adequate

michallepicki

michallepicki

Looks like there’s a better way. This didn’t work for me on Erlang/OTP 25.1.1 but seems to have worked on 25.3.2.2

michallepicki

michallepicki

I succeeded recently in building a release on a Apple Silicon Mac inside a UTM emulated x64 system (I used Ubuntu Server, to not waste cycles for a GUI when emulation is so slow). But for this particular service we don’t care about performance, so it was more convenient to use Docker with Erlang built from source with the JIT disabled. The asdf / kerl flag I used in my Dockerfile was:

ENV KERL_CONFIGURE_OPTIONS "--disable-jit"

This allows to avoid the qemu Erlang JIT issue.

derek-zhou

derek-zhou

I always have a pc at home, powered-on, reversed ssh tunneled to one of my VPS. So I do not use my MacBook to build the release, even mine is x86.

derpycoder

derpycoder

I was reading how others are doing it, and here’s what I gathered.

  1. We can use GitHub Action-like services.
  2. We can build directly on the server and replace the instance.
  3. Blue/Green deployment using 2 VPS. (Spin up a new VPS, that is identical to the running VPS, and deploy in that VPS like it’s staging, then replace the running VPS with the newly spawned one or move the artifact across. (Shutdown the VPS we are not using))
  4. Blue/Green deployment, but using tools like Packer & Terraform.

We can use tools like SCP, S3, CROC to move our build artifacts across servers.

P.S. Still learning by experimenting with all the ways to do it.

jbriggs

jbriggs

I build releases for ARM systems on an x86 build server.

I take the files for the ARM system’s ERTS, place them on the build server and then reference them in the release I am building.

Here is a snippet from the mix.exs, “releases” section:

  releases: [                                                                                                               
    sra_rps: [
      overwrite: true,
      include_executables_for: [:unix],

      # Keep the docs
      strip_beams: [keep: ["Docs", "Dbgi"]],

      # Path to the ERTS copied from ~/.asdf/installs/erlang/24.2.1
      include_erts: "/usr/local/share/erlang_rps/erts-12.2.1",
      ...

The only provisio is that building any NIFs or port programs becomes much more complicated. The only port programs I have are very stable, never needing changes, so I include compiled versions as binaries in priv.

s6o

s6o

Very very slow :wink:

I’m in a similar situation, my cloud infra is x86_64 (Ubuntu) and cannot just build on my M1 mac mini. So I also tried UTM on M1 with x86 emulation … its was pretty much unusable for builds.

So I run my builds on my 2015 intel MBP, which runs UTM (virtualization) for the same architecture. The UTM instance is running Lubuntu and my builds are way faster than on M1

Nicd

Nicd OP

Oh, and here’s the configuration I ended up with (permalinked to the current version, so maybe check if it has changed if you come from the future): .gitlab-ci.yml · e037b3c8245f2db487a13539062de726749b6156 · CodeStats / code-stats · GitLab

Let me know if you think I could do something better!

Nicd

Nicd OP

Thanks everyone for the answers, I hope they are also useful for any future readers that might find this thread. :slight_smile: I ended up building the release in GitLab CI which was surprisingly painless. I haven’t tested deploying the artifact yet, though, but it looks sensible enough when extracted. :grin:

cjbottaro

cjbottaro

Not only slow, but I’ve never got it to actually work for me. It always ends up crashing for some reason.

I’m in the camp of just letting your CI build the images (we use GitHub Actions).

Kind of an aside, but related… BuildKit lets you make multiarch images pretty easily, using a Kubernetes cluster to farm out the build jobs to machines of different architectures. My M1 is so fast though, that I like to do the ARM build locally though. I have a little bash script to help with this.

Build ARM locally, then use a BuildKit Kubernetes builder to build AMD64 and mash them together in to a multiarch image:

# mbuild <dir> <repo> <tag>
# mbuild elixir $AW_REGISTRY/1.14.0-erlang-25.0.4-alpine-3.16.1 latest

set -e

TAG=${3:-latest}

docker build $1 -t $2:arm64
docker push $2:arm64

docker buildx build $1 \
  --push \
  --platform linux/amd64 \
  -t $2:amd64 \
  --builder aw-amd64-builder-

docker manifest create $2:$TAG \
--amend $2:amd64 \
--amend $2:arm64

docker manifest push --purge $2:$TAG

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
Aludel - LLM Evaluation Workbench Aludel is an embeddable Phoenix LiveView dashboard for evaluating and comparing LLM prompts across mult...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews