Running one off commands in swarm containers

I’m using a docker-compose.yml file along with docker stack deploy to deploy a web service, a database service and some other supporting services across a cluster. This all works as expected.

The only piece I can’t work out is how to handle one off commands.

For example, I want to run the command bundle exec rake db:migrate within a web service container. That container needs to have access to the database server via it’s hostname. When using compose locally, it’s easy I can just use:

docker-compose run SERVICE_NAME CMD

But I can’t work out a way to do this on swarm. I’ve tried:

docker run -it --network=dcdeploydemo_default 127.0.0.1:5000/dcdeploydemo:1.1 bundle exec rake db:migrate

But the hostname doesn’t resolve.

Similarly I want to be able to run bash in one of these containers and attach to it. What’s the current correct way of approaching this when using swarm?

5 Likes

The closest I’ve come across so far is running a service with --restart-condition=none.

Example:

docker service create --restart-condition=none --name=db_migration {db container} bundle exec db:migrate

I hope that I’m wrong on this, and there is (eventually) a better way to run one-off commands in swarm.

2 Likes

The closest hack I have found thus far is this, https://gist.github.com/alexellis/e11321b8fbfc595c208ea3e74bf5e54b

In my case, my one-off task is scheduled to run from crond regularly and it needs a whole load of configs from docker swarm, so I wrote a docker-compose.yml but explicitly specify restart condition as none.

Say, the service name is my_service

docker service ls --filter name=my_service --format "{{.ID}}" | xargs --no-run-if-empty -I{} docker service rm {}
docker stack deploy --with-registry-auth -c docker-compose.yml my_service

Set the swarm network attachable. Then use docker run --net ... to execute something in the network.