Use Nix with Node@v20 & [email protected] in nixpacks.toml and railway.toml

Hi! 👋 I'm trying to configure a Node.js project with Nix on Railway. I have both railway.toml and nixpacks.toml files set up, but I'm not sure if I'm correctly defining the Nix config path. Here's my current setup: railway.toml:
[build]
builder = "nixpacks"
nixpacksConfigPath = "nixpacks.toml"
buildCommand = "yarn workspace @my-app build"
watchPatterns = [
"apps/web/src/**",
"apps/web/vite.config.mts",
"packages/**"
]

[deploy]
startCommand = "yarn workspace @my-app preview"
healthcheckPath = "/"
healthcheckTimeout = 180
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 3

[environments.staging.services.environment]
NODE_ENV = "production"
VITE_DATABASE_NAME = "database_staging"
VITE_DEBUG_ENABLED = "false"
VITE_HOST_NAME = "https://example.com"
VITE_SYNC_URL = "https://sync.example.com"
VITE_SERVER_HOST_NAME = "https://api.example.com"

[environments.staging.variables]
NODE_VERSION = "20"
YARN_VERSION = "4.3.1"
[build]
builder = "nixpacks"
nixpacksConfigPath = "nixpacks.toml"
buildCommand = "yarn workspace @my-app build"
watchPatterns = [
"apps/web/src/**",
"apps/web/vite.config.mts",
"packages/**"
]

[deploy]
startCommand = "yarn workspace @my-app preview"
healthcheckPath = "/"
healthcheckTimeout = 180
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 3

[environments.staging.services.environment]
NODE_ENV = "production"
VITE_DATABASE_NAME = "database_staging"
VITE_DEBUG_ENABLED = "false"
VITE_HOST_NAME = "https://example.com"
VITE_SYNC_URL = "https://sync.example.com"
VITE_SERVER_HOST_NAME = "https://api.example.com"

[environments.staging.variables]
NODE_VERSION = "20"
YARN_VERSION = "4.3.1"
nixpacks.toml:
[phases.setup]
nixPkgs = ['nodejs@20', 'yarn']

[variables]
NODE_VERSION = "20"
YARN_VERSION = "4.3.1"

[phases.install]
cmds = [
"corepack enable",
"corepack prepare [email protected] --activate",
"yarn install"
]

[phases.build]
cmds = ["yarn workspace @my-app build"]
[phases.setup]
nixPkgs = ['nodejs@20', 'yarn']

[variables]
NODE_VERSION = "20"
YARN_VERSION = "4.3.1"

[phases.install]
cmds = [
"corepack enable",
"corepack prepare [email protected] --activate",
"yarn install"
]

[phases.build]
cmds = ["yarn workspace @my-app build"]
Is this the correct way to specify the Nix configuration path in railway.toml? And is my nixpacks.toml set up correctly for a Node.js/Yarn project? Any guidance would be appreciated! 🙏 --- P.S. I already read https://docs.railway.app/guides/config-as-code
62 Replies
Percy
Percy5w ago
Project ID: cba0b597-8dda-49ec-abd1-d50886e024be
Guillem
GuillemOP5w ago
cba0b597-8dda-49ec-abd1-d50886e024be Railway logs:
#7 [ 3/11] COPY .nixpacks/nixpkgs-*.nix .nixpacks/nixpkgs-*.nix
#7 DONE 0.2s

#8 [ 4/11] RUN nix-env -if .nixpacks/nixpkgs-*.nix && nix-collect-garbage -d
#8 0.122 error: syntax error, unexpected '@'
#8 0.122 at /app/.nixpacks/nixpkgs-*.nix:19:15:
#8 0.122 18| '')
#8 0.122 19| nodejs@20 yarn
#8 0.122 | ^
#8 0.122 20| ];

#8 ERROR: process "/bin/bash -ol pipefail -c nix-env -if .nixpacks/nixpkgs-*.nix && nix-collect-garbage -d" did not complete successfully: exit code: 1
-----
> [ 4/11] RUN nix-env -if .nixpacks/nixpkgs-*.nix && nix-collect-garbage -d:
0.122 error: syntax error, unexpected '@'
0.122 at /app/.nixpacks/nixpkgs-*.nix:19:15:
0.122 18| '')
0.122 19| nodejs@20 yarn
0.122 | ^
0.122 20| ];
-----

Dockerfile:8
-------------------
6 |
7 | COPY .nixpacks/nixpkgs-*.nix .nixpacks/nixpkgs-*.nix
8 | >>> RUN nix-env -if .nixpacks/nixpkgs-*.nix && nix-collect-garbage -d
9 |
10 |
-------------------
ERROR: failed to solve: process "/bin/bash -ol pipefail -c nix-env -if .nixpacks/nixpkgs-*.nix && nix-collect-garbage -d" did not complete successfully: exit code: 1

Error: Docker build failed
#7 [ 3/11] COPY .nixpacks/nixpkgs-*.nix .nixpacks/nixpkgs-*.nix
#7 DONE 0.2s

#8 [ 4/11] RUN nix-env -if .nixpacks/nixpkgs-*.nix && nix-collect-garbage -d
#8 0.122 error: syntax error, unexpected '@'
#8 0.122 at /app/.nixpacks/nixpkgs-*.nix:19:15:
#8 0.122 18| '')
#8 0.122 19| nodejs@20 yarn
#8 0.122 | ^
#8 0.122 20| ];

#8 ERROR: process "/bin/bash -ol pipefail -c nix-env -if .nixpacks/nixpkgs-*.nix && nix-collect-garbage -d" did not complete successfully: exit code: 1
-----
> [ 4/11] RUN nix-env -if .nixpacks/nixpkgs-*.nix && nix-collect-garbage -d:
0.122 error: syntax error, unexpected '@'
0.122 at /app/.nixpacks/nixpkgs-*.nix:19:15:
0.122 18| '')
0.122 19| nodejs@20 yarn
0.122 | ^
0.122 20| ];
-----

Dockerfile:8
-------------------
6 |
7 | COPY .nixpacks/nixpkgs-*.nix .nixpacks/nixpkgs-*.nix
8 | >>> RUN nix-env -if .nixpacks/nixpkgs-*.nix && nix-collect-garbage -d
9 |
10 |
-------------------
ERROR: failed to solve: process "/bin/bash -ol pipefail -c nix-env -if .nixpacks/nixpkgs-*.nix && nix-collect-garbage -d" did not complete successfully: exit code: 1

Error: Docker build failed
Brody
Brody4w ago
Hello, yes nixpacksConfigPath is correct, but its also redundant since that is the default value. You also cant set environment variables in a railway.toml file, you would want to set them on your service in the UI. nodejs@20 is not a valid package. nixPkgs = ['nodejs@20', 'yarn'] is not needed, node 20 will be used automatically if your engines.node field in the package.json specifies it, and yarn will be used if you have a yarn lock file.
[phases.install]
cmds = [
"corepack enable",
"corepack prepare [email protected] --activate",
"yarn install"
]
[phases.install]
cmds = [
"corepack enable",
"corepack prepare [email protected] --activate",
"yarn install"
]
Corepack will install the set version of yarn for you if you have it set in the packageManager field in the package.json
[variables]
NODE_VERSION = "20"
YARN_VERSION = "4.3.1"
[variables]
NODE_VERSION = "20"
YARN_VERSION = "4.3.1"
Doesn't do anything
[phases.build]
cmds = ["yarn workspace @my-app build"]
[phases.build]
cmds = ["yarn workspace @my-app build"]
You already set this in your railway.toml - with all that said - - set the engines.node field in your package.json to 20 - set the packageManager field in your package.json to [email protected] - remove the nixpacks.toml file, it is redundant in this context. - set the needed variables in the service variables tab. - use this railway.toml file -
[build]
builder = "nixpacks"
buildCommand = "yarn workspace @my-app build"
watchPatterns = [
"apps/web/src/**",
"apps/web/vite.config.mts",
"packages/**"
]

[deploy]
startCommand = "yarn workspace @my-app preview"
healthcheckPath = "/"
healthcheckTimeout = 180
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 3
[build]
builder = "nixpacks"
buildCommand = "yarn workspace @my-app build"
watchPatterns = [
"apps/web/src/**",
"apps/web/vite.config.mts",
"packages/**"
]

[deploy]
startCommand = "yarn workspace @my-app preview"
healthcheckPath = "/"
healthcheckTimeout = 180
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 3
Guillem
GuillemOP4w ago
How can I split railway.toml for different apps of my monorepo (like web and server)? The docs recommend to use railway.toml in root directory, I was thinking to put in apps/web/ and apps/server Thanks Bordy for the detailed explanation!! With your suggestion, I got this:
#9 [5/7] COPY . /app/.

#9 DONE 1.6s


#10 [6/7] RUN yarn workspace @xiroi/apps-web build
#10 0.129 /bin/bash: line 1: yarn: command not found

#10 ERROR: process "/bin/bash -ol pipefail -c yarn workspace @xiroi/apps-web build" did not complete successfully: exit code: 127
-----
> [6/7] RUN yarn workspace @xiroi/apps-web build:
0.129 /bin/bash: line 1: yarn: command not found
-----

Dockerfile:16
-------------------
14 | # build phase
15 | COPY . /app/.
16 | >>> RUN yarn workspace @xiroi/apps-web build
17 |
18 | # setup phase
-------------------

ERROR: failed to solve: process "/bin/bash -ol pipefail -c yarn workspace @xiroi/apps-web build" did not complete successfully: exit code: 127

Error: Docker build failed
#9 [5/7] COPY . /app/.

#9 DONE 1.6s


#10 [6/7] RUN yarn workspace @xiroi/apps-web build
#10 0.129 /bin/bash: line 1: yarn: command not found

#10 ERROR: process "/bin/bash -ol pipefail -c yarn workspace @xiroi/apps-web build" did not complete successfully: exit code: 127
-----
> [6/7] RUN yarn workspace @xiroi/apps-web build:
0.129 /bin/bash: line 1: yarn: command not found
-----

Dockerfile:16
-------------------
14 | # build phase
15 | COPY . /app/.
16 | >>> RUN yarn workspace @xiroi/apps-web build
17 |
18 | # setup phase
-------------------

ERROR: failed to solve: process "/bin/bash -ol pipefail -c yarn workspace @xiroi/apps-web build" did not complete successfully: exit code: 127

Error: Docker build failed
My settings:
[build]
builder = "nixpacks"
buildCommand = "yarn workspace @xiroi/apps-web build"
# watchPatterns = [
# "xiroi-apps/web/**",
# "xiroi-packages/**"
# ]

[deploy]
startCommand = "yarn workspace @xiroi/apps-web preview"
healthcheckPath = "/"
healthcheckTimeout = 180
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 3
[build]
builder = "nixpacks"
buildCommand = "yarn workspace @xiroi/apps-web build"
# watchPatterns = [
# "xiroi-apps/web/**",
# "xiroi-packages/**"
# ]

[deploy]
startCommand = "yarn workspace @xiroi/apps-web preview"
healthcheckPath = "/"
healthcheckTimeout = 180
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 3
Brody
Brody4w ago
isolated or shared monorepo? do you not have a yarn lock file?
Guillem
GuillemOP4w ago
I have it. It's already in git Shared. My root package.json looks like:
"workspaces": [
"xiroi-apps/*",
"xiroi-packages/bc/commerce/*",
"xiroi-packages/bc/communication/*",
"xiroi-packages/bc/communication/infras,
...
"xiroi-packages/shared/*",
"xiroi-packages/shared/infrastructure/*",
"xiroi-packages/shared/ui/*",
"xiroi-packages/shared/usecases/*",
"xiroi-packages/shared/utils/*",
"xiroi-packages/ui-pages/*"
]
"workspaces": [
"xiroi-apps/*",
"xiroi-packages/bc/commerce/*",
"xiroi-packages/bc/communication/*",
"xiroi-packages/bc/communication/infras,
...
"xiroi-packages/shared/*",
"xiroi-packages/shared/infrastructure/*",
"xiroi-packages/shared/ui/*",
"xiroi-packages/shared/usecases/*",
"xiroi-packages/shared/utils/*",
"xiroi-packages/ui-pages/*"
]
Brody
Brody4w ago
for shared -- you wouldn't want to be setting a root directly in the service settings put each railway.toml in the subdirectory though, and then set the location with the Railway Config File setting in the service settings
Guillem
GuillemOP4w ago
To my xiroi-apps/web/package.json, I added:
"engines": {
"node": ">=20",
"npm": "please-use-yarn",
"yarn": ">=4.1.0"
},
"engines": {
"node": ">=20",
"npm": "please-use-yarn",
"yarn": ">=4.1.0"
},
Then xiroi-apps/web/railway.toml is:
[build]
builder = "nixpacks"
buildCommand = "yarn build"

[deploy]
startCommand = "yarn preview"
healthcheckPath = "/"
healthcheckTimeout = 180
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 3
[build]
builder = "nixpacks"
buildCommand = "yarn build"

[deploy]
startCommand = "yarn preview"
healthcheckPath = "/"
healthcheckTimeout = 180
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 3
Logs error:
6 DONE 1.6s

#7 [3/5] COPY . /app/.

#7 DONE 1.2s


#8 [4/5] RUN yarn build

#8 0.209 /bin/bash: line 1: yarn: command not found

#8 ERROR: process "/bin/bash -ol pipefail -c yarn build" did not complete successfully: exit code: 127
-----
> [4/5] RUN yarn build:
0.209 /bin/bash: line 1: yarn: command not found
-----

Dockerfile:15
-------------------
13 | # build phase
14 | COPY . /app/.
15 | >>> RUN yarn build
16 |
17 |
-------------------
ERROR: failed to solve: process "/bin/bash -ol pipefail -c yarn build" did not complete successfully: exit code: 127

Error: Docker build failed
6 DONE 1.6s

#7 [3/5] COPY . /app/.

#7 DONE 1.2s


#8 [4/5] RUN yarn build

#8 0.209 /bin/bash: line 1: yarn: command not found

#8 ERROR: process "/bin/bash -ol pipefail -c yarn build" did not complete successfully: exit code: 127
-----
> [4/5] RUN yarn build:
0.209 /bin/bash: line 1: yarn: command not found
-----

Dockerfile:15
-------------------
13 | # build phase
14 | COPY . /app/.
15 | >>> RUN yarn build
16 |
17 |
-------------------
ERROR: failed to solve: process "/bin/bash -ol pipefail -c yarn build" did not complete successfully: exit code: 127

Error: Docker build failed
P.S. My intention is to use a paid plan of Railway when I launch my web & app.
Brody
Brody4w ago
thats great, i hope we can get you up and running, but for that i would greatly appreciate if you made sure to read the information im giving you 🙂 ^
Guillem
GuillemOP4w ago
No description
Brody
Brody4w ago
No description
Guillem
GuillemOP4w ago
Ohhh, it's below Source Repo. I missed the underlined text 😁
No description
Guillem
GuillemOP4w ago
No success. This is my "web" service settings: - Root directory: /xiroi-apps/web - Railway config file: xiroi-apps/web/railway.toml Logs:
#8 [4/5] RUN yarn build
#8 0.081 /bin/bash: line 1: yarn: command not found

#8 ERROR: process "/bin/bash -ol pipefail -c yarn build" did not complete successfully: exit code: 127
-----
> [4/5] RUN yarn build:

0.081 /bin/bash: line 1: yarn: command not found
-----

Dockerfile:15
-------------------
13 | # build phase
14 | COPY . /app/.
15 | >>> RUN yarn build
16 |
17 |
-------------------
ERROR: failed to solve: process "/bin/bash -ol pipefail -c yarn build" did not complete successfully: exit code: 127

Error: Docker build failed
#8 [4/5] RUN yarn build
#8 0.081 /bin/bash: line 1: yarn: command not found

#8 ERROR: process "/bin/bash -ol pipefail -c yarn build" did not complete successfully: exit code: 127
-----
> [4/5] RUN yarn build:

0.081 /bin/bash: line 1: yarn: command not found
-----

Dockerfile:15
-------------------
13 | # build phase
14 | COPY . /app/.
15 | >>> RUN yarn build
16 |
17 |
-------------------
ERROR: failed to solve: process "/bin/bash -ol pipefail -c yarn build" did not complete successfully: exit code: 127

Error: Docker build failed
Brody
Brody4w ago
you wouldn't want to be setting a root directly in the service settings
Guillem
GuillemOP4w ago
hahah I'm little confused. My initial config hadn't the root directory in the Web service. My current config is Railway Config File xiroi-apps/web/railway.toml. I still cannot build it. *I'm skipping Server service for now.
No description
Brody
Brody4w ago
would you mind if i pull your code, it will help me to understand what you have going on
Guillem
GuillemOP4w ago
Yeah, no problem. Let me know what you need for that
Brody
Brody4w ago
your permission is sufficient
Brody
Brody4w ago
in all this messing about somehow the providers option got emptied, add node back to it
No description
Guillem
GuillemOP4w ago
Initially I deleted it because my (incorrect) Nix config
Brody
Brody4w ago
"npm": "please-use-yarn" lol
Guillem
GuillemOP4w ago
Great Brody! Everything is building, except for one monorepo package. I'll dig into that one. The last 1-2 years is quite common to use monorepos. I'd add cases to https://docs.railway.app/tutorials/deploying-a-monorepo for people
Brody
Brody4w ago
easier said than done unfortunately, your issues are incredibly specific to what you have already tried
Guillem
GuillemOP4w ago
😅 I didn't know I was unique 😁
Brody
Brody4w ago
your current build command is yarn build and your start command is yarn start shouldnt you be using workspace specific commands?
Guillem
GuillemOP4w ago
Because railway.toml is already in the frontend app (xiroi-apps/web/railway.toml with package.json's name @xiroi/apps-web), I guess it runs from the same directory xiroi-apps/web, instead of yarn workspace @xiroi/apps-web build that I run from the root directory.
Brody
Brody4w ago
your root directory is / thus the scripts from the root directory are used. you want to be in the root directory, but you need to be using workspace specific build and start commands
Guillem
GuillemOP4w ago
That was it. The build was successful, Brody! For the deployment, what Railway config do you recommend?
[deploy]
startCommand = "yarn workspace @xiroi/apps-web preview"
healthcheckPath = "/"
healthcheckTimeout = 180
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 3
[deploy]
startCommand = "yarn workspace @xiroi/apps-web preview"
healthcheckPath = "/"
healthcheckTimeout = 180
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 3
Logs
=== Successfully Built! ===

Run:
docker run -it us-west1.registry.rlwy.net/96a41a31-4b99-4571-9d8f-a0ea733a7fb2:42ff8b32-5ea2-4e0b-a559-8abcce8c5be3

Build time: 215.07 seconds

====================
Starting Healthcheck
====================
Path: /
Retry window: 3m0s

Attempt #1 failed with service unavailable. Continuing to retry for 2m49s
Attempt #2 failed with service unavailable. Continuing to retry for 2m38s
...

1/1 replicas never became healthy!
Healthcheck failed!
=== Successfully Built! ===

Run:
docker run -it us-west1.registry.rlwy.net/96a41a31-4b99-4571-9d8f-a0ea733a7fb2:42ff8b32-5ea2-4e0b-a559-8abcce8c5be3

Build time: 215.07 seconds

====================
Starting Healthcheck
====================
Path: /
Retry window: 3m0s

Attempt #1 failed with service unavailable. Continuing to retry for 2m49s
Attempt #2 failed with service unavailable. Continuing to retry for 2m38s
...

1/1 replicas never became healthy!
Healthcheck failed!
Brody
Brody4w ago
lemme look well the deploy failed -
Error bundling tamagui config: The service was stopped: write EPIPE (run with DEBUG=tamagui to see stack)
No bundled config generated, maybe an error in bundling. Set DEBUG=tamagui and re-run to get logs.
Error bundling tamagui config: The service was stopped: write EPIPE (run with DEBUG=tamagui to see stack)
No bundled config generated, maybe an error in bundling. Set DEBUG=tamagui and re-run to get logs.
Brody
Brody4w ago
Railway Docs
Fixing Common Errors | Railway Docs
Documentation for Railway
Guillem
GuillemOP4w ago
Great! I'm searching where UI library Tamagui breaks
Brody
Brody4w ago
just noticed you are running a dev server via vite
Guillem
GuillemOP4w ago
In /web?
Brody
Brody4w ago
yeah
Guillem
GuillemOP4w ago
The first time hosting with Vite. server field is for local development, you run it with vite. preview fields with vite preview
Brody
Brody4w ago
question, are you fixed on the .toml file, or can we move to a .json file? you would get a much better dx with a railway.json file since it has the schema we will need to use caddy, ill get you setup, just working out a plan of attack
Guillem
GuillemOP4w ago
Ohhh cool, .toml is done.
Brody
Brody4w ago
you got it, give me a few mins and ill come up with a plan to get you running with a production web server
Guillem
GuillemOP4w ago
About the Tamagui issue. I can build and run the web locally with vite preview on http://localhost:4173.
Brody
Brody4w ago
i dont think we need to worry about that, that error does not appear in the build logs and its not going to appear in the deploy logs after we only have caddy running
Guillem
GuillemOP4w ago
The first time I heard Caddy. The marketing website https://caddyserver.com/ is going high 😎
No description
Brody
Brody4w ago
we wont be using most of its features, railway handles https for us, we just need a user friendly http server
Guillem
GuillemOP4w ago
A note: my web can work without my server, only needs Supabase (auth) and Powersync (db sync) connections. The rest is a local-first approach.
Brody
Brody4w ago
sounds good does your frontend depend on another workspace other than shared-utils-logging ?
Guillem
GuillemOP4w ago
Ohh, good finding. "build": "yarn workspace @xiroi/shared-utils-logging build && tsc && vite build" is a past config. I gonna replace it for tsc && vite build
Brody
Brody4w ago
so is the frontend just depending on types from other packages?
Guillem
GuillemOP4w ago
Yes Pushed the commit about deletion of this
Brody
Brody4w ago
this nixpacks stuff really annoying, how do you feel about a dockerfile?
Guillem
GuillemOP4w ago
Very comfortable. nixpacks' packages were really difficult when I experimented with them No docker compose, only dockerfile?
Brody
Brody4w ago
only Dockerfile, ill write one for you sorry this is taking so long, got it mostly running but yarn is still running in the background for some reason
Brody
Brody4w ago
put these files in the web folder
Brody
Brody4w ago
you'll also need to change the config file path to use the .json extension now
Brody
Brody4w ago
this going from yarn running caddy, to just caddy when i switched to the dockerfile, ~250mb before
No description
Guillem
GuillemOP4w ago
250 mb before? With this new config, it will be smaller and faster to build? Good job! Now build time reduced from +3min to 2min
Brody
Brody4w ago
yeah faster builds since less nixpacks stuff, and faster deploys, since now the final image basically only contains the caddy binary and your dist folder
Guillem
GuillemOP4w ago
What do you think is going wrong https://web-staging-4672.up.railway.app/ ?
Brody
Brody4w ago
you would likely have a better idea than me -
vendor_react_native_web-Rn6azkte.js:1 Uncaught (in promise) TypeError: ss is not a function
at vendor_react_native_web-Rn6azkte.js:1:9786
vendor_react_native_web-Rn6azkte.js:1 Uncaught (in promise) TypeError: ss is not a function
at vendor_react_native_web-Rn6azkte.js:1:9786
Guillem
GuillemOP4w ago
This happened in the localhost and just needed to refresh in a new tab... But apparently not working in production I mark this ticket as SOLVED. Amazing help, Brody! Say to the team that you're providing next level support 🪄
Brody
Brody4w ago
thank you, hopefully this support is worth an upgrade to Pro? 🙂
Guillem
GuillemOP4w ago
I'll see the demand the first months of the launch next month, and adjust the paid plans accordingly. I'm confidence I can grow with Railway, after exploring many options. And because it's a consumer web & app, hopefully the demand will high
Brody
Brody4w ago
i wish you the best of luck then!
Want results from more Discord servers?
Add your server