yarn workspace server start: command not found

Getting this error while trying to push to fly.io

Seems, this is a monorepo - with React on frontend and node on backend. This command is in my Procfile:

web: yarn workspace server start

Same setup works with Heroku - not on fly.io @rubys

You are going to either need the right buildpack, or the right Dockerfile. If you need help finding the right buildpack, I’m not the person to ask.

If you need help building a Dockerfile, I can help, but I’ll need a bit more information. For starters, if you can copy and paste your top level package.json file, tell me the name of your Procfile (it could just be Procfile, but in reality it could be anything), and (if there is more than that one line in it) the contents of the Procfile.

Basically the term “monorepo” just means more than one application in one repository. To get your application up and running, the application is structured according to a number of conventions that Heroku expects. I’ve never used Heroku, but if I can either get a pointer to the documentation on those expectations or see enough examples, I can adjust fly’s launch tool and dockerfile generator to detect and support these conventions.

Sure, @rubys
top level package.json

{
  "name": "home-project-monorepo",
  "private": true,
  "workspaces": [
    "packages/*"
  ],
  "engines": {
    "yarn": ">= 1.19.1 <2",
    "node": ">= 17.3.0"
  },
  "scripts": {
    "build": "script/build",
    "knex": "knex --cwd ./packages/server",
    "prettier": "prettier --ignore-path .gitignore \"**/*.+(js|jsx|ts|tsx|json|css)\"",
    "prettier:check": "yarn prettier --check",
    "prettier:fix": "yarn prettier --write",
    "lint": "yarn workspaces run lint",
    "lint:fix": "yarn lint --fix",
    "stylelint:check": "yarn stylelint \"**/*.css\"",
    "stylelint:fix": "yarn stylelint \"**/*.css\" --fix",
    "validate": "yarn prettier:check && yarn lint && yarn stylelint:check",
    "fix": "yarn prettier:fix && yarn lint:fix && yarn stylelint:fix",
    "prepare": "husky install"
  },
  "devDependencies": {
    "eslint-config-airbnb": "^19.0.4",
    "eslint-config-prettier": "^8.5.0",
    "eslint-plugin-prettier": "^4.0.0",
    "husky": "^7.0.4",
    "lint-staged": "^13.0.3",
    "prettier": "^2.6.2",
    "stylelint": "^14.8.2",
    "stylelint-config-prettier": "^9.0.3",
    "stylelint-config-standard": "^25.0.0",
    "stylelint-prettier": "^2.0.0"
  },
  "lint-staged": {
    "**/*.+(js|jsx|ts|tsx|json|css)": [
      "yarn prettier:check"
    ],
    "**/*.+(js|jsx|ts|tsx)": [
      "yarn lint"
    ],
    "**/*.+(css)": [
      "yarn stylelint:check"
    ]
  }
}

Procfile - is just named Procfile.
Content of Procfile:

web: yarn workspace server start

If you still are set up to use a buildpack, remove these lines from your fly.toml:

[build]
  builder = "heroku/buildpacks:20"

If you don’t have a dockerfile, you can use dockerfile-node to build one.

Finally, a Procfile with just one entry seems overkill, let’s try adding a start script to your package.json:

  "scripts": {
    "build": "script/build",
    "start": "yarn workspace server start",
    "knex": "knex --cwd ./packages/server",

Once you are up and running, I’d appreciate it if you could post your final Dockerfile so that I can review it to see what improvementss I need to make to dockerfile-node,

Ok trying now.

If I remove

[build]
  builder = "heroku/buildpacks:20"

I get this error:

==> Building image
Remote builder fly-builder-quiet-bush-1444 ready
Error: failed to fetch an image or build from source: app does not have a Dockerfile or buildpacks configured. See https://fly.io/docs/reference/configuration/#the-build-section

I have a suggestion… :slight_smile:

Since you are using yarn, try

yarn add @flydotio/dockerfile --dev
npx dockerfile

@rubys
Now trying with Dockerfile.
I see this error

Running asdgsdg release_command: yarn knex migrate:latest
  Waiting for 148ed433f34078 to have state: stopped
Error: release command failed - aborting deployment. error running release_command machine: timeout reached waiting for machine to stopped failed to wait for VM 148ed433f34078 in stopped state: Get "https://api.machines.dev/v1/apps/asdgsdg/machines/148ed433f34078/wait?instance_id=01H08BV72ZS1PX2EAYHS6F4N4G&state=stopped&timeout=60": net/http: request canceled

Here is my Dockerfile:

# syntax = docker/dockerfile:1

# Adjust NODE_VERSION as desired
ARG NODE_VERSION=17.3.0
FROM node:${NODE_VERSION}-slim as base

LABEL fly_launch_runtime="NodeJS"

# NodeJS app lives here
WORKDIR /app

# Set production environment
ENV NODE_ENV=production
ARG YARN_VERSION=1.22.19
RUN npm install -g yarn@$YARN_VERSION


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

# Install packages needed to build node modules
RUN apt-get update -qq && \
    apt-get install -y python-is-python3 pkg-config build-essential

# Install node modules
COPY --link package.json yarn.lock .
RUN yarn install --legacy-peer-deps --production=false

# Copy application code
COPY --link . .

# Remove development dependencies
RUN yarn install --production=true


# Final stage for app image
FROM base

# Copy built application
COPY --from=build /app /app

# Start the server by default, this can be overwritten at runtime
CMD [ "yarn", "run", "start" ]

Some additional logs:

2023-05-12T16:14:24.358 app[148ed433f34078] ams [info] 2023/05/12 16:14:24 listening on [fdaa:2:2220:a7b:141:1e0f:a960:2]:22 (DNS: [fdaa::3]:53)

2023-05-12T16:14:28.287 app[148ed433f34078] ams [info] ℹ️ uncaughtException: connect ECONNREFUSED 127.0.0.1:3306

2023-05-12T16:14:28.287 app[148ed433f34078] ams [info] Error: connect ECONNREFUSED 127.0.0.1:3306

That is happening because of this in your fly.toml:

Now a number of mysteries:

  • release is run before start, so in order to have seen start command not found you either had a successful release previously or the release is a recent addition to the fly.toml.
  • It looks like knex is being launched, but is producing no output nor is it exiting.

Tell me more about your database. Are you intending to use postgres? Does fly secrets list include DATABASE_URL? Does your knex configuration match Migrations | Knex.js ?

Yes, I’m using postgres database and setting it up while fly deploy.
If I run fly secrets list:

NAME        	DIGEST          	CREATED AT 
DATABASE_URL	41f4367d86174525	10m6s ago 

Another thing is I have a fly.yml workflow for continuous deployment on github.

UPDATE: after running yarn knex migrate:latest locally, there was an issue with migration - I deleted migration file and it caused problem. Now I removed that migration file from local database and now yarn knex migrate:latest runs without issues locally.
It brings the same error…

That error message implies that you have not set up knex to use either DATABASE_URL or postgres. I’ve yet to use knex, but based on the documentation you should have a knexfile.js file that looks something like this:

module.exports = {
  client: 'pg',
  connection: process.env.DATABASE_URL
};

Does this match what you have?

I have a knexfile.js in packages/server

const path = require('path');
require('dotenv').config();

module.exports = {
  development: {
    client: 'mysql2',
    connection: {
      host: process.env.MYSQL_HOST,
      port: process.env.MYSQL_PORT,
      user: process.env.MYSQL_USER,
      password: process.env.MYSQL_PASSWORD,
      database: process.env.MYSQL_DATABASE,
    },
    pool: { min: 0, max: 7 },
    seeds: {
      directory: path.join(__dirname, '/seeds/development'),
    },
  },
  production: {
    client: 'mysql2',
    connection: {
      host: process.env.MYSQL_HOST,
      port: process.env.MYSQL_PORT,
      user: process.env.MYSQL_USER,
      password: process.env.MYSQL_PASSWORD,
      database: process.env.MYSQL_DATABASE,
    },
    pool: { min: 0, max: 7 },
    seeds: {
      directory: path.join(__dirname, '/seeds/production'),
    },
  },
};

Ah ok,
seems I need to set up these secrets in fly.io

# MYSQL_HOST
  # MYSQL_PORT
  # MYSQL_DATABASE
  # MYSQL_USER
  # MYSQL_PASSWORD

Update: I set it up. I think I will go with MySQL db for now.
Following this guide

That doesn’t look like:

{
  client: 'pg',
  connection: process.env.DATABASE_URL
},

Ok I tried this: fly secrets set MYSQL_HOST=sfddsfh-db.internal MYSQL_PORT=5433 MYSQL_DATABASE=sfddsfh-db MYSQL_USER=postgres MYSQL_PASSWORD=redacted

And this is knexfile.js

production: {
    client: 'postgresql',
    connection: {
      host: process.env.MYSQL_HOST,
      port: process.env.MYSQL_PORT,
      user: process.env.MYSQL_USER,
      password: process.env.MYSQL_PASSWORD,
      database: process.env.MYSQL_DATABASE,
    },

Still same error…

If the error you are still seeing matches this, then your application must be looking for the configuration in another place. 127.0.0.1 is locahost, and 3306 is the port that mysql uses.

I see different error now.

2023-05-12T20:11:58.705 app[e784e90dc260e8] ams [info] Preparing to run: `/cnb/process/web yarn knex migrate:latest` as heroku

2023-05-12T20:11:58.716 app[e784e90dc260e8] ams [info] 2023/05/12 20:11:58 listening on [fdaa:2:2220:a7b:13b:8133:6502:2]:22 (DNS: [fdaa::3]:53)

2023-05-12T20:12:12.081 app[e784e90dc260e8] ams [info] ℹ️ uncaughtException: connect ETIMEDOUT

2023-05-12T20:12:12.081 app[e784e90dc260e8] ams [info] Error: connect ETIMEDOUT

2023-05-12T20:12:12.081 app[e784e90dc260e8] ams [info] at Connection._handleTimeoutError (/workspace/node_modules/mysql2/lib/connection.js:189:17)
Running sfddsfh release_command: yarn knex migrate:latest
  Waiting for e784e90dc260e8 to have state: stopped
Error: release command failed - aborting deployment. error running release_command machine: timeout reached waiting for machine to stopped failed to wait for VM e784e90dc260e8 in stopped state: Get "https://api.machines.dev/v1/apps/sfddsfh/machines/e784e90dc260e8/wait?instance_id=01H08SE8QG4107JM5ZVPJ3086J&state=stopped&timeout=60": net/http: request canceled

Here is my updated knexfile.js

production: {
    client: 'pg',
    connection: process.env.DATABASE_URL,
    pool: { min: 0, max: 7 },
    seeds: {
      directory: path.join(__dirname, '/seeds/production'),
    },
  },

It is weird that error is still in mysql2, while it should use pg

I have an existing pg app; and I just tried to use it with knex, and it worked the first time.

hm…
trying mysql now, I have successfully setup mysql app, but when deploying again getting the same error…
ECONNREFUSED

Any way to help me with this? If I upgrade or anything? Just need to get it working…

Ok, after updating port env, I get this in logs:
2023-05-13T09:51:59.468 app[e28650e4be5118] ams [info] :information_source: connection to home_project_database db successful!
But still the app fails

Running new-app765 release_command: yarn knex migrate:latest
  Waiting for e28650e4be5118 to have state: stopped
Error: release command failed - aborting deployment. error running release_command machine: timeout reached waiting for machine to stopped failed to wait for VM e28650e4be5118 in stopped state: Get "https://api.machines.dev/v1/apps/new-app765/machines/e28650e4be5118/wait?instance_id=01H0A8BK30G6618HDEC4S6Z557&state=stopped&timeout=60": net/http: request canceled