Cron-Manager and rails console tasks

I’m following along this guide and am able to pass along a command to my app via the schedule.json file, however, the fly logs on my main app indicate that the command is invalid.

I’m trying to run a a task via rails runner:

"/rails/bin/rails runner RailsService.new().test"

Fly logs on the main app shows:

ERROR Error: failed to spawn command: /rails/bin/rails runner RailsService.new().test: No such file or directory (os error 2)
does `/rails/bin/rails` exist and is it executable?

I’ve tried multiple versions of rails runner and bin/rails runner to no success…

Thanks in advance.

Bumping for awareness

cron-manager is a separate machine running on a separate image; your Rails app is not running there. I’d need to know more of what you are trying to do to help you further, but perhaps what you are looking for is to have your cron job make a request to your Rails app? If so, perhaps curl could help…

Okay, maybe I didn’t explain correctly, I’ll try to further elaborate.
I have two apps on fly, let’s call them “rails-app” and “cron-app”.
I am trying to run a rails runner command on the rails-app, via the cron-app. I am able to see the command running on the rails-app.log, meaning that the cron-app is successfully sending the command to the rails-app. However, I get the following error (on the rails-app.log):

ERROR Error: failed to spawn command: /rails/bin/rails runner RailsService.new().test: No such file or directory (os error 2)
does `/rails/bin/rails` exist and is it executable?

What does your Dockerfile look like for the Rails app? In particular, what is the WORKDIR?

# syntax = docker/dockerfile:1

# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
ARG RUBY_VERSION=3.1.2
FROM ruby:$RUBY_VERSION-slim as base

LABEL fly_launch_runtime="rails"

# Rails app lives here
WORKDIR /rails

# Set production environment
ENV BUNDLE_DEPLOYMENT="1" \
    BUNDLE_PATH="/usr/local/bundle" \
    BUNDLE_WITHOUT="development:test" \
    RAILS_ENV="production"

# Update gems and bundler
RUN gem update --system --no-document && \
    gem install -N bundler

# Install packages needed to install nodejs
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y curl && \
    rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Install Node.js
ARG NODE_VERSION=16.15.1
ENV PATH=/usr/local/node/bin:$PATH
RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
    /tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
    rm -rf /tmp/node-build-master


# Throw-away build stage to reduce size of final image
FROM base as build

# Install packages needed to build gems and node modules
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y build-essential git libpq-dev libvips node-gyp pkg-config python-is-python3

# Install yarn
ARG YARN_VERSION=1.22.22
RUN npm install -g yarn@$YARN_VERSION

# Build options
ENV PATH="/usr/local/node/bin:$PATH"

# Install application gems
COPY --link Gemfile Gemfile.lock ./
RUN bundle install && \
    bundle exec bootsnap precompile --gemfile && \
    rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git

# Install node modules
COPY --link .yarnrc package.json yarn.lock ./
COPY --link .yarn/releases/* .yarn/releases/
RUN yarn install --frozen-lockfile

# Copy application code
COPY --link . .

# Precompile bootsnap code for faster boot times
RUN bundle exec bootsnap precompile app/ lib/

# Precompiling assets for production without requiring secret RAILS_MASTER_KEY
RUN SECRET_KEY_BASE=DUMMY ./bin/rails assets:precompile


# Final stage for app image
FROM base

# Install packages needed for deployment
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y curl imagemagick libvips postgresql-client && \
    rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Copy built artifacts: gems, application
COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
COPY --from=build /rails /rails

# Run and own only the runtime files as a non-root user for security
RUN groupadd --system --gid 1000 rails && \
    useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \
    chown -R 1000:1000 db log storage tmp
USER 1000:1000

# Deployment options
ENV RAILS_LOG_TO_STDOUT="1" \
    RAILS_SERVE_STATIC_FILES="true"

# Entrypoint sets up the container.
ENTRYPOINT ["/rails/bin/docker-entrypoint"]

# Start the server by default, this can be overwritten at runtime
EXPOSE 3000

I know this will sound annoying, but are you sure that your command is running on the Rails machine?

Inside the first square brackets in log lines is the machine number.

The error message you are getting says that /rails/bin/rails is not found, and the Dockerfile you provided places your rails app in the /rails directory. The possibilities are that this command is not running on the rails machine, or that your app does not contain a bin/rails file, or that file is not marked as executable.

The last possibility generally only affects Windows users, and is typically handled when the Dockerfile is generated. The fix is to add the following lines:

Okay this is helpful…
On my rails-app, the machine number that appears in the logs does not appear in any of my machines in my Sign in to Your Account · Fly
It also changes after each failed cron-job… (It seems)

The image your cron-job Machine is running is livebook:0.11.4 This image is used within the example config, so i’m guessing that’s where the problem lies. If you want to run a Rails command, you will need to configure your cron-job to use the appropriate image.

1 Like

Do you know what image that is by chance ?

In your specific case, it’s probably going to be the same image you’re Rails app is running.

You can find this by running: fly image show --app <app-name>

1 Like

I should note though that if this is the only cron-job you need to run, there are Rails specific cron gems you could use that could make things easier for you. E.G. whenever.

1 Like

Interesting, I didn’t know about this. I was previously doing this with a fly redis-server and found it to be too costly. I will look into “whenever”, however i have a few cron jobs I will be running.

Regardless, we are up and running as of now, I thank you both for your time and help :slight_smile:

1 Like

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