PLEASE follow this link to see the images, I’m a new user and can’t use more than 2 links or 1 embedded media: docker images · GitHub
Hey, I’ve been looking for any guide or article on internet with a similar situation, but found nothing.
Well, there’s this Node.js app that I built using Typescript + ExpressJS, and now I’m trying to setup docker to have both a working development container and a production one.
I’d like to have only one Dockerfile, once it is the recommended, and two docker-compose files, that would be docker-compose.yml
for development, and docker-compose.prod.yml
for production.
My project consists of the root folder, inside of it there are all these dockerfile and compose files, and also my package.json, src/ folder, yarn.lock and etc.
When I start the development container using compose, the goal is to “bind” my local src/ folder with the in container src/ folder, so when I make changes to the local source files, ts-node-dev
that is running inside the container would update the app automatically. I’m not sure if it’s good to make a volume to the container node_modules
, should I?
The problem starts when it comes to the production image.
I’m trying to use multi-stage build, even not completely understanding how it works.
For now I have this:
Dockerfile
FROM node:14.18.1-alpine3.14 as base
ENV APP=/home/node/app
WORKDIR $APP
RUN chown node:node $APP
USER node
COPY --chown=node:node package.json yarn.lock $APP/
RUN yarn install --frozen-lockfile &&\
rm -rf "$(yarn cache dir)"
COPY --chown=node:node . $APP/
RUN yarn build
FROM base as prod
ENV APP=/home/node/app
WORKDIR $APP
RUN chown node:node $APP
USER node
COPY --chown=node:node --from=base "$APP/package.json" "$APP/yarn.lock" "$APP/dist/" $APP/
RUN NODE_ENV=production yarn install --frozen-lockfile
My development docker-compose is:
version: "3.8"
services:
web-dev:
container_name: selfapi
build:
context: .
dockerfile: Dockerfile
target: base
ports:
- ${PORT}:${PORT}
environment:
MONGODB_URL: ${MONGODB_URL}
NODE_ENV: development
AUTH_TOKEN: ${AUTH_TOKEN}
volumes:
- node_modules:/home/node/app/node_modules
- ./src/:/home/node/app/src
- ./tests/:/home/node/app/tests
command: yarn dev2
volumes:
node_modules:
Firstly, I’m not sure why it works without EXPOSE
instruction in the Dockerfile, and without the key PORT
in the environment
in the compose file.
But anyways, if I run docker-compose up -d --build
, this is what I get:
Image: Dev Image
As you see, 358,13 MB.
Volumes: Dev Volume
Acceptable size for node_volumes folder, but I’m not sure if this volume is necessary or I should only let the node_modules inside the container image, any opinion?
Container: Dev Container
If I make changes to the source files locally, the container does update the running app using ts-node-dev
, but it only works if I use the flag --poll
in the command - which is ts-node-dev --poll --respawn --transpile-only --inspect -- ./src/index.ts
-, is there any way to avoid this flag and keep the thing working?
Now, the production part.
This is the docker-compose.prod.yml
:
version: "3.8"
services:
web:
container_name: selfapi
build:
context: .
dockerfile: Dockerfile
target: prod
ports:
- ${PORT}:${PORT}
environment:
MONGODB_URL: ${MONGODB_URL}
NODE_ENV: production
AUTH_TOKEN: ${AUTH_TOKEN}
command: yarn start
Running docker-compose -f ./docker-compose.prod.yml up -d --build
, this is what I get:
Image: Prod image
Why is the production image size the double of development image? I mean, I know the node_modules
folder is not in a separate volume anymore, but it seems that the dev image is somehow mixed
with the production image, is it?
Here is the problem, if I check the node_modules
folder inside the prod container, the devDependencies
are there!!! I want to NOT have them in a production environment. With that multi-stage building, shouldn’t this work as I am thinking?
Also, couldn’t this be unified into a single COPY instruction?
COPY --chown=node:node package.json yarn.lock $APP/
and COPY --chown=node:node . $APP/
And also (again), isn’t this (in the production stage) unecessary?
COPY --chown=node:node --from=base "$APP/package.json" "$APP/yarn.lock" "$APP/dist/" $APP/
I’m looking at the prod container folders, and apparently those files AND the dist
folder already exist in that directory. I thought since this is a multi-stage building process, the stuffs in dev stage wouldn’t be in the prod stage image.
Please, help me with that!!!