53

The project is currently running in the background from this command:

docker-compose up -d

I need to make two changes to their docker-compose.yml:

  • Add a new container
  • Update a previous container to have a link to the new container

After changes are made:

NOTE the "<--" arrows for my changes

web:
        build: .
        restart: always
        command: ['tini', '--', 'rails', 's']
        environment:
            RAILS_ENV: production
            HOST: example.com
            EMAIL: [email protected]
        links:
                - db:mongo
                - exim4:exim4.docker # <-- Add link
        ports:
                - 3000:3000
        volumes:
                - .:/usr/src/app
db:
        image: mongo
        restart: always
exim4: # <-------------------------------- Add new container
        image: exim4
        restart: always
        ports:
            - 25:25
        environment:
            EMAIL_USER: [email protected]
            EMAIL_PASSWORD: abcdabcdabcdabcd

After making the changes, how do I apply them? (without destroying anything)

I tried docker-compose down && docker-compose up -d but this destroyed the Mongo DB container... I cannot do that... again... :sob:

docker-compose restart says it won't recognize any changes made to docker-compose.yml (Source: https://docs.docker.com/compose/reference/restart/)

docker-compose stop && docker-compose start sounds like it'll just startup the old containers without my changes?


Test server:

  • Docker version: 1.11.2, build b9f10c9/1.11.2
  • docker-compose version: 1.8.0, build f3628c7

Production server is likely using older versions, unsure if that will be an issue?

3 Answers 3

71

If you just run docker-compose up -d again, it will notice the new container and the changed configuration and apply them.

But:

(without destroying anything)

There are a number of settings that can only be set at container startup time. If you change these, Docker Compose will delete and recreate the affected container. For example, links are a startup-only option, so re-running docker-compose up -d will delete and recreate the web container.

this destroyed the Mongo DB container... I cannot do that... again...

db:
    image: mongo
    restart: always

Add a volumes: option to this so that data is stored outside the container. You can keep it in a named volume, possibly managed by Docker Compose, which has some advantages, but a host-system directory is probably harder to accidentally destroy. You will have to delete and restart the container to change this option. But note that you will also have to delete and restart the container if, for example, there is a security update in MongoDB and you need a new image.

Your ideal state here is:

  • Actual databases (like your MongoDB container) store data in named volumes or host directories
  • Applications (like your Rails container) store nothing locally, and can be freely destroyed and recreated
  • All code is in Docker images, which can always be rebuilt from source control
  • Use volumes as necessary to inject config files and extract logs

If you lose your entire /var/lib/docker directory (which happens!) you shouldn't actually lose any state, though you will probably wind up with some application downtime.

2
  • Using volumes make sense and is a great thought, though I don't think storing DB's in containers make any sense (in production at least). I agree that I should be able to freely destroy/recreate containers. Thank you. Commented Jan 9, 2019 at 18:50
  • It works fine if I am on the same machine, but restarts all the containers if docker-compose up is fired remotely. Any suggestions here?
    – r_D
    Commented Sep 13, 2022 at 9:52
18

Just docker-compose up -d will do the job.

Output should be like

> docker-compose up -d
Starting container1 ... done

> docker-compose up -d
container1 is up-to-date
Creating container2 ... done

As a side note, docker-compose is not really for production. You may want to consider docker swarm.

1
  • 8
    What "production" exactly means differs for large, medium and small sized companies. For the latter two groups, Docker Compose may be adequate, even preferable, for certain projects.
    – Rok Povsic
    Commented Jul 15, 2021 at 18:06
6

the key here is that up is idempotent.

  • if you update configuration in docker-compose.yaml

    docker compose up -d
    
  • If compose is building images before run it, and you want to rebuild them:

    docker compose up -d --build
    

Not the answer you're looking for? Browse other questions tagged or ask your own question.