CMD npm run dev
FROM base as prod
RUN --mount=type=bind,source=package.json,target=package.json \
--mount=type=bind,source=package-lock.json,target=package-lock.json \
--mount=type=cache,target=/root/.npm \
npm ci --omit=dev
USER node
COPY . .
CMD node src/index.js
```
In the Dockerfile, you first add a label `as base` to the `FROM
node:${NODE_VERSION}-alpine` statement. This lets you refer to this build stage
in other build stages. Next, you add a new build stage labeled `dev` to install
your development dependencies and start the container using `npm run dev`.
Finally, you add a stage labeled `prod` that omits the dev dependencies and runs
your application using `node src/index.js`. To learn more about multi-stage
builds, see [Multi-stage builds](/manuals/build/building/multi-stage.md).
Next, you'll need to update your Compose file to use the new stage.
### Update your Compose file for development
To run the `dev` stage with Compose, you need to update your `compose.yaml`
file. Open your `compose.yaml` file in an IDE or text editor, and then add the
`target: dev` instruction to target the `dev` stage from your multi-stage
Dockerfile.
Also, add a new volume to the server service for the bind mount. For this application, you'll mount `./src` from your local machine to `/usr/src/app/src` in the container.
Lastly, publish port `9229` for debugging.
The following is the updated Compose file. All comments have been removed.
```yaml {hl_lines=[5,8,20,21],collapse=true,title=compose.yaml}
services:
server:
build:
context: .
target: dev
ports:
- 3000:3000
- 9229:9229
environment:
NODE_ENV: production
POSTGRES_HOST: db
POSTGRES_USER: postgres
POSTGRES_PASSWORD_FILE: /run/secrets/db-password
POSTGRES_DB: example
depends_on:
db:
condition: service_healthy
secrets:
- db-password
volumes:
- ./src:/usr/src/app/src
db:
image: postgres
restart: always