[Node.js] Default generated Dockerfile may cause user deployment to fail

I noticed recently that when creating a project on Fly if the project is detected as a JavaScript type it will use Dockerfile instead of Heroku build pack.

In the default generated Dockerfile we can see the following configuration:

# ...
RUN mkdir /app

ENV NODE_ENV production

COPY . .

RUN yarn
# ...

If we set NODE_ENV to production on build time, the default behavior of yarn is that it will not download devDependencies, which may result in non-global commands not being available. (JS developers usually configure them in the devDependencies)

A simple example is that TypeScript users usually place the typescript dependency in devDependencies and then compile it with tsc in scripts, then we may fail at deployment time because tsc cannot be found. This is an implicit behavior, and I think users unfamiliar with yarn / npm may need to debug for this for quite a while.

If possible, it is recommended to add a comment stating # ... when generating the Dockerfile template (as there is no documentation or starting example project on this), which would be helpful in a JavaScript ecosystem where compilation and bundle are very common.

In fact, if we’re not deploying to a volume-sensitive environment like serverless, it’s not offensive to download extra packages in the container, and if Fly wants to make deep optimizations to NodeJS’ bundle behavior, perhaps the following is a better choice:

  • Use the documentation to prompt the user for ways to reduce the size of the image
  • Add a comment to the generated Dockerfile
  • After the JavaScript project completes the bundle, remove all files in node_modules that are unrelated to devDependencies. These actions should become an additional image or utils that can be enabled manually by the user.
1 Like

Any chance I can talk you into making a pull request? :slight_smile:

@rubys Sure. I created a PR(flyctl#1448) for adding comments.