When you issue a docker-compose up
, all services always start. While you're iterating over some code, this isn't always great (some background: we use consul for service discovery once our images are started, so we don't rely on links too heavily. Having said that, our consul service images do link to one another).
When I'm heavily iterating on the code in a particular container and it requires many restarts, it's much easier to have all other containers controlled by docker-compose, and the container you're iterating on to be controlled separately.
The yaml could be something like:
conductor:
build: ./conductor
volumes:
- /data/consul/conductor:/data/consul:rw
consulagent:
build: ./consul
links:
- conductor:consul-agent
db:
build: ./db
links:
- conductor:consul-agent
cache:
build: ./cache
links:
- conductor:consul-agent
static:
build: ./static
links:
- conductor:consul-agent
ports:
- 80:80
- 443:443
environment:
- DEBUG=debug,info,error
- NODE_ENV=development
consului:
build: ./consul-ui
links:
- conductor:consul-agent
ports:
- 8500:8500
app:
build: ./app
links:
- conductor:consul-agent
environment:
- NODE_ENV=development
- APP_PORT=4000
always-start: false
Notice the always-start
property, being set to false. This would allow me to have a workflow of:
$ docker-compose up -d
$ docker-compose up app
I could then docker compose stop app
and docker compose up app
independently of all other services. To achieve this at present, you have comment/uncomment the app service within the yaml file.
You could do this:
$ docker-compose up -d
$ docker-compose -f app.yml up
[edit]
... and use external_links
.
That could work for sure. However, to build the entire suite of services, you'd need to issue two commands:
$ docker-compose build
$ docker-compose -f app.yml build
It would be preferable to have this in one command...
+1
This is a duplicate of many previous issues (#1439, #697, #942, #1041, #1451, etc)
If a container isn't going to start and run with the rest of the containers, it's not really "part of the composition", so I'm -1 on any new keys to define different behaviours for services.
There are however, already a few ways to handle this scenario:
docker-compose run
extends
to pull in services from the core configFor your specific case, there is a new experimental flag in the docker-compose 1.3 release candidate. docker-compose up --x-smart-recreate
which will only recreate and restart the containers that have changed, and leave the rest running.
+1, ideally allow the flag to be set from an environment variable. We have a few build/run variants, to this feature would be great
For my team I made a script that basically does this :
docker rm -vf project_app_1
docker build -t project_app app
docker-compose up -d --no-recreate --no-build
This works well.
Since 1.3.0rc1 --x-smart-recreate
may resolve our problem.
Thanks for the suggestion! I've created an issue here to aggregate many similar suggestions: https://github.com/docker/compose/issues/1896
This feature would be tremendously useful. For example, I have an program that runs an interactive terminal, and passes configuration parameters to the running services (e.g. debug verbosity). Because it uses the same network, volumes, etc., as the other services, it makes sense to keep it in the same compilation. Running it from it's own compilation is doable, but it requires hard-coding the names of the volumes into the compose file.
The no-op command idea is fine, but not very elegant, especially if there's a long path to the executable. Another option would be to run a script inside the container that somehow tests what kind of environment it's in, and determine if it was run via up
. But, again, providing a config parameter for this would be much cleaner.
This helps for me:
docker-compose up --scale <service>=0
Apparently docker-compose up --scale <service>=0
will still build <service>
.
If you don't like typing the extra arguments in the CLI you could always do something like
services:
<service>:
entrypoint: "bash -c"
command: "exit 0"
I implemented this using environment variables. Solution on stackoverflow: https://stackoverflow.com/a/61107015/10534470
Most helpful comment
That could work for sure. However, to build the entire suite of services, you'd need to issue two commands:
It would be preferable to have this in one command...