I have a circle.yml file that runs things like docker-compose -f ci/docker-compose.ci.yml run web pytests. It’s working dandy and everything but… Within that container it generates a /test_artifacts/pytest.xml file that I’d like to extract and use in the CircleCI error reporting.
If volume mounts worked, I could have used that in my docker-compose.ci.yml but that’s not an option because CircleCI Docker doesn’t support volume mounts. Switching to the slower machine executor isn’t attractive.
Basically, I have a file inside that docker container I’d now like to get out. Any hot tips on how to make that work? Also, it would be nice to be able to get to that file in case the tests fail. I.e. the above docker-compose command exits !0.
In the run step following your docker-compose, are your containers still running? I would suggest you make them resilient so that they are, and then you can use docker cp (from container to host) regardless of whether your tests fail or not.
Edit
Hmm, I wonder: you may not even need the containers still to be running. I seem to recall that Docker Compose will leave your containers in their old state even if all of your containers have stopped. I wonder if you can still use docker cp on them?
▶ docker-compose -f ci/docker-compose.ci.yml run web bash
$ touch /app/foo.bar
$ exit
But as soon as I do that, that file disappears. I.e.:
▶ docker cp $(docker-compose -f ci/docker-compose.ci.yml ps -q web):/app/foo.bar .
Error: No such container:path: cfa8b245c328600acd76ab84cd894e9fb93afb110518ef8ac1942d714d9ba3eb:/app/foo.bar
The file /app/foo.bar is not part of the image, it’s part of the container and all of those files are deleted when you stop the container. It doesn’t help if I start it again with docker start $(docker-compose -f ci/docker-compose.ci.yml ps -q web).
There must be some other way to “change the image” or something inside a container.
Have a look at this answer, and the answer linked. Does it help if you start your exited container and then do the cp in another terminal? If you use start, can you see your touched file?
As an alternative, you could look at keeping your containers running, as I mentioned earlier.
Finally, volume mounts do seem to work in certain circumstances. I think they don’t work on running containers (because the CircleCI infra distributes them across physical machines, where volumes won’t work) but they work on data-only containers (or at least they do for me, at least in r/o mode).
To resolve this, we first switched to machine instead of docker. That made it possible to volume mounts.
Then, we discovered a better way. We switch back to using docker but use a volume on each container called test-artifacts that each docker container could use. That means that files written in one docker container exists in other docker containers. Then, as a first step in the circle.yml we run:
docker-compose -f ci/docker-compose.yml run --user root artifact-collector
And in the last step we use docker cp to extract files out of that container.