Using cron with Shopify Remix App

Hi everyone

I am a bit of a newbie to the world of Shopify Remix, but I am really loving the stack. :slightly_smiling_face:

I want to use node-cron in my Remix App.
I am using fly.io for my hosting requirements:

fly deploy

The default container script Dockerfile, does not pre-install cron.

But the documentation suggests, using a library called supercronic:

https://fly.io/docs/app-guides/supercronic/

The part I don’t get, is the bit about processes in fly.toml?

[processes]> > # The command below is used to launch a Rails server; be sure to replace with the command you’re using to launch your server.> > web = “bin/rails fly:server”> > cron = “supercronic /app/crontab”> > # Make sure there’s only one processes entry under [[services]]> > [[services]]> > processes = [“web”]

I feel that we should remove the services section, altogether, and the web part of the processes section. I am pretty sure these don’t apply, if you are running a Node based application, like a Remix App?

My current fly.toml does not have a services or a processes section.

I presume Remix Apps don’t require Rails? They run off NodeJs, which is pre installed from the Dockerfile script:

FROM node:18-alpine> > EXPOSE 3000> > WORKDIR /app> > COPY . .> > RUN npm install> > RUN npm run build> > # You’ll probably want to remove this in production, it’s here to make it easier to test things!> > RUN rm prisma/dev.sqlite> > RUN npx prisma migrate dev --name init> > CMD [“npm”, “run”, “start”]

Can anyone explain the best way to install cron, using the default Remix fly.io container?

Maybe I can just add this to my Dockerfile:

RUN apt-get update> > RUN apt-get install -y cron

Does anyone know where I should add these two commands, in the Dockerfile?

Update:

I can now show you, what the Dockerfile, should look like:

FROM node:18-alpine

EXPOSE 3000
WORKDIR /app
COPY . .

RUN npm install
RUN npm run build

# You'll probably want to remove this in production, it's here to make it easier to test things!
RUN rm prisma/dev.sqlite
RUN npx prisma migrate dev --name init

# Install prerequisites
RUN  add --update curl

# Latest releases available at https://github.com/aptible/supercronic/releases
ENV SUPERCRONIC_URL=https://github.com/aptible/supercronic/releases/download/v0.2.29/supercronic-linux-amd64 \
    SUPERCRONIC=supercronic-linux-amd64 \
    SUPERCRONIC_SHA1SUM=cd48d45c4b10f3f0bfdd3a57d054cd05ac96812b
RUN curl -fsSLO "$SUPERCRONIC_URL" \
 && echo "${SUPERCRONIC_SHA1SUM}  ${SUPERCRONIC}" | sha1sum -c - \
 && chmod +x "$SUPERCRONIC" \
 && mv "$SUPERCRONIC" "/usr/local/bin/${SUPERCRONIC}" \
 && ln -s "/usr/local/bin/${SUPERCRONIC}" /usr/local/bin/supercronic

CMD ["npm", "run", "start"]

I am still not sure about the fly.toml file part, though?

Maybe it would like this:

# fly.toml app configuration file generated for sb-user-admin-app-v1 on 2024-03-22T11:44:39Z
#
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
#

app = 'sb-user-admin-app-v1'
primary_region = 'ams'

[build]

[processes]
# web = "bin/rails fly:server" # REMOVE????? // I am not using Rails; I am using NodeJs/remix
cron = "supercronic /app/crontab"
# [https://fly.io/docs/apps/processes/](https://fly.io/docs/apps/processes/) It says:
# Once there’s a [processes] section in your config, flyctl assumes this is a complete list of your processes. If you want an app process group alongside others, add it to the config explicitly.
# So maybe, we should add:
app = 'sb-user-admin-app-v1' # But is this the correct value?

[env]
PORT = "8081"
SHOPIFY_APP_URL = "https://sb-user-admin-app-v1.fly.dev"
SHOPIFY_API_KEY = "[SHOPIFY_API_KEY ]"
SCOPES = "read_checkouts,read_content,read_customers,read_files,read_orders,read_products,write_checkouts,write_customers,write_files,write_orders,write_products,write_themes,write_content"
DATABASE_URL = "file:/data/dev.sqlite"
DEFER_TOKEN = "[DEFER_TOKEN]"
TZ="Europe/London"

[experimental]
cmd = "start_with_migrations.sh"
entrypoint = "sh"

[http_service]
internal_port = 8081
force_https = true
auto_stop_machines = true
auto_start_machines = true
min_machines_running = 0
processes = ['app'] # KEEP????? // My remix app has been installed at /app

[mounts]
source = "sb_user_admin_app_v1_data"
destination = "/data"

[[vm]]
memory = '1gb'
cpu_kind = 'shared'
cpus = 1

Hi Charles,

Did you find out something new?

Thank you

Yes. I am using node-cron, which doesn’t require a cron installation.
It is incredibly easy to install and use. Here is a sample method I built that I call from my action() method:

let job = {};

function createCron(action, shop, process){

  const cron = require('node-cron');

  const cronTime = process.env.ENVIRONMENT === 'prod' ? '30 1 * * * ' : '30 * * * * * ';

  let error = false;

  const tasks = cron.getTasks();

  let deferReadOrdersTaskExists = false;

  for (let [key, value] of tasks.entries()) {
    if(value.options.name === 'deferReadOrders-task'){
      deferReadOrdersTaskExists = true;
      break;
    }
  }

  if(!deferReadOrdersTaskExists){
    job = cron.schedule(cronTime, async function execute() {
      const date = new Date().toLocaleString();
      const days = [14,7,3];
      const res = deferReadOrders(days, shop, process);
    },{
      name: 'deferReadOrders-task',
      scheduled: false
    });
  }

  try{
    action == 'stop' ? job.stop() : job.start();
  }
  catch(error){
    job.stop();
    error = true;
  }

  return json({
    cronTime,
    action,
    error
  });
}