compose: strange exit status code behavior

Depending wether I use docker-compose run with or without --rm, the exit status code is ignored. Using docker-compose exec returns me a exit status code 129, while the same command with docker exec returns the correct status code.

I tried to understand what’s happening under the hood, but I can’t make sense of it, so I’ll paste my results here.

 % $(docker exec qspot_php_1 php -r"exit(2);"); echo $?
2
 % $(docker-compose exec php php -r"exit(2);"); echo $?
129
 % $(docker-compose exec php sh -c "exit 2;"); echo $?
2
 % $(docker-compose run php php -r"exit(2);"); echo $? 
0
 % $(docker-compose run --rm php php -r"exit(2);"); echo $?
2

As you can see, there are quite a few differences 😃 Is it a normal behavior? What command should I use if I care about the exit status code?

PS: I’d like to be able to use the docker-compose exec version.

PPS: my versions:

 % docker-compose version
docker-compose version 1.7.0, build 0d7bf73
docker-py version: 1.8.0
CPython version: 3.5.1
OpenSSL version: OpenSSL 1.0.2g  1 Mar 2016

 % docker version
Client:
 Version:      1.10.3
 API version:  1.22
 Go version:   go1.5.3
 Git commit:   20f81dd
 Built:        Sat Mar 12 19:18:57 2016
 OS/Arch:      linux/amd64

Server:
 Version:      1.11.0
 API version:  1.23
 Go version:   go1.5.4
 Git commit:   4dc5990
 Built:        Wed Apr 13 19:36:04 2016
 OS/Arch:      linux/amd64

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 21
  • Comments: 19

Commits related to this issue

Most upvoted comments

I’m confirming docker-compose exec -T ... is solving (exactly) the same issue. Thanks @mauricioprado00

m@localhost:~/gaps$ docker exec -ti gaps_pgsql_1 mkdir /tmp/dbmigration-scripts
m@localhost:~/gaps$ docker exec -ti gaps_pgsql_1 rm -Rf /tmp/dbmigration-scripts
m@localhost:~/gaps$ echo $?
129

but if I remove the allocation of the pseudo-TTY (-t parameter), it does work:

m@localhost:~/gaps$ docker exec -i gaps_pgsql_1 mkdir /tmp/dbmigration-scripts
m@localhost:~/gaps$ docker exec -i gaps_pgsql_1 rm -Rf /tmp/dbmigration-scripts
m@localhost:~/gaps$ echo $?
0

I think it’s a better workaround for the issue than running sh -c, and hopefully brings some enlightenment to docker developers about the issue.

I found a workaround that addresses the issue without switching to sh or removing -t (either of which were not a viable option).

Add ; (exit $?) at the end of a command you are trying to execute with docker exec -it.

Example with docker

$ docker exec -it <container_name> bash -c 'php -r"exit(7);"; (exit $?)'
$ echo $?
7

The same applies to docker-compose

$ docker-compose exec <service_name> bash -c 'php -r "exit(7);"; (exit $?)'
$ echo $?
7

Credits: https://github.com/docksal/docksal/commit/34d1bb094e8f7c8265672f8b46bfa4035fee574f

Been running into this as well on 1.11.2:

Works sometimes, or randomly exists with 129:

docker exec -it "my_container" bash -c "rm -rf /somefolder/*"

Works all the time:

docker exec -it "my_container" sh -c "rm -rf /somefolder/*"

For what it is worth I worked around the rm -rf inconsistent exit code issue with this:

set +e
docker exec -t <container> [ -d /my/dir ] && rm -rf /my/dir
set -e

Not pretty but it worked. I’ll try setting -i instead of -t approach that @mauricioprado00 mentioned and the -T for docker-compose exec approach @myovchev mentioned and see if that solves it too.

Oh, I forgot a last result, which is interesting, as it seems that the php command behaves differently sometimes, compared to sh.

 % $(docker-compose exec php sh -c "exit 2;"); echo $?
2

Hi everyone,

Please note that docker-compose allocates a TTY by default for run / exec operations, whereas docker does not. As such, to obtain the equivalent behavior with compose as in docker, one should use the -T flag.

With that in mind, I don’t believe this is a Compose issue (please correct me if I’m mistaken there), and I would recommend opening an issue on the moby/moby tracker instead.

The only workaround I found is to wrap it in sh -c:

 docker-compose exec php sh -c 'php -r"exit(2);"'
 # returns 2