Michaël Perrin
Michaël Perrin

Reputation: 6268

How to update a Docker container from a newer image?

I have a project with the following file structure:

- Dockerfile
- app/
    - file.txt
    - uploads/

The file.txt file contains Hello 1.

The Dockerfile generates the app image and is quite simple:

FROM busybox

COPY ./app /var/www/app
VOLUME /var/www/app/uploads

The generated image is pushed to Docker Hub on the michaelperrin/app-test repository.

On my server where the app is deployed, I have the following docker-compose.yml file:

version: '2'
services:
  app:
    image: michaelperrin/app-test:0.1.0
    working_dir: /var/www/app
    volumes:
      - /var/www/app

  nginx:
    image: nginx:1.11
    volumes_from:
      - app
    working_dir: /var/www/app

It defines two containers:

The app is run with the docker-compose up -d command.

Running docker-compose exec nginx cat test-file.txt will therefore display:

Hello 1

Now, suppose I do the following steps:

  1. Update the content of file.txt with Hello 2 on my local machine.
  2. Build a new image of my app (that copies the new version of file.txt)
  3. Tag it and push it on Docker Hub as version 0.2.0.
  4. Change my docker-compose.yml file on the server to tell that I now use michaelperrin/app-test:0.2.0 for my app.
  5. Run docker-compose up -d (and docker-compose restart to be sure).

Then the terminal outputs:

Status: Downloaded newer image for michaelperrin/app-test:0.2.0
Recreating apptest_app_1
Recreating apptest_nginx_1

And here is my problem:

If I run docker-compose exec nginx cat test-file.txt it will still display Hello 1, and not Hello 2.

The only solution I found was to do the following:

docker-compose stop app
docker-compose rm app
docker-compose up -d

Is there any better solution?

The problem with the rm solution is that it will remove all other files that could have been created inside the app container by my app, in the /var/www/app/uploads directory (despite the fact it is declared as a volume in the Dockerfile).

Upvotes: 1

Views: 1680

Answers (1)

n2o
n2o

Reputation: 6487

I think (and really hope) that this is not possible. You create an instance (container) from your image with the state it has in the moment as it was built. You'd have unintended side effects when the creation of a new image has an effect on the containers.

Therefore you should remove the old containers and build fresh ones with the new image.

Upvotes: 2

Related Questions