Phoenix getting started guide is missing some important steps

I was off to a bit of a rough start trying to deploy my Phoenix 1.6.4 application to fly.io using the getting started guide. I believe there are some steps that are missing to make it work even for the latest version (1.6.7). Here’s my attempt at a more “complete” guide. Feel free to incorporate it into the official docs if you want :slight_smile:.

It’s very important that you have a project that’s created with Phoenix 1.6.7 or higher for this to work. I had a project that was generated using an earlier version of Phoenix, and then upgraded to 1.6.7, and that didn’t work because of changes to how the config files look in the 1.6 line. If you need to bring an older project up to speed I suggest using something like PhoenixDiff to see which changes you need to make.

Here are the steps I took with a fresh Phoenix 1.6.7 project to get it to work.

# Create a completely new phoenix app.
mix phx.new hello

# Generate a live view page, schema and database migration.
# This is important to be able to demonstrate that Ecto migrations and
# live view CORS protection works as intended. I had issues with my
# setup earlier that took a while to notice. Creating a live view like this
# will help in surfacing any problems early on.
cd hello
mix phx.gen.live Demo Message message content:string

# IMPORTANT: Add the routes to lib/web/hello_web/router.ex as instructed.

# Generate the rel/overlays/bin/[server|migrate] scripts.
# The `--ecto` flag is because of this bug that's present in 1.6.7.
# https://github.com/phoenixframework/phoenix/pull/4796
# It'll be fixed in 1.6.8, but for now this is essential because otherwise
# your VM won't come up properly and complain that /app/bin/migrate
# doesn't exist.
mix phx.gen.release --ecto

# Login (or signup)
fly auth login  # or `fly auth signup`

# Launch the app (create a new app).
# Btw, this naming confused me a lot.
# My issue was that I tried to run "launch" multiple times, when
# it should only be run once. Perhaps naming it something like
# "fly init" / "fly app init" would be better since it really does the 
# init for you.
fly launch
  postgres: yes
  deploy: no  # Don't try to deploy, it won't work!

# Set the SECRET_KEY_BASE secret.
# Phoenix expects it in runtime.exs, and things won't work without it.
# I could not find anything about this in the docs.
fly secrets set SECRET_KEY_BASE=`mix phx.gen.secret`

# Deploy your app.
# You can now visit it at https://<appname>.fly.dev/messages,
# where you have your live view to verify that both the Postgres
# and CORS works as expected.
fly deploy --detach && fly logs

I think it’s pretty common to have a node dependency or two, which also caused me some issues. In my case I had alpinejs and daisyui. To make this work I needed to do the following changes to the Dockerfile.

  1. Add nodejs npm to the apt install for the builder image.
  2. Add the following line after COPY assets assets:
    RUN npm install --prefix ./assets

Once I got it all working I’ve had a blast working with fly.io. Seriously well done to y’all who built it!
Things I love:

  • The “generator” approach with the Dockerfile. It’s all industry standard tools under the hood, and it’s easy to modify and follow what’s happening.
  • No OAuth access required to my repo, and no automagic builds being done. It’s up to us to set up the build & deploy pipeline that works the best for us.
  • The 1-minute deployments! It’s pretty amazing compared to the 10-minute plus deployments I’ve experienced with other platforms.
  • The ability to SSH into one of your VMs.
  • VM performance. I used other platforms that performed about 15x worse than my local machine when it came to things like bcrypt. With fly.io everythies…flies :stuck_out_tongue: . It’s just as fast, if not faster, as running it on my local machine, even on the free tier with the shared CPU.
  • The very generous and flexible free tier. It allowed me to experiment freely with Fly, and this is what ultimately made me decide to go for Fly instead of one of the competitors.

Things that could use some work:

  • The docs. They’re OK, but not great. Hopefully the above can help with improving them a bit.
  • The error messages. I for example got “Error error connecting to docker: failed building options: failed probing “personal”: context deadline exceeded” when I just had forgot to fly auth login.
  • flyctl feels a bit overwhelming at first. Since the web UI is very limited one has to learn flyctl to get started. Doing a fly help and seeing a wall of commands was very overwhelming. I love how kubectl groups their commands, maybe something like that?
  • The sometimes “hacky” solutions needed to do what I consider basic things, like changing shared_preload_libraries for Postgres.
3 Likes

THANK YOU!

This was driving me crazy for the last hour - I was getting kernel panics on deploys. The missing

was the key.

Thank you for taking the time to post your findings!

1 Like

These are great notes, but one comment on the above: Phoenix prints everything you need to change when you run that upgrade. It’s easy to miss, so we’ve been working on a way to do as much as we can automatically.

Fair enough, Phoenix probably did tell me all those things, but since I didn’t need it at the time I most probably ignored it, dumb as I am :stuck_out_tongue:.

Great to hear that you’re working on a way to do as much as you can automatically, much appreciated :slight_smile: .