0
votes

I am a newbie in Docker, and while going through a course online, I stumbled into a problem. While trying to build separate dev, prod and test images, only my dev one seems to build correctly.

My prod and test images build with their flag as "<none>", even though I run the build with the following command: "sudo docker build -t ultimatenode:test --target test ."

Also my prod image is supposed to be smaller in size, because I removed the original node_modules and ./test folder, but there seems to be some mistake on my part.

Would anyone be kind enough to check the problem in the following Dockerfile:

    FROM node:16 as base
    
    EXPOSE 80
    WORKDIR /app
    COPY package*.json ./
    
    RUN npm config list
    RUN npm ci \
        && npm cache clean --force
    
    
    ENV PATH /app/node_modules/.bin:$PATH
    
    CMD ["node", "server.js"]
    
    #DEVELOPMENT
    
    FROM base as dev
    ENV NODE_ENV=development
    
    # NOTE: these apt dependencies are only needed
    # for testing. they shouldn't be in production
    RUN apt-get update -qq \
        && apt-get install -qy --no-install-recommends \
        bzip2 \
        ca-certificates \
        curl \
        libfontconfig \
        && rm -rf /var/lib/apt/lists/*
    RUN npm config list
    RUN npm install --only=development \
        && npm cache clean --force 
    
    
    COPY . /app
    CMD ["nodemon", "server.js"]
    
    
    
    #TEST
    FROM dev as test
    COPY . .
    RUN npm audit
    
    #PREPROD
    FROM test as preprod
 

       #Removing unecessary folders

    RUN rm -rf ./tests && rm -rf ./node_modules
    
    
    FROM base as prod
 
    COPY --from=pre-prod /app /app
   WORKDIR /app
    HEALTHCHECK CMD curl http://127.0.0.1/ || exit 1
    CMD ["node", "server.js"]

Also, here is my docker-compose.yml

version: '2.4'

services:
  redis:
    image: redis:alpine

  db:
    image: postgres:9.6
    environment:
      - POSTGRES_HOST_AUTH_METHOD=trust
    volumes:
      - db-data:/var/lib/postgresql/data

  vote:
    image: bretfisher/examplevotingapp_vote
    ports:
      - '5000:80'
    depends_on:
      - redis

  result:
    build: 
      context: .
      target: dev
    ports:
      - '5001:80'
    volumes:
      - .:/app
      
    environment:
      - NODE_ENV=development
    depends_on:
      - db

  worker:
    image: bretfisher/examplevotingapp_worker
    depends_on:
      - redis
      - db

volumes:
    db-data:
RUN rm never makes an image smaller. Internally, Docker remembers the content of the image up to this point, plus a new layer recording that files got removed. If you want a smaller image, you need to start a new build stage that only COPY --from=earlier-stage the specific things you want to include. - David Maze
Building separate images per environment isn't typically a best practice (how will you test the production image, if your preprod image has a different build pipeline?). I'd also recommend removing the volumes: that replace the image's code with something from the host. As this setup is now, your production image will be almost totally untested; you haven't executed its build pipeline before going to production and you haven't run with the actual code built into the image. - David Maze