I am running my app in docker, but my production build and start script fails only in docker environment. Although node_env development works well in docker environment.
Here is my script that fails to make a production build and start a server. I am using nodemon and babel
"build:prod": {
"command": "babel ./src/server/ -d server --presets es2015,stage-2 && next build src",
"env": {
"NODE_ENV": "production"
}
},
"start:prod": {
"command": "PORT=3000 nodemon --watch ./src/server/ ./src/server/server.js --exec babel-node --presets es2015,stage-2",
"env": {
"NODE_ENV": "production"
}
}
But when I give same command in docker environment:
FROM node:8-alpine
COPY package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app
WORKDIR /opt/app
ADD . /opt/app
RUN npm run build:prod
EXPOSE 3000
CMD ["npm", "run", "start:prod"]
I get the following error in docker:
> better-npm-run start:prod
site_1 |
site_1 | running better-npm-run in /opt/app
site_1 | Executing script: start:prod
site_1 |
site_1 | to be executed: PORT=3000 NODE_ENV=production nodemon --watch ./src/server/ ./src/server/server.js --exec babel-node --presets es2015,stage-2
site_1 | [nodemon] 1.17.3
site_1 | [nodemon] to restart at any time, enter `rs`
site_1 | [nodemon] watching: /opt/app/src/server/**/*
site_1 | [nodemon] starting `babel-node ./src/server/server.js --presets es2015,stage-2`
site_1 | false 'production'
site_1 | > Could not find a valid build in the '.next' directory! Try building your app with 'next build' before starting the server.
site_1 | [nodemon] app crashed - waiting for file changes before starting...
I would appreciate any help and would be nice to know what I am doing wrong.
5 Answers 5
You need to make sure the .next directory is not being copied from your host
ADD . /opt/app
Will also add the .next directory you had on host. I would add .dockerignore and add .next to the same. And then build and run again
2 Comments
As this issue has gotten quite a few extra votes over time, let me elaborate a bit on a few things you might want to take into account when facing the above problem.
Version
Please refer to the official docs where Vercel lists Node.js version 10.13 or later as a requirement.
Using hardened images for production
I would also recommend using images that are production hardened and proven to be secure. It's considered good practice to use open source images like those of Bitnami (why?, example). Note that this will solve your problem, as now you no longer use any of your local files.
Guarantee build integrity
Recommend ignoring node_modules along with any build artifacts like .next in your .dockerignore file and mounting the cache folder for yarn or npm during build time. That way you can be sure to generate node_modules with the correct OS bindings for your image.
Comments
Check your .dockerignore
FROM node:latest
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./
RUN npm install pm2 -g
ENV NPM_CONFIG_LOGLEVEL warn
RUN npm install --production
# Show current folder structure in logs
RUN ls -al -R
# Bundle app source
COPY . .
EXPOSE 8080
CMD [ "npm", "start" ]
Comments
For production using nextjs use the below commands
npm run build && npm run start
Comments
Update from 2022
Please check the official example from vercel how to use nextjs and docker: https://github.com/vercel/next.js/tree/canary/examples/with-docker
They don't use npm run start, instead node server.js
Don't just copy Dockerfile... Look in next.config for standalone parametr, and package.json for nextjs version.
In next js 12.1.6 next.config should be:
module.exports = {
eslint: {
ignoreDuringBuilds: true,
},
experimental: {
outputStandalone: true
}
}
next build srcbit to the prod command?nodemonand not thenext startcommand?.nextto something without a starting period, perhaps_next.