Docker running old images not picking up changes - docker

I have been stuck with docker not picking up any changes.
So I released my app few days ago as v1.0.0.0 and obviously since its a sort of pre release i still have some bug fixes to do currently i'm already at v1.0.5.0. But for some reason every time I deploy it seem to run an old image and not the new one with my bug fix in it.
Firstly i'm not using ci/cd pipelines for the moment just everything manually(still learning)
What I do to run:
So i run docker-compose -f docker-compose.yml -f docker-compose-override.yml up -d
this works
when I want to redeploy i overwrite my files by deleting them and putting my new files in the folder
i close my containers :
docker-compose -f docker-compose.yml -f docker-compose-override.yml down
and when everything is ready i'll start them again with:
docker-compose -f docker-compose.yml -f docker-compose-override.yml up -d
but for some reason when I do this it does not pickup the changes. I think it tries to load the old untagged image or something although when i run docker images list i get nothing
I can fix this kinda issue by deleting everything with:
docker rmi $(docker images -a -q)
this deletes everything and then i'll start my containers again and this start the new one.
But obviously i'm not going to remove all my images everytime.
my webapp consist of a api, frontend in blazor and mvc app all in .net5.0 and production database running on another vm.
my compose:
version: '3.4'
services:
portfoliorepositoryapi:
image: ${DOCKER_REGISTRY-}portfoliorepositoryapi:${TAG:-latest}
container_name: "PortfolioApi"
ports:
- "5100:80"
- "5101:443"
- "1433:1433"
build:
context: .
dockerfile: PortfolioRepositoryApi/Dockerfile
portfolio-frontend:
image: ${DOCKER_REGISTRY-}portfoliofrontend:${TAG:-latest}
container_name: "PortfolioFrontend"
ports:
- "5104:80"
- "5105:443"
build:
context: .
dockerfile: Portfolio-Frontend/Dockerfile
volumes:
- ./Portfolio-Frontend/Files:/app/Files
cmsapp:
image: ${DOCKER_REGISTRY-}cmsapp:${TAG:-latest}
container_name: "CMSAPP"
ports:
- "5102:80"
- "5103:443"
build:
context: .
dockerfile: CMSApp/Dockerfile
What do I need to do so it picks up the changes?

Try using --build option of docker compose up, as specified in the docs. There's also a --force-recreate option available, which you may or may not find useful depending on your workflow.
In your case, your command would be something similar to:
docker-compose -f docker-compose.yml -f docker-compose-override.yml up --build -d

Related

Docker Compose - Is it possible to update all changed images with a single command?

I have a compose.yml like this one:
version: '3.7'
services:
nginx:
restart: unless-stopped
image: ghcr.io/user/frontend:latest
ports:
- 80:80
depends_on:
- backend
backend:
restart: unless-stopped
image: ghcr.io/user/backend:latest
entrypoint: /home/app/web/wsgi-entrypoint.sh
expose:
- 8000
We have 2 images stored on Github: frontend and backend.
My goal is the following: when an image has been updated on the Github Docker Registry, I'd like to automatically update the image on the server and launch the new one substituting the old one via docker-compose.
For example: I have a running compose made by frontend and backend, but I just pushed a new image: ghcr.io/user/frontend:latest.
Now, I want a single command which updates only the images that have been changed (in this case ghcr.io/user/frontend:latest) and when I reload the frontend webpage I see the changes.
My attempt is the following:
docker-compose up -d --build
But the system says:
compose-backend_1 is up-to-date
compose-nginx_1 is up-to-date
which is not true!
So, the working procedure I use is a bit manual:
docker pull ghcr.io/user/frontend:latest
I see in the console: Status: Downloaded newer image,
which is the proof that a new image has been downloaded.
Then, if I relaunch the same command the console displays: Status: Image is up to date for ghcr.io/user/frontend:latest
Finally:
docker-compose up -d --build
says: Recreating compose-nginx_1 ... done
I suppose the command docker-compose up -d --build ALONE is not looking for new images and so does not update the image that is changed.
So, is there a SINGLE specific command to fix this?
Should be achieved by running docker-compose pull, and then docker-compose up -d
Or, shorter: docker-compose up -d --pull always
You can use variable substitution in many places in a docker-compose.yml file, in particular including the image:. If you give every build a unique tag, then you can supply the tag as an environment variable, and it will work the way you describe.
Let's say the two images have the same tagging scheme (they don't necessarily need to). You could update the Compose file to say
version: '3.8'
services:
nginx:
restart: unless-stopped
image: ghcr.io/user/frontend:${TAG:-latest} # <--
ports:
- 80:80
depends_on:
- backend
backend:
restart: unless-stopped
image: ghcr.io/user/backend:${TAG:-latest} # <--
Notice the $TAG reference at the end of the image: lines. If TAG isn't set in the environment, it will use latest, but if it is, it will use that exact build.
Now, if I run:
TAG=20221020 docker-compose up -d
For both containers, Compose will notice that they're running an older build, automatically pull the updated image from GitHub, and restart both containers against the newer image.
This brings the mild complication of your continuous-deployment system needing to know the current image tag. In exchange, though, you get the ability to very easily roll back – if today's build turns out to have a critical bug you can run the exact same command with a different tag to redeploy on yesterday's build. A setup like this is also necessary if you're considering migrating to Kubernetes, since it depends on the text of the image: string changing to trigger a redeployment.

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"
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.
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
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>.

Docker not mapping changes from local project to the container in windows

I am trying to use Docker volume/bind mount so that I don't need to build my project again and again after every small change. I do not get any error but changes in the local files are not visible in container thus I still have to rebuild the project for the new files system snapshot.
Following solution seemed to work for some people.Therefore,
I have tried restarting Docker and Reset Credentials at Docker Desktop-->Setting-->Shared Drives
Here is my docker-compose.yml file
version: '3'
services:
web:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "3000:3000"
volumes:
- /app/node_modules
- .:/app
I have tried through Docker CLI too. but problem persists
docker build -f Dockerfile.dev .
docker run -p 3000:3000 -v /app/node_modules -v ${pwd}:/app image-id
Windows does copy the files in current directory to container but they are
not in sync
I am using Windows 10 power shell and docker version 18.09.2
UPDATE:
I have checked container contents
using command
docker exec -t -i container-id sh
and the printed file contents using command
cat filename
And from this it is clear that the files container references to has/have changed/updated but I still don't understand why do i have to restart container to see the changes in browser.
Should not they be apparent after just refreshing the tab?

How to force docker-compose to download a new image when using docker hub?

I have a docker-compose.yml file which takes the image svka4019/notes2:latest from the docker hub.
However, if I change the image build it and push it, when I run docker-compose it just uses the one it has already downloaded before.
Here is the docker-compose.yml:
springboot-docker-compose-app-container:
image: svka4019/notes2:latest
ports:
- "80:5001"
depends_on:
- friendservice
networks:
- mynet
container_name: base_notes
friendservice:
build: ./Pirmas
command: python app.py
ports:
- 5000:5000
container_name: friend
networks:
- mynet
networks:
mynet:
And the command I use for building and running: docker-compose up --build -d.
For updating the image in docker-hub I use:
docker build -t svka4019/notes2
docker push svka4019/notes2
If I use methods as no-cache it just rebuilds friendService container and skips the base one.
As #DazWilkin pointed out in the comments, using latest tag should be used carefully. Not only can it introduce bugs in your app if latest comes with BC breaks, but it also doesn't indicate that a new update must be performed on your machine if you already have an image 'latest'.
In your case, what you have to do should you want to keep using latest, is to simply call:
docker-compose pull
In case you are building your own image, then you must do:
docker-compose build --pull
The latter will tell docker-compose to first pull the base image before building your custom image.

docker-compose up not recreate container

I create two containers, one is an oracle db and one is an apache tomcat.
I run both of them using the following docker compose:
version: '3.4'
services:
tomcat:
build: ./tomcat/.
ports:
- "8888:8080"
- "59339:59339"
depends_on:
- oracle
volumes:
- ./tomcat/FILES:/usr/test/FILES
- ./ROOT.war:/opt/tomcat/webapps/ROOT.war
expose:
- "8888"
- "59339"
oracle:
build: ./database/.
ports:
- "49161:1521"
environment:
- ORACLE_ALLOW_REMOTE=true
expose:
- "49161"
I use the command docker-compose up that in according with the documentation it must be recreate the container.
But in reality it start only the old containers (same containers ID) with the state of the containers when it was stoped, this is a problem because I use it for testing and I want to start from a clean situation (ROOT.war must be deployed every time i run the command).
It is normal or I miss something.
I'm using docker for windows 18.06.1-ce and Compose 1.22.0
UPDATE
So is not true that up recreate container but do it only if something changed?
I also see docker-compose down that remove the container and force up to recreate them, is the right approch?
The things that I not uderstand is why the status of the container was saved every time i stoped it (file app.pid create by tomcat still present after a simple up without a previous down)
docker-compose starts and stops containers, if you want to recreate them every time you have to pass the --force-recreate flag as per the docs.
Yes, this is as expected.
Sounds like you want to do a restart:
docker-compose restart
or to force a rebuild:
docker-compose --build start
--force-recreate will recreate the contianers
From Docs
--force-recreate => Recreate containers even if their configuration and image haven't
changed.
docker-compose up -d --force-recreate

Resources