Unable to migrate/seed Rails app

Hi there,

I’ve previously run the following and it has worked:

fly ssh console
cd /rails
apt-get update
apt-get install -y nodejs
bin/rails db:migrate
bin/rails db:seed

The reason for running update and nodejs parts was because I was getting an ExecJS::RuntimeUnavailable: Could not find a JavaScript runtime error without them.

I just updated my rails/ruby version and the above doesn’t work anymore. When I run the node command, it runs and then quits the fly console (i.e. I’m unable to enter the subsequent migrate command).

Any idea as to what I should do?

It is probably worth updating your Dockerfile:

bundle update dockerfile-rails
bin/rails generate dockerfile

This should also address the ExecJS::RuntimeUnavailable: Could not find a JavaScript runtime problem. You also shouldn’t need to run migrate yourself as db:prepare will be run by the release command (in fly.toml) if you are running with postgresql or in the dockerfile-entrypoint (if you are running sqlite3).

What likely is happening is that you are running out of memory. See: Dockerfiles and fly.toml · Fly Docs

I did update the dockerfile using that command right after I had updated rails. The exec error has been there for a while (even before I upgraded rails). Is there a fix for that?

If your Gemfile or Gemfile.lock has execjs in it, your generated Dockerfile should look like the following:

Note: these lines appear before FROM base as build so that node will be in the base (and therefore deployed) image, and the PATH will also be set.

Can you verify that (1) execjs is in your Gemfile.lock, (2) that you Dockerfile matches the description above, and (3) when you run fly ssh console that your PATH contains /usr/local/node/bin?

(1) yes, execjs is there
(2) yes it does match
(3) i get this when I run fly ssh console: root@90800d5b656168:/rails#

Also, I regenerated the dockerfile with the lower memory. I’m now able to get past the node bit but the seeding doesn’t seem to take place fully. The deployed app has some missing things.

Also, when I run echo $PATH within fly ssh console, i get the following:
/usr/local/bundle/bin:/usr/local/bundle/gems/bin:/usr/lib/fullstaq-ruby/versions/3.2.2-jemalloc/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Running /usr/local/node/bin/node -v returns v14.16.1

How do I fix this memory problem? I added the virtual memory as well. I mean, it’s a toy app so I don’t want to pay for extra memory.

It is not clear why this is occurring, but I found a workaround that works for me:

fly ssh console --pty -C bash

Adding swap should solve this problem. You can verify that your swap is activated properly using:

# cat /proc/swaps 
Filename                                Type            Size            Used            Priority
/swapfile                               file            524284          0               -2

Nothing comes up when I run cat /proc/swaps within the ssh console. The table headings come up but there aren’t any values. How do I ensure that swap is properly configured? It sounds like a memory problem because when I run rails db: seed in the ssh console, it runs for a bit and then I get the following error:

Error: ssh shell: wait: remote command exited without exit status or exit signal

Below is my fly.toml file

app = "app"
primary_region = "iad"
kill_signal = "SIGINT"
kill_timeout = "5s"

[experimental]
  auto_rollback = true

[[services]]
  protocol = "tcp"
  internal_port = 3000
  min_machines_running = 0
  processes = ["app"]

  [[services.ports]]
    port = 80
    handlers = ["http"]
    force_https = true

  [[services.ports]]
    port = 443
    handlers = ["tls", "http"]
  [services.concurrency]
    type = "connections"
    hard_limit = 25
    soft_limit = 20

  [[services.tcp_checks]]
    interval = "15s"
    timeout = "2s"
    grace_period = "30s"
    restart_limit = 0

[[statics]]
  guest_path = "/rails/public"
  url_prefix = "/"
  swap_size_mb = 512

Place this in the top group, unindented.

this is where i put it. Doesn’t make a difference.

app = "app-name"
primary_region = "iad"
kill_signal = "SIGINT"
kill_timeout = "5s"
swap_size_mb = 512

And you redeployed? That should work.

You can also set this up yourself. Remove that from fly.toml, remove USER rails:rails from the Dockerfile, and edit your bin/docker-entrypoint to look like this:

Yes I redeployed after making that change.

These commands should be entered within the fly ssh console?

how/where exactly should I be running these commands?

At the moment, I’m still at a loss why swap_size_mb doesn’t work for you, I just tried it again and it works for me.

As to those commands, if you look at https://github.com/fly-apps/dockerfile-node/tree/main/test/base/swap you will see an example Dockerfile and dockerfile-entrypoint script. From the Dockerfile, copy the following lines:

Place the docker-entrypoint script in your bin directory.

Note that this script will run ./bin/rails db:prepare when you start your server; this will automatically run migrate and seed so there should be no need to ssh into your server to perform these functions.

sorry but where is the bin directory?

those 2 lines are already on my dockerfile…

In the same directory as your Dockerfile. A typical rails application looks like the following:

ok, this is now fixed but I still had to get into ssh and run migrate/seed even though the entrypoint file had db:prepare…

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.