Compose: About scale command deprecration warning

Created on 10 Oct 2017  路  15Comments  路  Source: docker/compose

Currently (v1.16.1 with 17.05.0-ce) the use of scale command (when docker-compose.yml is version 2) prints a warning indicating that it will be deprecated and suggests the user to use --scale flag instead.

Having tried docker-compose up's --scale flag, it seems that the behaviour is different from the old scale command.

I mean that docker-compose scale servicename=3 != docker-compose up -d --scale servicename=3.

Plain --scale will end up recreating the started service containers if there is a new image or if the configuration changed. While scale command didn't do that.
So the equivalent of docker-compose scale servicename=3 is docker-compose up -d --scale servicename=3 --no-recreate.

Why such a big deal for this? If the user uses databases without mounting the data folder as volume, this can end up in deleting the database.

Please confirm me the --scale has the desired behaviour and I'll submit a pull request to add this info the docs.

kinquestion

Most helpful comment

Thanks for the fast reply.
Another thing;
If I recall correctly, with the old scale command (at least a few docker-compose versions ago (with version '2' in yml)) doing the following:

docker-compose scale service_a=3
docker-compose scale service_b=3

will result in having 3 containers of service_a and 3 of service_b.

With --scale flag, doing:

docker-compose up -d --scale service_a=3 --no-recreate
docker-compose up -d --scale service_b=3 --no-recreate

will result in 3 service_b containers and only 1 of service_a (asuming there is no scale setting in compose yml). As the second command will stop&remove two service_a containers.

So the user should do both in one command to get 3&3:

docker-compose up -d --scale service_a=3 --scale service_b=3 --no-recreate

Confirm me this is correct, and I'll also add this info to the docs.

All 15 comments

Thank you for the report!

I can confirm that this is the intended behavior (since it is also the behavior of the up command without the --scale option). It also ensures that the configuration is consistent among scaled services, which is generally the desired behavior.

If the user uses databases without mounting the data folder as volume, this can end up in deleting the database.

At the risk of being flippant, if that's the case, the --scale option really is the least of their problems. But I get your point.

Thanks for the fast reply.
Another thing;
If I recall correctly, with the old scale command (at least a few docker-compose versions ago (with version '2' in yml)) doing the following:

docker-compose scale service_a=3
docker-compose scale service_b=3

will result in having 3 containers of service_a and 3 of service_b.

With --scale flag, doing:

docker-compose up -d --scale service_a=3 --no-recreate
docker-compose up -d --scale service_b=3 --no-recreate

will result in 3 service_b containers and only 1 of service_a (asuming there is no scale setting in compose yml). As the second command will stop&remove two service_a containers.

So the user should do both in one command to get 3&3:

docker-compose up -d --scale service_a=3 --scale service_b=3 --no-recreate

Confirm me this is correct, and I'll also add this info to the docs.

I am currently investigating the use of the docker-compose up --scale flag for use with my docker-compose file. Is there an "equivalent" command that I can use with the docker-compose.yaml file itself? For example, on doing a plain o'd docker-compose up -d, the number to scale each component to can be detected from an option in the file. The replicas options looks close to what I want, but this seems to be only for when deploying to a swarm.

@CharlesWinter for v2, use the scale option: https://docs.docker.com/compose/compose-file/compose-file-v2/#scale

@CrimsonGlory
I am very curious about why docker-compose up -d --scale service_b=3 --no-recreate would change or even touch service_a at all?

@mrampant-nist because the --scale service_b=3 is asuming that service_a should be scaled to 1 container (the default value). If there is currently only one container of service_a, then it will not change. But if there are more, it will stop+remove the extra containers leaving only one container.

@CrimsonGlory thank you for the explanation. I can actually achieve what I want using docker-compose up -d --scale service_b=3 --no-recreate service_b
It makes total sense and is consistent with up's behavior

@CrimsonGlory thank you for the explanation. I can actually achieve what I want using docker-compose up -d --scale service_b=3 --no-recreate service_b
It makes total sense and is consistent with up's behavior

I see. That command scales service_b without touching service_a, right? I haven't though about that, but now all make sense. Without adding "service_b" at the end, the command was executing on the whole project (all services), and that make the other services scale down (services that had more than one container and were not specified in the command scale flags).

Funny thing, every time I change the scale of one service, I used to list all the other services in the command, each with its current value scale, lol.

@CrimsonGlory exactly, without adding "service_b" it applies to the project. I realized it made sense when I thought about:
Usage: up [options] [--scale SERVICE=NUM...] [SERVICE...] from the docs
it just looks a bit silly to use the service name twice, but hey, at least it's consistent!

So if I don't want the scaling of one service to affect another service (scale them down to 1), I have to list all those services after --no-recreate?
So if I add a service_c I have to go to everywhere I did:
docker-compose up -d --scale service_b=3 --no-recreate service_b
and add
docker-compose up -d --scale service_b=3 --no-recreate service_b service_c
? That seems brittle. But I guess all this changes with swarm / kubernetes anyway.

@jamshid no, as I understood it, if you don't mention any service at the end of the command, then the default is that the command will effect all services. But if you mention one service there at the end, then only that services is effected no matter how many services you have.

So if you have three services, "service_a", "service_b" and "service_c", this one effects all of them:
docker-compose up -d --scale service_b=3 --no-recreate

...while this one only effects service_b:
docker-compose up -d --scale service_b=3 --no-recreate service_b

@jihu tried what you suggested against docker-compose 1.24.1 and is not working as you mention:

$ docker-compose up --detach --scale app=3 --no-recreate app
Creating prj-site_app_1 ... done
Creating prj-site_app_2 ... done
Creating prj-site_app_3 ... done

$ docker-compose up --detach --scale app-worker=1 --no-recreate app-worker
Stopping and removing prj-site_app_2 ... done
Stopping and removing prj-site_app_3 ... done
Starting prj-site_app_1              ... done
Creating prj-site_app-worker_1       ... done

I'm missing something?

@luislavena that is very odd. I cannot reproduce that behavior.

# docker-compose up --detach --scale app=3 --no-recreate app
Creating prj-site_app_1 ... done
Creating prj-site_app_2 ... done
Creating prj-site_app_3 ... done
# docker-compose up --detach --scale app-worker=1 --no-recreate app-worker
Creating prj-site_app-worker_1 ... done
# docker-compose --version
docker-compose version 1.24.1, build 4667896b

cc @shin- any idea?

@CrimsonGlory I originally thought was because both services shared app- as part of the name, but I believe the issue is caused by depends_on:

This works:

$ docker --version
Docker version 19.03.5, build 633a0ea838

$ docker-compose --version
docker-compose version 1.24.1, build 4667896b
---
version: "3.7"

services:
  app:
    image: containous/whoami:v1.4.0

  worker:
    image: alpine:3.10
    command: sh -c 'while true; do echo "working"; sleep 10; done'
$ docker-compose up --detach --scale app=3 app
Creating network "test-compose-scale_default" with the default driver
Creating test-compose-scale_app_1 ... done
Creating test-compose-scale_app_2 ... done
Creating test-compose-scale_app_3 ... done

$ docker-compose up --detach --scale worker=1 worker
Creating test-compose-scale_worker_1 ... done

$ docker-compose ps
           Name                          Command               State   Ports 
-----------------------------------------------------------------------------
test-compose-scale_app_1      /whoami                          Up      80/tcp
test-compose-scale_app_2      /whoami                          Up      80/tcp
test-compose-scale_app_3      /whoami                          Up      80/tcp
test-compose-scale_worker_1   sh -c while true; do echo  ...   Up

$ docker-compose down
Stopping test-compose-scale_app_3    ... done
Stopping test-compose-scale_app_2    ... done
Stopping test-compose-scale_app_1    ... done
Stopping test-compose-scale_worker_1 ... done
Removing test-compose-scale_app_3    ... done
Removing test-compose-scale_app_2    ... done
Removing test-compose-scale_app_1    ... done
Removing test-compose-scale_worker_1 ... done
Removing network test-compose-scale_default

But introducing depends_on, causes the issue I commented before:

---
version: "3.7"

services:
  app:
    image: containous/whoami:v1.4.0

  worker:
    image: alpine:3.10
    command: sh -c 'while true; do echo "working"; sleep 10; done'
    depends_on:
      - app
$ docker-compose up --detach --scale app=3 app
Creating network "test-compose-scale_default" with the default driver
Creating test-compose-scale_app_1 ... done
Creating test-compose-scale_app_2 ... done
Creating test-compose-scale_app_3 ... done

$ docker-compose up --detach --scale worker=1 worker
Stopping and removing test-compose-scale_app_2 ... done
Stopping and removing test-compose-scale_app_3 ... done
Starting test-compose-scale_app_1              ... done
Creating test-compose-scale_worker_1           ... done

$ docker-compose ps
           Name                          Command               State   Ports 
-----------------------------------------------------------------------------
test-compose-scale_app_1      /whoami                          Up      80/tcp
test-compose-scale_worker_1   sh -c while true; do echo  ...   Up

Should this be considered a bug or a caveat?

Thank you in advance for your response.

Don't know if this helps, but here are my findings on my test machine:

$ docker-compose --version
docker-compose version 1.24.0, build 0aa59064

$ docker --version
Docker version 18.09.7, build 2d0083d

$ docker version
Client:
 Version:           18.09.7
 API version:       1.39
 Go version:        go1.10.8
 Git commit:        2d0083d
 Built:             Thu Jun 27 17:56:23 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.7
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.8
  Git commit:       2d0083d
  Built:            Thu Jun 27 17:23:02 2019
  OS/Arch:          linux/amd64
  Experimental:     false

$ docker-compose ps
     Name         Command   State   Ports 
------------------------------------------
scaletest_app_1   /whoami   Up      80/tcp
scaletest_app_2   /whoami   Up      80/tcp
scaletest_app_3   /whoami   Up      80/tcp

$ docker-compose up -d --scale worker=3 --scale app=3 app
WARNING: The Docker Engine you're using is running in swarm mode.

Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.

To deploy your application across the swarm, use `docker stack deploy`.

scaletest_app_1 is up-to-date
scaletest_app_2 is up-to-date
scaletest_app_3 is up-to-date

$ docker-compose up -d --scale worker=3 --scale app=3 worker
WARNING: The Docker Engine you're using is running in swarm mode.

Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.

To deploy your application across the swarm, use `docker stack deploy`.

Pulling worker (alpine:3.10)...
3.10: Pulling from library/alpine
89d9c30c1d48: Pull complete
Digest: sha256:c19173c5ada610a5989151111163d28a67368362762534d8a8121ce95cf2bd5a
Status: Downloaded newer image for alpine:3.10
scaletest_app_1 is up-to-date
scaletest_app_2 is up-to-date
scaletest_app_3 is up-to-date
Creating scaletest_worker_1 ... done
Creating scaletest_worker_2 ... done
Creating scaletest_worker_3 ... done

$ docker-compose up -d --scale worker=1 worker
WARNING: The Docker Engine you're using is running in swarm mode.

Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.

To deploy your application across the swarm, use `docker stack deploy`.

Stopping and removing scaletest_app_2 ... done
Stopping and removing scaletest_app_3 ... done
Starting scaletest_app_1              ... done
Stopping and removing scaletest_worker_2 ... done
Stopping and removing scaletest_worker_3 ... done
Starting scaletest_worker_1              ... done

$ docker-compose ps
       Name                     Command               State   Ports 
--------------------------------------------------------------------
scaletest_app_1      /whoami                          Up      80/tcp
scaletest_worker_1   sh -c while true; do echo  ...   Up            

Running the test with --no-recreate:

$ docker-compose up -d --no-recreate --scale worker=3 --scale app=3 app
WARNING: The Docker Engine you're using is running in swarm mode.

Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.

To deploy your application across the swarm, use `docker stack deploy`.

Starting scaletest_app_1 ... done
Creating scaletest_app_2 ... done
Creating scaletest_app_3 ... done

$ docker-compose up -d --no-recreate --scale worker=3 --scale app=3 worker
WARNING: The Docker Engine you're using is running in swarm mode.

Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.

To deploy your application across the swarm, use `docker stack deploy`.

Starting scaletest_app_1 ... done
Starting scaletest_app_2 ... done
Starting scaletest_app_3 ... done
Starting scaletest_worker_1 ... done
Creating scaletest_worker_2 ... done
Creating scaletest_worker_3 ... done

And then running with worker=1:

$ docker-compose up -d --no-recreate --scale worker=1  worker
WARNING: The Docker Engine you're using is running in swarm mode.

Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.

To deploy your application across the swarm, use `docker stack deploy`.

Stopping and removing scaletest_app_2 ... done
Stopping and removing scaletest_app_3 ... done
Starting scaletest_app_1              ... done
Stopping and removing scaletest_worker_2 ... done
Stopping and removing scaletest_worker_3 ... done
Starting scaletest_worker_1              ... done

$ docker-compose ps
       Name                     Command               State   Ports 
--------------------------------------------------------------------
scaletest_app_1      /whoami                          Up      80/tcp
scaletest_worker_1   sh -c while true; do echo  ...   Up            
Was this page helpful?
0 / 5 - 0 ratings