Ben
Ben

Reputation: 5414

Docker: How to update your container when your code changes

I am trying to use Docker for local development. The problem is that when I make a change to my code, I have to run the following commands to see the updates locally:

docker-compose down
docker images # Copy the name of the image
docker rmi <IMAGE_NAME>
docker-compose up -d

That's quite a mouthful, and takes a while. (Possibly I could make it into a bash script, but do you think that is a good idea?)

My real question is: Is there a command that I can use (even manually each time) that will update the image & container? Or do I have to go through the entire workflow above every time I make a change in my code?

Just for reference, here is my Dockerfile and docker-compose.yml.

Dockerfile

FROM node:12.18.3

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

RUN npm run build

EXPOSE 4000

CMD ["npm", "start"]

docker-compose.yml

version: "2"

services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: web
    restart: always
    ports:
      - "3000:3000"
    depends_on:
      - mongo
  mongo:
    container_name: mongo
    image: mongo
    volumes:
      - ./data:/data/db
    ports:
      - "27017:27017"

Upvotes: 27

Views: 38077

Answers (3)

Marko E
Marko E

Reputation: 18103

Even though there are multiple good answers to this question, I think they missed the point, as the OP is asking about the local dev environment. The command I usually use in this situation is:

docker-compose up -d --build

If there aren't any errors in Dockerfile, it should rebuild all the images before bringing up the stack. It could be used in a shell script if needed.

#!/bin/bash

sudo docker-compose up -d --build

If you need to tear down the whole stack, you can have another script:

#!/bin/bash

sudo docker-compose down -v

The -v flag removes all the volumes so you can have a fresh start.

NOTE: In some cases, sudo might not be needed to run the command.

Upvotes: 23

Oli
Oli

Reputation: 1

When a docker image is build the artifacts are already copied and no new change can reflect until you rebuild the image.

But

If it is only for local development, then you can leverage volume sharing to update code inside container in runtime. The idea is to share your app/repo directory on host machine with /usr/src/app (as per your Dockerfile) and with this approach your code (and new changes) will be appear on both host and the running container.

Also, you will need to restart the server on every change and for this you can run your app using nodemon (as it watches for changes in code and restarts the server)

Changes required in Dockerfile.

services:
  web:
    ...
    container_name: web
    ...
    volumes:
      - /path/in/host/machine:/usr/src/app
    ...
    ...
    ports:
      - "3000:3000"
    depends_on:
      - mongo

Upvotes: 12

Taha Yavuz Bodur
Taha Yavuz Bodur

Reputation: 150

You may use Docker Swarm as an orchestration tool to apply rolling updates. Check Apply rolling updates to a service.

Basically you issue docker compose up once and do it with a shell script maybe, and once you get your containers running and then you may create a Jenkinsfile or configure a CI/CD pipeline to pull the updated image and apply it to running container with previous image with docker service update <NEW_IMAGE>.

Upvotes: -4

Related Questions