#Cronjob / Background task update

12 messages · Page 1 of 1 (latest)

thick maple
#

I'm about to start a side project and I'd love to use TSS but for it to make sense I'd need to also be able to run cron jobs using TSS (otherwise the path to least resistance is react-router + fastify backend). What's the status of the server atm? Is it Vinxi still? Is this supported out of the box? Is it supported by the underlying infrastructure?

#

Well really I'd just need a way to run something on server start (e.g. setup node-cron)

radiant pebble
thick maple
#

@radiant pebble No, I just went with a separate node process/instance.

#

Sorry

radiant pebble
# thick maple <@525746637109198850> No, I just went with a separate node process/instance.

I think I found a solution. I implemented it this way, but I am not sure if it is secure or if it will work in production. While it works in development mode, I need to verify its behavior in a live environment.

In my vite.config.ts, I added the following:

    plugins: [
        devtools(),
        viteTsConfigPaths({ projects: ['./tsconfig.json'] }),
        tailwindcss(),
        tanstackStart(),
        nitro({
            plugins: ['./src/cronjobs/autoInvoices.ts'],
        }),
        viteReact(),
    ],
    optimizeDeps: {
        exclude: ['@tanstack/start-server-core', '@tanstack/react-start'],
    },
})```
final plover
uneven pendant
#

Running cronjob in the node web server app is a bad idea.
In prod your app has multiple instances, so you would need somehow to sync it, using redis, some db, or any external persisted state. Otherwise all instances are goona do the same tasks. If you do not care that every instance will run your cron job then you can just use something like setInterval in your server entry point(you need to take into account redeploys, server crashes). You are mixing your web server requests handling with completely different case: cron job

Just use separate node app for this case, or some service. Dont mix both in the same node process

#

.

If your cron job specifically is coupled by logic to your tanstack server app you can do this:
Make a server route which executes your task, and then invoke it externally

radiant pebble
final plover
radiant pebble
# final plover Would you mind sharing said Docker Compose setup? I’m interested to see how you ...

Well, I'm pretty new to all this Docker stuff and the TanStack Start ecosystem, but I really like both! My current way of doing things might not be the only or the absolute best way, but it works perfectly for me. Here is my setup:
package.json scripts:

    "dev": "vite dev --port 3000",
    "build": "vite build",
    "start": "node .output/server/index.mjs",
    "start:prod": "node scripts/migrate.mjs && node .output/server/index.mjs",
    "migrate:prod": "node scripts/migrate.mjs",
    "start:worker": "tsx src/cronjobs/worker.ts",
    "db:generate": "drizzle-kit generate",
    "db:migrate": "drizzle-kit migrate",
    "db:push": "drizzle-kit push",
    "db:pull": "drizzle-kit pull",
    "db:studio": "drizzle-kit studio"
}

Dockerfile:

WORKDIR /app
ARG APP_VERSION
ENV VITE_APP_VERSION=$APP_VERSION
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:22-bookworm-slim AS runner
WORKDIR /app
ENV NODE_ENV=production

ARG APP_VERSION
ENV APP_VERSION=$APP_VERSION

ENV PORT=3000
COPY package.json package-lock.json ./
RUN npm ci --omit=dev

COPY --from=builder /app/.output ./.output
COPY --from=builder /app/drizzle ./drizzle
COPY --from=builder /app/scripts ./scripts
COPY --from=builder /app/src ./src

EXPOSE 3000
CMD ["npm","run","start:prod"]

vite.config.ts:
(I had to add the nitroV2Plugin so that vite build still generates the .output folder with the standalone server!)

export default defineConfig({
    plugins: [
        devtools(),
        viteTsConfigPaths({ projects: ['./tsconfig.json'] }),
        tailwindcss(),
        tanstackStart(),
        nitroV2Plugin(),
        viteReact(),
    ],
    optimizeDeps: {
        exclude: ['@tanstack/react-start', '@tanstack/start-server-core'],
    },
})