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
WORKDIR /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 todevDependencies
. These actions should become an additional image or utils that can be enabled manually by the user.