#How are we supposed to run the application in non-dev mode?

79 messages · Page 1 of 1 (latest)

clever crane
#

I'm very confused by this and I've read the getting started docs multiple times. How do I run the tanstack start app in NON-dev mode? In the docs there's a vite build script, but what do we do after we run vite build...?

I browsed the dist directory that got created after vite build, and I found a dist/server/server.js, but running node dist/server/server.js doesn't start the server at all.

clever crane
#

I found this script hidden in a small section in the hosting docs: "start": "node .output/server/index.mjs", however this .output folder does not exist at all for me. vite build creates a dist folder, not a .output folder.

sonic sedge
clever crane
#

I'm using node.js with Docker

#

It says I can use the node .output/server/index.mjs command, but that doesn't exist.

brave crow
#

it doesn't have a way to run a prod build

#

yes you may install nitro

#

it will build an optimal server runner for you

#

ts start only builds a fetch handler

#

which is good, because it means the server can be very easily delegated

#

to netlify, vercel, or nitro for example

#

you can create a server entry file yourself if you want

#

using express and/or srvx

#

or Bun.serve, or Deno.serve

#

do whatever you want. but if you want something no brain that just works, then go nitro

clever crane
#

can it be done with... fastify? 🙂

smoky junco
#

sure

clever crane
#

Hmm, I just tried nitro but it always listens on port 3000 and I can't find a way to change that. It seems to ignore the port I set in my vite config's server.port.

smoky junco
#

in dev or prod?

#

in prod, set PORT env var

clever crane
#

thanks, didn't think it would be env var, I was looking in the config page of the docs

#

hmm, I took a peek at the source code and it DOES look like the nitro vite plugin is looking at vite config's server.port. It says:

          server: {
            port:
              Number.parseInt(process.env.PORT || "") ||
              userConfig.server?.port ||
              ctx.nitro.options.devServer?.port ||
              3000,
          },
#

I'm throwing in some console.log statements in my build to see if I can figure out why that number is still getting overridden by 3000

#

yeah it's not carrying over into the .output/server/index.mjs file, which reads env vars all over again from scratch:

const port = destr(process.env.NITRO_PORT || process.env.PORT) || 3e3;
#

time to clone this repo and tinker!

#

I don't like having to declare my port twice -- once in vite config and again in an env var

smoky junco
#

why is that an issue?

#

dev server could very well have a different port than prod

#

you could add a define to set process.env.PORT to 3000

clever crane
#

I have this in my vite.config.ts:

const { SERVER_PORT } = process.env;
const port = parseInt(SERVER_PORT || 15502);

export default defineConfig({
  server: { port },
  ...
});

I'm in a monorepo with a shared Dockerfile that is used across multiple apps and is setting an env var named SERVER_PORT for production servers.

Also, I sometimes want to test the "built" version of my app locally, and my apps work behind a separately running reverse proxy server that operates on port. If the dev mode port and the "built" mode port that is running locally are different, then my local dev workflow no longer works to test the "built" version.

#

We have fastify apps, express apps, and other apps in the monorepo. We built a single Dockerfile to support all of them. When we built it we assumed that every type of app would be able to configure its port in this way.

smoky junco
#

ok then does the define approach work?

clever crane
#

I'm trying it right now

#

This doesn't work:

const { SERVER_PORT } = process.env;
const port = parseInt(SERVER_PORT || 15502);

export default defineConfig({
  define: {
    PORT: port,
  },
  server: { port },
  ...
});

It still listens on 3000

smoky junco
#

try this

define: {
    `process.env.PORT`: JSON.stringify(port),
  },
clever crane
#

ah, that did work

#

This also worked:

    define: {
        'process.env.NITRO_PORT': port,
    },
smoky junco
#

you could also just run start inside fastify, if this is what you have right now

#

have a look at this example that shows how to embed into an express server

clever crane
#

Hmmm, I don't have a strong reason to do that since this is a greenfield brand new app.

#

I do however need to define some healthz-endpoints so kubernetes can ping them. I defined them as a vite plugin thinking that the vite server would run in prod, but I guess that's wrong and I need to redefine them in nitro?

smoky junco
#

vite server does not run in prod

#

you can define them as server routes in Start

clever crane
#

vite server does not run in prod
Ah, so does that mean I can move vite from dependencies to devDependencies?

smoky junco
#

or as a separate API service in nitro

clever crane
#

you can define them as server routes in Start
I didn't do that because I have a custom base route

smoky junco
#

or, if you embed in a custom server, then there

clever crane
#

my vite config has:

export default defineConfig({
  base: '/temp/h2-initiative',
  // ...
});

Therefore I thought all the routes I define in Start would be prefixed with /temp/h2-initiative

smoky junco
#

they will, yes

clever crane
#

and I wanted to listen to /livez, /readyz and not /temp/h2-initiative/livez

smoky junco
#

well then dont set the base in vite

clever crane
#

these would be the only endpoints that need to be outside the base

smoky junco
#

and move the other routes in a folder that expresses the base?

clever crane
#

Yeah I thought about that option as well, but I wanted to keep these routes separate from the application routes since they exist purely for kubernetes healthchecks and not actual business stuff. There are some pretty good advantages of setting the base.

#

or as a separate API service in nitro
Is this a robust feature in Nitro or would you recommend that I avoid it?

smoky junco
#

nitro3 overall is still alpha, so i cant say really

clever crane
#

Thanks. I’ll try the fastify option

#

Might also tinker with nitro

clever crane
brave crow
#

it's just an example to show capabilities

#

you can strip the dev part

#

and use the entrypoint only for prod

clever crane
#

thank you all for your help!

smoky junco
clever crane
smoky junco
#

nice! want to create an example in the router github repo?

clever crane
#

I was thinking about turning this into a fastify plugin and publishing on npm first

#

I already got started on that, hopefully get some time this weekend to continue

full void
#

would be awesome to see it in action, I am using it with fastify as well, awesome combo!

clever crane
clever crane
clever crane
strange mauve
# clever crane starting to make some small PRs to update docs based on what I've learned here: ...

i have a problem here it give this error " {"level":50,"time":1761323412845,"pid":11608,"hostname":"BILU","err":{"type":"Error","message":"Only URLs with a scheme in: file, data, and node are supported by the default ESM loader. On Windows, absolute paths must be valid file:// URLs. Received protocol 'c:'","stack":"Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only URLs with a scheme in: file, data, and node are supported by the default ESM loader. On Windows, absolute paths must be valid file:// URLs. Received protocol 'c:'\n at throwIfUnsupportedURLScheme (node:internal/modules/esm/load:209:11)\n at defaultLoad (node:internal/modules/esm/load:107:3)\n at ModuleLoader.load (node:internal/modules/esm/loader:800:12)\n at ModuleLoader.loadAndTranslate (node:internal/modules/esm/loader:580:43)\n at #createModuleJob (node:internal/modules/esm/loa
der:604:36)\n at #getJobFromResolveResult (node:internal/modules/esm/loader:338:34)\n at ModuleLoader.getModuleJobForImport (node:internal/modules/esm/loader:306:41)\n at process.processTicksAndRe
jections (node:internal/process/task_queues:105:5)\n at async onImport.tracePromise.proto (node:internal/modules/esm/loader:643:25)","code":"ERR_UNSUPPORTED_ESM_URL_SCHEME"},"msg":"Only URLs with a scheme in: file, data, and node are supported by the default ESM loader. On Windows, absolute paths must be valid file:// URLs. Received protocol 'c:'"}
" and i'm using solidJs with tanstack start is it compatible?