I basically expose the daemon socket into the docker container so that it requests builds from the host. It means that everything is cached right on local disk. If you need more oomph than one machine will provide the cache won't be shared between different machines without extra effort but you can do a lot of building on a single machine (especially if a lot of stuff is using Nix so cached).
It caches on two levels (instance's /nix/store on EBS and then also binary cache on S3).
Of course the attack surface is quite large, so I wouldn't expose this to the public. But using this for my repos and trusted developers is fine with me. It is basically impossible to accidentally do harm. Also note that GitLab forks and Merge Requests from forks run in the author's repo, so they won't use your runners. So it is only people with push access that will use them.