Building docker images from circle 2


I converted one of our builds over to circle 2, to do some testing. First off, performance is much better, went from a 2.5 minute build to 20 seconds. The only hitch I’ve run into is building the actual docker image when our test steps have passed. I’m guessing that we can’t build the docker image if the executorType is docker… and that we’ll need to use machine in order to do this?


You can build a Docker image. Assuming you have Docker installed on the image, just use - type: setup-docker-engine to obtain a Docker socket. Then you can build and push an image; you can even use private repositories like this.


Ok. i take it there is no way to cache the layers of the images we’re building yet? It’s fairly slow without that. In circle 1 I used to download the last version of the images first then build from there. That doesn’t seem to work here anymore


Not quite in the same way. We have some beta access to Docker layer caching. You need to contact your CSM to gain access to it. Also, I imagine layer caching will cost money in the future.


@rohara I seem to have followed these steps and the setup-docker-engine step runs, but then after that Docker doesn’t seem to be installed.

Here’s my build:

Any idea why this might not be working?


You need to install Docker on the base image you’re using. You can either install it during the build or create your own node base image.


Ah okay. Maybe I am missing the concept here. Does executorType: docker mean that we are running in a docker container (hence quicker to start up) - but there is less installed on that container than before?

Or does the build leave us with a container we can then use to deploy?


The build runs inside a container using the image specified first in your containerInfo entry, so you’ll only be able to run docker commands if your first image has docker installed on it (ie docker-in-docker), and same goes for any other tool.

The power of this is that you can push your own image to docker hub that has all of the build tools you need pre-installed, or you can install them on the fly during your build.

AFAIU - setup-docker-engine exposes a remote docker engine running on circle’s infrastructure to your installed docker client, so when you use docker commands the legwork is actually done on the remote engine - which is presumably why things like network connections into/out of running containers can be tricky.

If you want to package your app as a docker image, I believe you need to build and push that using the usual docker commands just as you did in circle v1. There’s no relation between the container your build runs in and the image you’d want to deploy. I’m now doing this successfully for a simple build, pushing to a private repo.

What I’m not sure about (@rohara?) is whether it’s possible to run commands, eg docker run myapp yarn test and let that ‘inner’ container communicate with the other containers listed in containerInfo. Can I run tests inside my app container that need a mongodb connection? I haven’t had any luck with this but not really sure where to start getting host addresses etc.


No, you can’t do that. Like you said, the Docker socket is from a remote engine and the containers run there. There is no real, shared networking between you and the running containers. The containers you docker run can be accessible to each other, but you can’t connect directly to them, and they can’t connect to the services on your localhost.

So you can definitely run a Mongo instance - you just need to start it with your other containers.

Circle 2 localstack support?

Ok - thanks. It’d be neat if the containerInfo containers ran in the same shared network, or if it were possible to attach a manually started container to that network somehow, but I don’t know what the technical barriers to that are.

I guess it’s no trouble for me to docker run those dependencies manually, it’s presumably just a bit slower to pull those images down (circle seems to cache the containerInfo images?). Will give it a go, cheers.


100% correct.

Just to note, we do have layer caching available through your CSM, for an additional cost post-beta.


@rh389 What Ryan said is accurate, but it may be possible to connect a Docker executor localhost image to a remote image with docker network. One of our engineers mentioned this before, but I haven’t had yet time to explore how this would work.


Cheers. I guess this might be possible because the localhost executor and the remote one are part of the same swam, and so it’s possible in principle to create an overlay network to attach them?

I’ve no idea how we’d orchestrate this from inside a running container (ie circleci’s userland), since it seems like the connections would need to be made at a higher level, for security if nothing else, but if anyone has any ideas I’d be happy to experiment.

It really would make Docker a “first class citizen” if you could network an app container with its test dependencies as containerInfo containers. For now CCI2 is fantastically powerful and fast for pretty much everything except testing docker-built apps. I still love it, don’t get me wrong.


We have updated our documentation to show how to build docker images: