Elixir Getting Started Guide

Thanks. If memory serves, I saw those errors and warnings on the first deploy as well as subsequent ones. They stop appearing after a minute or two.

Hi @brainlid I have some feedback on the static cookie and observer guides, hope this is the right place for them.

First of all, thanks a lot for writing them! I learned a lot getting my elixir app running on fly and even found some bugs in how I was handling configuration for my gigalixir setup :slight_smile:

On to the feedback:

You suggest setting the cookie in the releases function in mix.exs. I tried to avoid this as I didn’t want the shared secret to be in my code repository. I know that we’re relying on the wiregaurd tunnels for security more than this static cookie, but still it felt like bad form to me.

In the docs I saw

At runtime, we will first attempt to fetch the cookie from the RELEASE_COOKIE environment variable and then we’ll read the releases/COOKIE file.

I set the RELEASE_COOKIE using flyctl secrets set and everything worked perfectly!

I think this would make the process a little easier, and can be done in the same step in the guide where we set SECRET_KEY_BASE.

Secondly, this is very minor, but the observer script should start with #!/usr/bin/env bash for portability (I’m a nixos user and have been trained to do this always :smiley: )

Finally a question: I can connect to IEx by either sshing in or connecting using distributed elixir like we do for observer.

Do you think there’s any advantage to either?

Hi @brainlid, thanks for the guide. Unsure why but cloning the sample repo (changing nothing at all) and following the guide, it doesn’t want to deploy.
Have tested in both Sydney and Virginia (the default) regions.

Here’s the final lines of the deploy

Running: `/app/bin/hello_elixir eval HelloElixir.Release.migrate` as nobody       
         2021/07/08 00:38:42 listening on [fdaa:0:2f24:a7b:ad6:f8da:1834:2]:22 (DNS: [fdaa::3]:53)
: not foundpp/bin/hello_elixir: /app/releases/0.1.0/env.sh: line 2:
         Main child exited normally with code: 127
         Starting clean up.
Error Release command failed, deployment aborted

Any thoughts on how to get this deployed, or whether I need to make changes to the repo before it’ll work?

Hi @samw! I can’t tell what’s wrong from the output. What is the app name that was generated for your instance?

Hey @brainlid, generated name is crimson-forest-7023. Happy to supply more logs too if that’d help.

I also tried building the docker image and that’s possibly where the problem is? It built successfully but wouldn’t let me run the container (although could start the container in the ash shell per your comment here).

The main difference I see in your logs is this line:

/app/bin/hello_elixir: /app/releases/0.1.0/env.sh: line 2: 
: not found

The env.sh file is generated when building a release from the env.sh.eex file.

Going by the error “not found”, I can’t tell if the file wasn’t found or there was an error performing a command from that file.

One thing you can try is to SSH into the app (if that works given it’s state) and see if the file exists /app/releases/0.1.0/env.sh and if, so, you can cat it to see that it was generated correctly.

I assume you changed the fly.toml file. It needs to have your app’s name.

@brainlid the fly.toml has app = "crimson-forest-7023"; that’s the generated name it gave. Tested changing it to app = "hello_elixir" but that gives Error not possible to validate configuration: server returned Could not resolve App so I don’t expect that’s what you meant. Just did flyctl launch again and it’s now named broken-snow-4053.

It must be failing too early in the deploy to let me SSH into it; returns Error connect to SSH server: dial: lookup broken-snow-4053.internal. on fdaa:0:2f24::3: no such host

If I build the Docker container locally and try run it directly, it exits with a similar error, returning : not foundlixir: /app/releases/0.1.0/env.sh: line 2: (looks like it overwrites part of the message somehow).
Connecting directly with docker run -it --rm hello_elixir /bin/ash and using cat on the env.sh file as requested, looks normal to me:

/app $ cat releases/0.1.0/env.sh
#!/bin/sh

# Sets and enables heart (recommended only in daemon mode)
# case $RELEASE_COMMAND in
#   daemon*)
#     HEART_COMMAND="$RELEASE_ROOT/bin/$RELEASE_NAME $RELEASE_COMMAND"
#     export HEART_COMMAND
#     export ELIXIR_ERL_OPTIONS="-heart"
#     ;;
#   *)
#     ;;
# esac

# Set the release to work across nodes. If using the long name format like
# the one below (my_app@127.0.0.1), you need to also uncomment the
# RELEASE_DISTRIBUTION variable below. Must be "sname", "name" or "none".

ip=$(grep fly-local-6pn /etc/hosts | cut -f 1)
export RELEASE_DISTRIBUTION=name
export RELEASE_NODE=$FLY_APP_NAME@$ip
export ELIXIR_ERL_OPTIONS="-proto_dist inet6_tcp"

Not sure if it’s relevant but I couldn’t run the env.sh file due to missing permissions (could well just be a Docker quirk that doesn’t affect this though)

@samw Locally running the Docker container will fail because ENV settings like $FLY_APP_NAME won’t exist.

When you run flyctl launch, it generates the app name for you but it also regenerates the fly.toml file. My question about that file is really like, “It needs to be different – it needs your app name, but it gets overwritten when you generate an app name… so you have to edit back in some of the settings.”

When working with a cloned repo, that’s the one file where it becomes a little sticky.

@brainlid so just to confirm the order:

  1. git clone https://github.com/fly-apps/hello_elixir-dockerfile hello_elixir
  2. cd hello_elixir
  3. flyctl launch
  4. flyctl deploy

This should work with no changes? That’s the impression I get from the guide; I’ve double-checked and the generated fly.toml uses the existing settings so the only change that flyctl launch makes is to app at the top (confirmed in git diff).

Do I have to make any changes or should those 4 commands in a row just work?

@samw Thanks for working with me on this! I’d like to iron out any kinks people might have and update the guide/repo if needed.

Here’s the steps needed:

  1. git clone https://github.com/fly-apps/hello_elixir-dockerfile hello_elixir
  2. cd hello_elixir
  3. flyctl launch - Don’t deploy yet. Keep the generated app name in fly.toml but revert the other changes.
  4. Go through the process of Preparing to Deploy section. You need a database to connect to, and the ENV values set for your app. Both for the mix phx.gen.secret and the database connection.
  5. flyctl deploy

There is a little bit of a dance that happens the first time you deploy an app that uses a database. Because the database app must exist first for the app to start. The step with setting the ENV for the mix phx.gen.secret as a secret will appear to fail when you first run it because the app can’t be deployed yet. But you just want the ENV set and that works.

I just went through the process and cloned, launched and deployed so otherwise it should all work.

@brainlid sorry that’s still not working! I actually went through that full process the first time and just did again with a new testing DB; exact same error. Switched from organisation account to personal in case that helped but no luck. Anything you guys can double-check to see what it’s actually building?
I’m running this on Windows too in case that’s relevant (shouldn’t be but who knows); can try again on wsl if you think that has a shot.

The one other thing that may be relevant is that creating the DB failed monitoring:

Monitoring Deployment
Error 1 error occurred:
        * No deployment available to monitor

I can see the DB fine in the apps dashboard though and it attached fine.

Hmm. Looking at the logs for your newly created app, it’s the same issue.

/app/bin/hello_elixir: /app/releases/0.1.0/env.sh: line 2: 
: not found

If you run flyctl secrets list, does it inclue DATABASE_URL and SECRET_KEY_BASE?

Yes both of them are there:

NAME            DIGEST                           DATE       
DATABASE_URL    8024c100fe1aefec9ae93f39ce8af633 36m14s ago
SECRET_KEY_BASE 0aee23febbe904ae148ba7a6047b2742 53m56s ago

Well that’s good.

You can try building it where the Docker build happens on Fly servers using the --remote-only flag…

fly deploy --remote-only

You can try that to help rule out if the problem is the local Windows build environment or not.

I don’t have Docker running locally at the moment so is building remotely already, but just ran it again with that flag to confirm.
Had Docker up yesterday and same issues though.

@samw did you ever try this with wsl? The “not found” is suspicious, like a file’s not getting added to the docker context.

@kurt just tried with wsl and got an entirely different error! Looks like the pipe to Docker shuts part-way through:

Deploying spring-smoke-2645
==> Validating app configuration
--> Validating app configuration done
Services
TCP 80/443 ⇢ 4000
Remote builder fly-builder-throbbing-frost-6382 ready
==> Creating build context
--> Creating build context done
==> Building image with Docker
ERRO[0604] Can't add file /c/programming/fosters/site_track/hello_elixir_wsl/_build/dev/lib/ecto/ebin/Elixir.Ecto.Repo.Queryable.beam to tar: io: read/write on closed pipe 
ERRO[0604] Can't close tar writer: io: read/write on closed pipe 
Error error building: error building with docker: error during connect: Post "http://fly-builder-throbbing-frost-6382.internal:2375/v1.41/build?buildargs=%7B%7D&cachefrom=null&cgroupparent=&cpuperiod=0&cpuquota=0&cpusetcpus=&cpusetmems=&cpushares=0&dockerfile=Dockerfile&labels=null&memory=0&memswap=0&networkmode=&platform=linux%2Famd64&rm=0&shmsize=0&t=registry.fly.io%2Fspring-smoke-2645%3Adeployment-1625796128&target=&ulimits=null&version=": write tcp [fdaa:0:2f24:a7b:ce2:0:a:100]:48674->[fdaa:0:2f24:a7b:ab8:0:299e:2]:2375: endpoint is closed for send

Tested that disabling VPN didn’t fix it.
It sat for ages before that with the line Sending build context to Docker daemon 1.049MB, then replaced that with the error messages.

I noticed that the file it can’t add is _build/dev/lib/ecto/ebin/Elixir.Ecto.Repo.Queryable.beam. So it fails to add a dev build (should be prod) of a dependency.

Yeah that’s weird; just ran through the same process so not sure why it would be different.
Happy to set WSL aside again though & revisit the other build (got a lot further through) - given the fly deploy --remote-only failed too, what are the next steps to debug this?
I can try with a new account and a different dev machine if that would be useful.

@brainlid I just made a fresh account under a coworker’s email and deployed the same repo from scratch. Same error! It’s even on a different machine (still Windows) so really not sure what to do now.